Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Vazquez <blendergit@gmail.com>2022-06-21 20:09:54 +0300
committerAntonio Vazquez <blendergit@gmail.com>2022-06-21 20:09:54 +0300
commitdd6d0aefcc56288bfe154fe06df56163d6961372 (patch)
tree7b74c26bcd48d0fbd844fd8b286c9a399813b203
parentc27a395d8cd8b58b3155cfdc26ae35198fbcdb14 (diff)
parent714001683888770f9d870ba73edd65f4c2757bda (diff)
Merge branch 'master' into asset-greasepencilasset-greasepencil
-rw-r--r--build_files/build_environment/CMakeLists.txt2
-rw-r--r--build_files/build_environment/cmake/ispc.cmake4
-rw-r--r--build_files/build_environment/cmake/llvm.cmake9
-rw-r--r--build_files/build_environment/cmake/openimagedenoise.cmake2
-rw-r--r--extern/draco/README.blender4
-rw-r--r--extern/draco/draco/src/draco/attributes/attribute_octahedron_transform.cc95
-rw-r--r--extern/draco/draco/src/draco/attributes/attribute_octahedron_transform.h31
-rw-r--r--extern/draco/draco/src/draco/attributes/attribute_quantization_transform.cc113
-rw-r--r--extern/draco/draco/src/draco/attributes/attribute_quantization_transform.h38
-rw-r--r--extern/draco/draco/src/draco/attributes/attribute_transform.cc25
-rw-r--r--extern/draco/draco/src/draco/attributes/attribute_transform.h36
-rw-r--r--extern/draco/draco/src/draco/attributes/geometry_attribute.cc12
-rw-r--r--extern/draco/draco/src/draco/attributes/geometry_attribute.h42
-rw-r--r--extern/draco/draco/src/draco/attributes/point_attribute.cc43
-rw-r--r--extern/draco/draco/src/draco/attributes/point_attribute.h6
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/attributes_decoder.cc22
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/attributes_encoder.cc16
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.cc19
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.cc15
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.h6
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/normal_compression_utils.h133
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h4
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h9
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h9
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h7
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc33
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h4
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h6
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h18
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h2
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.cc4
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.cc15
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.cc3
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.cc44
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.h3
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.cc13
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc64
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.h8
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc19
-rw-r--r--extern/draco/draco/src/draco/compression/config/compression_shared.h3
-rw-r--r--extern/draco/draco/src/draco/compression/config/draco_options.h6
-rw-r--r--extern/draco/draco/src/draco/compression/decode.cc5
-rw-r--r--extern/draco/draco/src/draco/compression/encode_base.h8
-rw-r--r--extern/draco/draco/src/draco/compression/entropy/ans.h7
-rw-r--r--extern/draco/draco/src/draco/compression/entropy/rans_symbol_coding.h9
-rw-r--r--extern/draco/draco/src/draco/compression/entropy/rans_symbol_encoder.h4
-rw-r--r--extern/draco/draco/src/draco/compression/entropy/symbol_decoding.cc2
-rw-r--r--extern/draco/draco/src/draco/compression/expert_encode.cc2
-rw-r--r--extern/draco/draco/src/draco/compression/expert_encode.h6
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc31
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder.cc1
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.cc2
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h1
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_shared.h2
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h7
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_sequential_decoder.cc7
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_sequential_encoder.cc4
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_sequential_encoder.h1
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/traverser/mesh_attribute_indices_encoding_observer.h2
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h2
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h5
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h5
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.cc27
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.h4
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.h3
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.h3
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/quantize_points_3.h2
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/point_cloud_decoder.cc10
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/point_cloud_encoder.cc14
-rw-r--r--extern/draco/draco/src/draco/core/bounding_box.cc13
-rw-r--r--extern/draco/draco/src/draco/core/bounding_box.h42
-rw-r--r--extern/draco/draco/src/draco/core/cycle_timer.cc14
-rw-r--r--extern/draco/draco/src/draco/core/cycle_timer.h7
-rw-r--r--extern/draco/draco/src/draco/core/data_buffer.cc2
-rw-r--r--extern/draco/draco/src/draco/core/decoder_buffer.h12
-rw-r--r--extern/draco/draco/src/draco/core/draco_index_type_vector.h3
-rw-r--r--extern/draco/draco/src/draco/core/draco_version.h2
-rw-r--r--extern/draco/draco/src/draco/core/macros.h27
-rw-r--r--extern/draco/draco/src/draco/core/options.h2
-rw-r--r--extern/draco/draco/src/draco/core/status.h4
-rw-r--r--extern/draco/draco/src/draco/core/varint_decoding.h1
-rw-r--r--extern/draco/draco/src/draco/core/vector_d.h14
-rw-r--r--extern/draco/draco/src/draco/draco_features.h2
-rw-r--r--extern/draco/draco/src/draco/mesh/corner_table.cc7
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh.h4
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh_attribute_corner_table.h6
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh_cleanup.cc321
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh_cleanup.h27
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh_misc_functions.h1
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh_stripifier.h8
-rw-r--r--extern/draco/draco/src/draco/mesh/triangle_soup_mesh_builder.cc2
-rw-r--r--extern/draco/draco/src/draco/metadata/geometry_metadata.cc15
-rw-r--r--extern/draco/draco/src/draco/metadata/geometry_metadata.h2
-rw-r--r--extern/draco/draco/src/draco/metadata/metadata.cc8
-rw-r--r--extern/draco/draco/src/draco/metadata/metadata.h1
-rw-r--r--extern/draco/draco/src/draco/metadata/metadata_decoder.cc10
-rw-r--r--extern/draco/draco/src/draco/point_cloud/point_cloud.cc16
-rw-r--r--extern/draco/patches/blender.patch30
-rw-r--r--extern/draco/src/common.cpp28
-rw-r--r--extern/draco/src/common.h2
-rw-r--r--extern/draco/src/decoder.cpp74
-rw-r--r--extern/draco/src/decoder.h36
-rw-r--r--extern/draco/src/encoder.cpp97
-rw-r--r--extern/draco/src/encoder.h33
-rw-r--r--intern/cycles/blender/camera.cpp2
-rw-r--r--intern/cycles/blender/curves.cpp4
-rw-r--r--intern/cycles/blender/display_driver.cpp6
-rw-r--r--intern/cycles/blender/mesh.cpp10
-rw-r--r--intern/cycles/blender/object.cpp2
-rw-r--r--intern/cycles/blender/session.cpp4
-rw-r--r--intern/cycles/blender/sync.cpp4
-rw-r--r--intern/cycles/bvh/build.cpp42
-rw-r--r--intern/cycles/bvh/embree.cpp8
-rw-r--r--intern/cycles/device/cpu/device_impl.cpp26
-rw-r--r--intern/cycles/device/cuda/device.cpp28
-rw-r--r--intern/cycles/device/cuda/device_impl.cpp62
-rw-r--r--intern/cycles/device/cuda/queue.cpp6
-rw-r--r--intern/cycles/device/device.cpp6
-rw-r--r--intern/cycles/device/hip/device.cpp25
-rw-r--r--intern/cycles/device/hip/device_impl.cpp56
-rw-r--r--intern/cycles/device/hip/queue.cpp6
-rw-r--r--intern/cycles/device/memory.h2
-rw-r--r--intern/cycles/device/metal/device_impl.mm32
-rw-r--r--intern/cycles/device/metal/queue.mm8
-rw-r--r--intern/cycles/device/optix/device.cpp6
-rw-r--r--intern/cycles/device/optix/device_impl.cpp24
-rw-r--r--intern/cycles/device/queue.cpp21
-rw-r--r--intern/cycles/integrator/denoiser.cpp4
-rw-r--r--intern/cycles/integrator/denoiser_device.cpp2
-rw-r--r--intern/cycles/integrator/denoiser_oidn.cpp4
-rw-r--r--intern/cycles/integrator/path_trace.cpp66
-rw-r--r--intern/cycles/integrator/path_trace_work_gpu.cpp8
-rw-r--r--intern/cycles/integrator/render_scheduler.cpp21
-rw-r--r--intern/cycles/integrator/shader_eval.cpp4
-rw-r--r--intern/cycles/integrator/work_tile_scheduler.cpp6
-rw-r--r--intern/cycles/kernel/CMakeLists.txt2
-rw-r--r--intern/cycles/kernel/bvh/bvh.h2
-rw-r--r--intern/cycles/kernel/bvh/embree.h6
-rw-r--r--intern/cycles/kernel/bvh/local.h20
-rw-r--r--intern/cycles/kernel/bvh/nodes.h18
-rw-r--r--intern/cycles/kernel/bvh/shadow_all.h22
-rw-r--r--intern/cycles/kernel/bvh/traversal.h22
-rw-r--r--intern/cycles/kernel/bvh/util.h38
-rw-r--r--intern/cycles/kernel/bvh/volume.h26
-rw-r--r--intern/cycles/kernel/bvh/volume_all.h26
-rw-r--r--intern/cycles/kernel/camera/camera.h6
-rw-r--r--intern/cycles/kernel/closure/bsdf.h4
-rw-r--r--intern/cycles/kernel/data_arrays.h82
-rw-r--r--intern/cycles/kernel/device/cpu/compat.h14
-rw-r--r--intern/cycles/kernel/device/cpu/globals.h26
-rw-r--r--intern/cycles/kernel/device/cpu/image.h4
-rw-r--r--intern/cycles/kernel/device/cpu/kernel.cpp8
-rw-r--r--intern/cycles/kernel/device/cuda/globals.h26
-rw-r--r--intern/cycles/kernel/device/gpu/image.h4
-rw-r--r--intern/cycles/kernel/device/hip/globals.h26
-rw-r--r--intern/cycles/kernel/device/metal/context_end.h2
-rw-r--r--intern/cycles/kernel/device/metal/globals.h18
-rw-r--r--intern/cycles/kernel/device/metal/kernel.metal54
-rw-r--r--intern/cycles/kernel/device/optix/globals.h16
-rw-r--r--intern/cycles/kernel/device/optix/kernel.cu48
-rw-r--r--intern/cycles/kernel/device/optix/kernel_shader_raytrace.cu8
-rw-r--r--intern/cycles/kernel/geom/attribute.h31
-rw-r--r--intern/cycles/kernel/geom/curve.h44
-rw-r--r--intern/cycles/kernel/geom/curve_intersect.h22
-rw-r--r--intern/cycles/kernel/geom/motion_curve.h24
-rw-r--r--intern/cycles/kernel/geom/motion_point.h4
-rw-r--r--intern/cycles/kernel/geom/motion_triangle.h30
-rw-r--r--intern/cycles/kernel/geom/motion_triangle_intersect.h2
-rw-r--r--intern/cycles/kernel/geom/motion_triangle_shader.h4
-rw-r--r--intern/cycles/kernel/geom/object.h72
-rw-r--r--intern/cycles/kernel/geom/patch.h24
-rw-r--r--intern/cycles/kernel/geom/point.h14
-rw-r--r--intern/cycles/kernel/geom/point_intersect.h6
-rw-r--r--intern/cycles/kernel/geom/shader_data.h57
-rw-r--r--intern/cycles/kernel/geom/subd_triangle.h119
-rw-r--r--intern/cycles/kernel/geom/triangle.h136
-rw-r--r--intern/cycles/kernel/geom/triangle_intersect.h26
-rw-r--r--intern/cycles/kernel/geom/volume.h2
-rw-r--r--intern/cycles/kernel/integrator/init_from_bake.h4
-rw-r--r--intern/cycles/kernel/integrator/intersect_closest.h14
-rw-r--r--intern/cycles/kernel/integrator/mnee.h12
-rw-r--r--intern/cycles/kernel/integrator/shade_background.h4
-rw-r--r--intern/cycles/kernel/integrator/shade_surface.h2
-rw-r--r--intern/cycles/kernel/integrator/shader_eval.h16
-rw-r--r--intern/cycles/kernel/integrator/subsurface.h4
-rw-r--r--intern/cycles/kernel/integrator/subsurface_disk.h2
-rw-r--r--intern/cycles/kernel/integrator/volume_stack.h6
-rw-r--r--intern/cycles/kernel/light/background.h40
-rw-r--r--intern/cycles/kernel/light/light.h28
-rw-r--r--intern/cycles/kernel/light/sample.h4
-rw-r--r--intern/cycles/kernel/osl/services.cpp2
-rw-r--r--intern/cycles/kernel/sample/jitter.h6
-rw-r--r--intern/cycles/kernel/sample/pattern.h2
-rw-r--r--intern/cycles/kernel/svm/bevel.h4
-rw-r--r--intern/cycles/kernel/svm/ies.h12
-rw-r--r--intern/cycles/kernel/svm/ramp.h2
-rw-r--r--intern/cycles/kernel/svm/svm.h6
-rw-r--r--intern/cycles/kernel/textures.h82
-rw-r--r--intern/cycles/kernel/types.h10
-rw-r--r--intern/cycles/kernel/util/lookup_table.h4
-rw-r--r--intern/cycles/scene/alembic.cpp2
-rw-r--r--intern/cycles/scene/camera.cpp4
-rw-r--r--intern/cycles/scene/colorspace.cpp19
-rw-r--r--intern/cycles/scene/constant_fold.cpp13
-rw-r--r--intern/cycles/scene/film.cpp8
-rw-r--r--intern/cycles/scene/geometry.cpp50
-rw-r--r--intern/cycles/scene/image.cpp6
-rw-r--r--intern/cycles/scene/image_oiio.cpp4
-rw-r--r--intern/cycles/scene/image_vdb.cpp2
-rw-r--r--intern/cycles/scene/integrator.cpp6
-rw-r--r--intern/cycles/scene/light.cpp23
-rw-r--r--intern/cycles/scene/object.cpp2
-rw-r--r--intern/cycles/scene/osl.cpp4
-rw-r--r--intern/cycles/scene/particles.cpp2
-rw-r--r--intern/cycles/scene/scene.cpp165
-rw-r--r--intern/cycles/scene/scene.h2
-rw-r--r--intern/cycles/scene/shader_graph.cpp4
-rw-r--r--intern/cycles/scene/shader_nodes.cpp12
-rw-r--r--intern/cycles/scene/svm.cpp12
-rw-r--r--intern/cycles/scene/tables.cpp2
-rw-r--r--intern/cycles/scene/volume.cpp10
-rw-r--r--intern/cycles/session/session.cpp6
-rw-r--r--intern/cycles/session/tile.cpp16
-rw-r--r--intern/cycles/test/render_graph_finalize_test.cpp2
-rw-r--r--intern/cycles/util/debug.cpp2
-rw-r--r--intern/cycles/util/log.h19
-rw-r--r--intern/cycles/util/task.cpp2
-rw-r--r--intern/ghost/CMakeLists.txt34
-rw-r--r--intern/ghost/GHOST_C-api.h40
-rw-r--r--intern/ghost/GHOST_IWindow.h7
-rw-r--r--intern/ghost/GHOST_Rect.h59
-rw-r--r--intern/ghost/GHOST_Types.h10
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp74
-rw-r--r--intern/ghost/intern/GHOST_CallbackEventConsumer.cpp2
-rw-r--r--intern/ghost/intern/GHOST_ContextGLX.cpp10
-rw-r--r--intern/ghost/intern/GHOST_DropTargetX11.cpp19
-rw-r--r--intern/ghost/intern/GHOST_EventPrinter.cpp17
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.cpp11
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerUnix.cpp6
-rw-r--r--intern/ghost/intern/GHOST_System.cpp16
-rw-r--r--intern/ghost/intern/GHOST_SystemWayland.cpp438
-rw-r--r--intern/ghost/intern/GHOST_SystemWayland.h9
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp144
-rw-r--r--intern/ghost/intern/GHOST_Window.cpp17
-rw-r--r--intern/ghost/intern/GHOST_Window.h9
-rw-r--r--intern/ghost/intern/GHOST_WindowWayland.cpp10
-rw-r--r--intern/ghost/intern/GHOST_WindowWayland.h4
-rw-r--r--intern/ghost/intern/GHOST_XrAction.cpp37
-rw-r--r--intern/ghost/test/gears/GHOST_C-Test.c12
-rw-r--r--intern/ghost/test/multitest/MultiTest.c6
m---------release/datafiles/locale0
m---------release/scripts/addons0
-rw-r--r--release/scripts/modules/rna_manual_reference.py89
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/blender_default.py1
-rw-r--r--release/scripts/startup/bl_operators/wm.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py18
-rw-r--r--release/scripts/startup/bl_ui/properties_mask_common.py3
-rw-r--r--release/scripts/startup/bl_ui/space_image.py1
-rw-r--r--release/scripts/startup/nodeitems_builtins.py1
-rw-r--r--source/blender/blenfont/BLF_api.h15
-rw-r--r--source/blender/blenfont/intern/blf.c28
-rw-r--r--source/blender/blenfont/intern/blf_font.c20
-rw-r--r--source/blender/blenfont/intern/blf_font_default.c43
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c403
-rw-r--r--source/blender/blenfont/intern/blf_internal.h6
-rw-r--r--source/blender/blenfont/intern/blf_internal_types.h5
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/BKE_main.h10
-rw-r--r--source/blender/blenkernel/BKE_mesh_boolean_convert.hh5
-rw-r--r--source/blender/blenkernel/BKE_mesh_remap.h2
-rw-r--r--source/blender/blenkernel/BKE_mesh_sample.hh59
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/intern/constraint.c146
-rw-r--r--source/blender/blenkernel/intern/curves_geometry.cc1
-rw-r--r--source/blender/blenkernel/intern/effect.c2
-rw-r--r--source/blender/blenkernel/intern/fluid.c1
-rw-r--r--source/blender/blenkernel/intern/gpencil_modifier.c2
-rw-r--r--source/blender/blenkernel/intern/image.cc2
-rw-r--r--source/blender/blenkernel/intern/lib_override.cc58
-rw-r--r--source/blender/blenkernel/intern/mesh_boolean_convert.cc24
-rw-r--r--source/blender/blenkernel/intern/mesh_sample.cc172
-rw-r--r--source/blender/blenkernel/intern/mesh_tangent.c2
-rw-r--r--source/blender/blenkernel/intern/nla.c25
-rw-r--r--source/blender/blenkernel/intern/node.cc1
-rw-r--r--source/blender/blenlib/BLI_generic_virtual_array.hh18
-rw-r--r--source/blender/blenlib/BLI_math_base.hh10
-rw-r--r--source/blender/blenlib/CMakeLists.txt1
-rw-r--r--source/blender/blenlib/intern/kdtree_impl.h27
-rw-r--r--source/blender/blenlib/intern/string_utf8.c4
-rw-r--r--source/blender/blenlib/tests/BLI_kdtree_test.cc63
-rw-r--r--source/blender/blenloader/intern/versioning_280.c2
-rw-r--r--source/blender/blenloader/intern/versioning_300.c12
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c1
-rw-r--r--source/blender/draw/engines/eevee/eevee_bloom.c24
-rw-r--r--source/blender/draw/engines/eevee/eevee_shaders.c2
-rw-r--r--source/blender/draw/engines/eevee/shaders/closure_eval_surface_lib.glsl4
-rw-r--r--source/blender/draw/intern/draw_attributes.cc10
-rw-r--r--source/blender/draw/intern/draw_attributes.h5
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.cc6
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h16
-rw-r--r--source/blender/draw/intern/draw_cache_impl_curves.cc52
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.cc4
-rw-r--r--source/blender/draw/intern/draw_cache_impl_subdivision.cc16
-rw-r--r--source/blender/draw/intern/draw_subdivision.h4
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc22
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc4
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc16
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc8
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc9
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc8
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc10
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc23
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc6
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc2
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc2
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc4
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc6
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc2
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_nor.cc8
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc4
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc2
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc6
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc4
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc2
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc10
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc4
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc4
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_skin_roots.cc2
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc10
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc6
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc4
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc4
-rw-r--r--source/blender/draw/intern/shaders/common_subdiv_ibo_lines_comp.glsl2
-rw-r--r--source/blender/draw/intern/shaders/common_subdiv_ibo_tris_comp.glsl2
-rw-r--r--source/blender/draw/intern/shaders/common_subdiv_lib.glsl4
-rw-r--r--source/blender/draw/intern/shaders/common_subdiv_patch_evaluation_comp.glsl2
-rw-r--r--source/blender/draw/intern/shaders/common_subdiv_vbo_lnor_comp.glsl29
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c22
-rw-r--r--source/blender/editors/include/ED_clip.h25
-rw-r--r--source/blender/editors/include/ED_image.h14
-rw-r--r--source/blender/editors/include/ED_mask.h14
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/include/ED_select_utils.h8
-rw-r--r--source/blender/editors/interface/interface_handlers.c6
-rw-r--r--source/blender/editors/interface/interface_region_search.cc7
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.c2
-rw-r--r--source/blender/editors/interface/interface_style.cc18
-rw-r--r--source/blender/editors/io/io_obj.c7
-rw-r--r--source/blender/editors/mask/mask_add.c6
-rw-r--r--source/blender/editors/mask/mask_draw.c21
-rw-r--r--source/blender/editors/mask/mask_intern.h3
-rw-r--r--source/blender/editors/mask/mask_ops.c10
-rw-r--r--source/blender/editors/mask/mask_relationships.c1
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c2
-rw-r--r--source/blender/editors/screen/area.c6
-rw-r--r--source/blender/editors/screen/screen_ops.c26
-rw-r--r--source/blender/editors/sculpt_paint/CMakeLists.txt2
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_add.cc697
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_brush.cc96
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_comb.cc20
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_delete.cc10
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc22
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_intern.hh42
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc14
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc21
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc (renamed from source/blender/editors/sculpt_paint/paint_vertex_color_ops.c)58
-rw-r--r--source/blender/editors/space_clip/space_clip.c1
-rw-r--r--source/blender/editors/space_image/image_ops.c2
-rw-r--r--source/blender/editors/space_image/space_image.c1
-rw-r--r--source/blender/editors/space_nla/nla_draw.c129
-rw-r--r--source/blender/editors/util/select_utils.c14
-rw-r--r--source/blender/editors/uvedit/uvedit_intern.h1
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c1
-rw-r--r--source/blender/editors/uvedit/uvedit_select.c574
-rw-r--r--source/blender/functions/FN_multi_function_procedure.hh8
-rw-r--r--source/blender/functions/intern/multi_function_procedure.cc4
-rw-r--r--source/blender/functions/intern/multi_function_procedure_executor.cc368
-rw-r--r--source/blender/geometry/CMakeLists.txt2
-rw-r--r--source/blender/geometry/GEO_add_curves_on_mesh.hh54
-rw-r--r--source/blender/geometry/intern/add_curves_on_mesh.cc354
-rw-r--r--source/blender/geometry/intern/realize_instances.cc43
-rw-r--r--source/blender/geometry/intern/uv_parametrizer.c89
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c21
-rw-r--r--source/blender/gpu/intern/gpu_context.cc2
-rw-r--r--source/blender/gpu/intern/gpu_material.c2
-rw-r--r--source/blender/gpu/intern/gpu_texture.cc6
-rw-r--r--source/blender/gpu/metal/mtl_texture.hh2
-rw-r--r--source/blender/gpu/shaders/infos/gpu_shader_3D_polyline_info.hh2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl9
-rw-r--r--source/blender/imbuf/intern/stereoimbuf.c31
-rw-r--r--source/blender/io/alembic/intern/alembic_capi.cc24
-rw-r--r--source/blender/io/stl/importer/stl_import_mesh.cc4
-rw-r--r--source/blender/io/usd/intern/usd_capi_import.cc19
-rw-r--r--source/blender/io/usd/intern/usd_reader_mesh.cc14
-rw-r--r--source/blender/io/usd/intern/usd_reader_prim.h5
-rw-r--r--source/blender/io/wavefront_obj/IO_wavefront_obj.h1
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc9
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_mesh.cc39
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_mesh.hh6
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_objects.hh2
-rw-r--r--source/blender/io/wavefront_obj/tests/obj_importer_tests.cc2
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h7
-rw-r--r--source/blender/makesdna/DNA_ipo_types.h2
-rw-r--r--source/blender/makesdna/DNA_light_types.h2
-rw-r--r--source/blender/makesdna/DNA_space_defaults.h1
-rw-r--r--source/blender/makesdna/DNA_space_types.h3
-rw-r--r--source/blender/makesdna/DNA_texture_types.h3
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h15
-rw-r--r--source/blender/makesrna/intern/rna_access.c2
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c2
-rw-r--r--source/blender/makesrna/intern/rna_pose.c6
-rw-r--r--source/blender/makesrna/intern/rna_space.c7
-rw-r--r--source/blender/modifiers/intern/MOD_boolean.cc3
-rw-r--r--source/blender/modifiers/intern/MOD_displace.c1
-rw-r--r--source/blender/modifiers/intern/MOD_warp.c1
-rw-r--r--source/blender/modifiers/intern/MOD_wave.c1
-rw-r--r--source/blender/modifiers/intern/MOD_weightvg_util.c1
-rw-r--r--source/blender/nodes/NOD_geometry.h1
-rw-r--r--source/blender/nodes/NOD_static_types.h1
-rw-r--r--source/blender/nodes/geometry/CMakeLists.txt1
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_boolean.cc47
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_volume_cube.cc197
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc14
-rw-r--r--source/blender/nodes/shader/node_shader_tree.cc1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc38
-rw-r--r--source/blender/nodes/texture/node_texture_tree.c8
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_output.c17
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_proc.c39
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_texture.c2
-rw-r--r--source/blender/render/RE_texture.h3
-rw-r--r--source/blender/render/intern/render_result.c2
-rw-r--r--source/blender/render/intern/texture_image.c308
-rw-r--r--source/blender/render/intern/texture_procedural.c414
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c142
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c4
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c2
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c9
-rw-r--r--source/blender/windowmanager/intern/wm_window.c19
438 files changed, 6909 insertions, 4409 deletions
diff --git a/build_files/build_environment/CMakeLists.txt b/build_files/build_environment/CMakeLists.txt
index b63e86a3ac2..1cf63f2d332 100644
--- a/build_files/build_environment/CMakeLists.txt
+++ b/build_files/build_environment/CMakeLists.txt
@@ -57,7 +57,6 @@ include(cmake/alembic.cmake)
include(cmake/opensubdiv.cmake)
include(cmake/sdl.cmake)
include(cmake/opencollada.cmake)
-include(cmake/llvm.cmake)
if(APPLE)
include(cmake/openmp.cmake)
endif()
@@ -75,6 +74,7 @@ include(cmake/osl.cmake)
include(cmake/tbb.cmake)
include(cmake/openvdb.cmake)
include(cmake/python.cmake)
+include(cmake/llvm.cmake)
option(USE_PIP_NUMPY "Install NumPy using pip wheel instead of building from source" OFF)
if(APPLE AND ("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64"))
set(USE_PIP_NUMPY ON)
diff --git a/build_files/build_environment/cmake/ispc.cmake b/build_files/build_environment/cmake/ispc.cmake
index 160088bc16f..86dc1d9efa8 100644
--- a/build_files/build_environment/cmake/ispc.cmake
+++ b/build_files/build_environment/cmake/ispc.cmake
@@ -6,6 +6,7 @@ if(WIN32)
-DBISON_EXECUTABLE=${LIBDIR}/flexbison/win_bison.exe
-DM4_EXECUTABLE=${DOWNLOAD_DIR}/mingw/mingw64/msys/1.0/bin/m4.exe
-DARM_ENABLED=Off
+ -DPython3_FIND_REGISTRY=NEVER
)
elseif(APPLE)
# Use bison and flex installed via Homebrew.
@@ -43,6 +44,8 @@ set(ISPC_EXTRA_ARGS
-DISPC_INCLUDE_TESTS=Off
-DCLANG_LIBRARY_DIR=${LIBDIR}/llvm/lib
-DCLANG_INCLUDE_DIRS=${LIBDIR}/llvm/include
+ -DPython3_ROOT_DIR=${LIBDIR}/python/
+ -DPython3_EXECUTABLE=${PYTHON_BINARY}
${ISPC_EXTRA_ARGS_WIN}
${ISPC_EXTRA_ARGS_APPLE}
${ISPC_EXTRA_ARGS_UNIX}
@@ -61,6 +64,7 @@ ExternalProject_Add(external_ispc
add_dependencies(
external_ispc
ll
+ external_python
)
if(WIN32)
diff --git a/build_files/build_environment/cmake/llvm.cmake b/build_files/build_environment/cmake/llvm.cmake
index cf92a5175a3..df4cd8b71e9 100644
--- a/build_files/build_environment/cmake/llvm.cmake
+++ b/build_files/build_environment/cmake/llvm.cmake
@@ -25,11 +25,14 @@ set(LLVM_EXTRA_ARGS
-DLLVM_BUILD_LLVM_C_DYLIB=OFF
-DLLVM_ENABLE_UNWIND_TABLES=OFF
-DLLVM_ENABLE_PROJECTS=clang${LLVM_BUILD_CLANG_TOOLS_EXTRA}
+ -DPython3_ROOT_DIR=${LIBDIR}/python/
+ -DPython3_EXECUTABLE=${PYTHON_BINARY}
${LLVM_XML2_ARGS}
)
if(WIN32)
set(LLVM_GENERATOR "Ninja")
+ list(APPEND LLVM_EXTRA_ARGS -DPython3_FIND_REGISTRY=NEVER)
else()
set(LLVM_GENERATOR "Unix Makefiles")
endif()
@@ -74,3 +77,9 @@ if(APPLE)
external_xml2
)
endif()
+
+add_dependencies(
+ ll
+ external_python
+)
+
diff --git a/build_files/build_environment/cmake/openimagedenoise.cmake b/build_files/build_environment/cmake/openimagedenoise.cmake
index 3612e91a690..14a730d69b6 100644
--- a/build_files/build_environment/cmake/openimagedenoise.cmake
+++ b/build_files/build_environment/cmake/openimagedenoise.cmake
@@ -9,6 +9,7 @@ set(OIDN_EXTRA_ARGS
-DOIDN_STATIC_RUNTIME=OFF
-DISPC_EXECUTABLE=${LIBDIR}/ispc/bin/ispc
-DOIDN_FILTER_RTLIGHTMAP=OFF
+ -DPYTHON_EXECUTABLE=${PYTHON_BINARY}
)
if(WIN32)
@@ -38,6 +39,7 @@ add_dependencies(
external_openimagedenoise
external_tbb
external_ispc
+ external_python
)
if(WIN32)
diff --git a/extern/draco/README.blender b/extern/draco/README.blender
index b9c3bbb967d..a879ded978b 100644
--- a/extern/draco/README.blender
+++ b/extern/draco/README.blender
@@ -1,5 +1,5 @@
Project: Draco
URL: https://google.github.io/draco/
License: Apache 2.0
-Upstream version: 1.3.6
-Local modifications: None
+Upstream version: 1.5.2
+Local modifications: Apply patches/blender.patch
diff --git a/extern/draco/draco/src/draco/attributes/attribute_octahedron_transform.cc b/extern/draco/draco/src/draco/attributes/attribute_octahedron_transform.cc
index 283a21251f4..51c3bb6c872 100644
--- a/extern/draco/draco/src/draco/attributes/attribute_octahedron_transform.cc
+++ b/extern/draco/draco/src/draco/attributes/attribute_octahedron_transform.cc
@@ -38,6 +38,46 @@ void AttributeOctahedronTransform::CopyToAttributeTransformData(
out_data->AppendParameterValue(quantization_bits_);
}
+bool AttributeOctahedronTransform::TransformAttribute(
+ const PointAttribute &attribute, const std::vector<PointIndex> &point_ids,
+ PointAttribute *target_attribute) {
+ return GeneratePortableAttribute(attribute, point_ids,
+ target_attribute->size(), target_attribute);
+}
+
+bool AttributeOctahedronTransform::InverseTransformAttribute(
+ const PointAttribute &attribute, PointAttribute *target_attribute) {
+ if (target_attribute->data_type() != DT_FLOAT32) {
+ return false;
+ }
+
+ const int num_points = target_attribute->size();
+ const int num_components = target_attribute->num_components();
+ if (num_components != 3) {
+ return false;
+ }
+ constexpr int kEntrySize = sizeof(float) * 3;
+ float att_val[3];
+ const int32_t *source_attribute_data = reinterpret_cast<const int32_t *>(
+ attribute.GetAddress(AttributeValueIndex(0)));
+ uint8_t *target_address =
+ target_attribute->GetAddress(AttributeValueIndex(0));
+ OctahedronToolBox octahedron_tool_box;
+ if (!octahedron_tool_box.SetQuantizationBits(quantization_bits_)) {
+ return false;
+ }
+ for (uint32_t i = 0; i < num_points; ++i) {
+ const int32_t s = *source_attribute_data++;
+ const int32_t t = *source_attribute_data++;
+ octahedron_tool_box.QuantizedOctahedralCoordsToUnitVector(s, t, att_val);
+
+ // Store the decoded floating point values into the attribute buffer.
+ std::memcpy(target_address, att_val, kEntrySize);
+ target_address += kEntrySize;
+ }
+ return true;
+}
+
void AttributeOctahedronTransform::SetParameters(int quantization_bits) {
quantization_bits_ = quantization_bits;
}
@@ -51,38 +91,55 @@ bool AttributeOctahedronTransform::EncodeParameters(
return false;
}
-std::unique_ptr<PointAttribute>
-AttributeOctahedronTransform::GeneratePortableAttribute(
+bool AttributeOctahedronTransform::DecodeParameters(
+ const PointAttribute &attribute, DecoderBuffer *decoder_buffer) {
+ uint8_t quantization_bits;
+ if (!decoder_buffer->Decode(&quantization_bits)) {
+ return false;
+ }
+ quantization_bits_ = quantization_bits;
+ return true;
+}
+
+bool AttributeOctahedronTransform::GeneratePortableAttribute(
const PointAttribute &attribute, const std::vector<PointIndex> &point_ids,
- int num_points) const {
+ int num_points, PointAttribute *target_attribute) const {
DRACO_DCHECK(is_initialized());
- // Allocate portable attribute.
- const int num_entries = static_cast<int>(point_ids.size());
- std::unique_ptr<PointAttribute> portable_attribute =
- InitPortableAttribute(num_entries, 2, num_points, attribute, true);
-
// Quantize all values in the order given by point_ids into portable
// attribute.
int32_t *const portable_attribute_data = reinterpret_cast<int32_t *>(
- portable_attribute->GetAddress(AttributeValueIndex(0)));
+ target_attribute->GetAddress(AttributeValueIndex(0)));
float att_val[3];
int32_t dst_index = 0;
OctahedronToolBox converter;
if (!converter.SetQuantizationBits(quantization_bits_)) {
- return nullptr;
+ return false;
}
- for (uint32_t i = 0; i < point_ids.size(); ++i) {
- const AttributeValueIndex att_val_id = attribute.mapped_index(point_ids[i]);
- attribute.GetValue(att_val_id, att_val);
- // Encode the vector into a s and t octahedral coordinates.
- int32_t s, t;
- converter.FloatVectorToQuantizedOctahedralCoords(att_val, &s, &t);
- portable_attribute_data[dst_index++] = s;
- portable_attribute_data[dst_index++] = t;
+ if (!point_ids.empty()) {
+ for (uint32_t i = 0; i < point_ids.size(); ++i) {
+ const AttributeValueIndex att_val_id =
+ attribute.mapped_index(point_ids[i]);
+ attribute.GetValue(att_val_id, att_val);
+ // Encode the vector into a s and t octahedral coordinates.
+ int32_t s, t;
+ converter.FloatVectorToQuantizedOctahedralCoords(att_val, &s, &t);
+ portable_attribute_data[dst_index++] = s;
+ portable_attribute_data[dst_index++] = t;
+ }
+ } else {
+ for (PointIndex i(0); i < num_points; ++i) {
+ const AttributeValueIndex att_val_id = attribute.mapped_index(i);
+ attribute.GetValue(att_val_id, att_val);
+ // Encode the vector into a s and t octahedral coordinates.
+ int32_t s, t;
+ converter.FloatVectorToQuantizedOctahedralCoords(att_val, &s, &t);
+ portable_attribute_data[dst_index++] = s;
+ portable_attribute_data[dst_index++] = t;
+ }
}
- return portable_attribute;
+ return true;
}
} // namespace draco
diff --git a/extern/draco/draco/src/draco/attributes/attribute_octahedron_transform.h b/extern/draco/draco/src/draco/attributes/attribute_octahedron_transform.h
index 6e4e74284f0..21a1725bb52 100644
--- a/extern/draco/draco/src/draco/attributes/attribute_octahedron_transform.h
+++ b/extern/draco/draco/src/draco/attributes/attribute_octahedron_transform.h
@@ -37,19 +37,40 @@ class AttributeOctahedronTransform : public AttributeTransform {
void CopyToAttributeTransformData(
AttributeTransformData *out_data) const override;
+ bool TransformAttribute(const PointAttribute &attribute,
+ const std::vector<PointIndex> &point_ids,
+ PointAttribute *target_attribute) override;
+
+ bool InverseTransformAttribute(const PointAttribute &attribute,
+ PointAttribute *target_attribute) override;
+
// Set number of quantization bits.
void SetParameters(int quantization_bits);
// Encode relevant parameters into buffer.
- bool EncodeParameters(EncoderBuffer *encoder_buffer) const;
+ bool EncodeParameters(EncoderBuffer *encoder_buffer) const override;
+
+ bool DecodeParameters(const PointAttribute &attribute,
+ DecoderBuffer *decoder_buffer) override;
bool is_initialized() const { return quantization_bits_ != -1; }
int32_t quantization_bits() const { return quantization_bits_; }
- // Create portable attribute.
- std::unique_ptr<PointAttribute> GeneratePortableAttribute(
- const PointAttribute &attribute, const std::vector<PointIndex> &point_ids,
- int num_points) const;
+ protected:
+ DataType GetTransformedDataType(
+ const PointAttribute &attribute) const override {
+ return DT_UINT32;
+ }
+ int GetTransformedNumComponents(
+ const PointAttribute &attribute) const override {
+ return 2;
+ }
+
+ // Perform the actual transformation.
+ bool GeneratePortableAttribute(const PointAttribute &attribute,
+ const std::vector<PointIndex> &point_ids,
+ int num_points,
+ PointAttribute *target_attribute) const;
private:
int32_t quantization_bits_;
diff --git a/extern/draco/draco/src/draco/attributes/attribute_quantization_transform.cc b/extern/draco/draco/src/draco/attributes/attribute_quantization_transform.cc
index daa634ed03f..a7f93a488d7 100644
--- a/extern/draco/draco/src/draco/attributes/attribute_quantization_transform.cc
+++ b/extern/draco/draco/src/draco/attributes/attribute_quantization_transform.cc
@@ -1,4 +1,3 @@
-
// Copyright 2017 The Draco Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -51,13 +50,74 @@ void AttributeQuantizationTransform::CopyToAttributeTransformData(
out_data->AppendParameterValue(range_);
}
-void AttributeQuantizationTransform::SetParameters(int quantization_bits,
+bool AttributeQuantizationTransform::TransformAttribute(
+ const PointAttribute &attribute, const std::vector<PointIndex> &point_ids,
+ PointAttribute *target_attribute) {
+ if (point_ids.empty()) {
+ GeneratePortableAttribute(attribute, target_attribute->size(),
+ target_attribute);
+ } else {
+ GeneratePortableAttribute(attribute, point_ids, target_attribute->size(),
+ target_attribute);
+ }
+ return true;
+}
+
+bool AttributeQuantizationTransform::InverseTransformAttribute(
+ const PointAttribute &attribute, PointAttribute *target_attribute) {
+ if (target_attribute->data_type() != DT_FLOAT32) {
+ return false;
+ }
+
+ // Convert all quantized values back to floats.
+ const int32_t max_quantized_value =
+ (1u << static_cast<uint32_t>(quantization_bits_)) - 1;
+ const int num_components = target_attribute->num_components();
+ const int entry_size = sizeof(float) * num_components;
+ const std::unique_ptr<float[]> att_val(new float[num_components]);
+ int quant_val_id = 0;
+ int out_byte_pos = 0;
+ Dequantizer dequantizer;
+ if (!dequantizer.Init(range_, max_quantized_value)) {
+ return false;
+ }
+ const int32_t *const source_attribute_data =
+ reinterpret_cast<const int32_t *>(
+ attribute.GetAddress(AttributeValueIndex(0)));
+
+ const int num_values = target_attribute->size();
+
+ for (uint32_t i = 0; i < num_values; ++i) {
+ for (int c = 0; c < num_components; ++c) {
+ float value =
+ dequantizer.DequantizeFloat(source_attribute_data[quant_val_id++]);
+ value = value + min_values_[c];
+ att_val[c] = value;
+ }
+ // Store the floating point value into the attribute buffer.
+ target_attribute->buffer()->Write(out_byte_pos, att_val.get(), entry_size);
+ out_byte_pos += entry_size;
+ }
+ return true;
+}
+
+bool AttributeQuantizationTransform::IsQuantizationValid(
+ int quantization_bits) {
+ // Currently we allow only up to 30 bit quantization.
+ return quantization_bits >= 1 && quantization_bits <= 30;
+}
+
+bool AttributeQuantizationTransform::SetParameters(int quantization_bits,
const float *min_values,
int num_components,
float range) {
+ if (!IsQuantizationValid(quantization_bits)) {
+ return false;
+ }
quantization_bits_ = quantization_bits;
min_values_.assign(min_values, min_values + num_components);
range_ = range;
+ return true;
}
bool AttributeQuantizationTransform::ComputeParameters(
@@ -65,6 +125,9 @@ bool AttributeQuantizationTransform::ComputeParameters(
if (quantization_bits_ != -1) {
return false; // already initialized.
}
+ if (!IsQuantizationValid(quantization_bits)) {
+ return false;
+ }
quantization_bits_ = quantization_bits;
const int num_components = attribute.num_components();
@@ -121,20 +184,37 @@ bool AttributeQuantizationTransform::EncodeParameters(
return false;
}
-std::unique_ptr<PointAttribute>
-AttributeQuantizationTransform::GeneratePortableAttribute(
- const PointAttribute &attribute, int num_points) const {
+bool AttributeQuantizationTransform::DecodeParameters(
+ const PointAttribute &attribute, DecoderBuffer *decoder_buffer) {
+ min_values_.resize(attribute.num_components());
+ if (!decoder_buffer->Decode(&min_values_[0],
+ sizeof(float) * min_values_.size())) {
+ return false;
+ }
+ if (!decoder_buffer->Decode(&range_)) {
+ return false;
+ }
+ uint8_t quantization_bits;
+ if (!decoder_buffer->Decode(&quantization_bits)) {
+ return false;
+ }
+ if (!IsQuantizationValid(quantization_bits)) {
+ return false;
+ }
+ quantization_bits_ = quantization_bits;
+ return true;
+}
+
+void AttributeQuantizationTransform::GeneratePortableAttribute(
+ const PointAttribute &attribute, int num_points,
+ PointAttribute *target_attribute) const {
DRACO_DCHECK(is_initialized());
- // Allocate portable attribute.
- const int num_entries = num_points;
const int num_components = attribute.num_components();
- std::unique_ptr<PointAttribute> portable_attribute =
- InitPortableAttribute(num_entries, num_components, 0, attribute, true);
// Quantize all values using the order given by point_ids.
int32_t *const portable_attribute_data = reinterpret_cast<int32_t *>(
- portable_attribute->GetAddress(AttributeValueIndex(0)));
+ target_attribute->GetAddress(AttributeValueIndex(0)));
const uint32_t max_quantized_value = (1 << (quantization_bits_)) - 1;
Quantizer quantizer;
quantizer.Init(range(), max_quantized_value);
@@ -149,24 +229,18 @@ AttributeQuantizationTransform::GeneratePortableAttribute(
portable_attribute_data[dst_index++] = q_val;
}
}
- return portable_attribute;
}
-std::unique_ptr<PointAttribute>
-AttributeQuantizationTransform::GeneratePortableAttribute(
+void AttributeQuantizationTransform::GeneratePortableAttribute(
const PointAttribute &attribute, const std::vector<PointIndex> &point_ids,
- int num_points) const {
+ int num_points, PointAttribute *target_attribute) const {
DRACO_DCHECK(is_initialized());
- // Allocate portable attribute.
- const int num_entries = static_cast<int>(point_ids.size());
const int num_components = attribute.num_components();
- std::unique_ptr<PointAttribute> portable_attribute = InitPortableAttribute(
- num_entries, num_components, num_points, attribute, true);
// Quantize all values using the order given by point_ids.
int32_t *const portable_attribute_data = reinterpret_cast<int32_t *>(
- portable_attribute->GetAddress(AttributeValueIndex(0)));
+ target_attribute->GetAddress(AttributeValueIndex(0)));
const uint32_t max_quantized_value = (1 << (quantization_bits_)) - 1;
Quantizer quantizer;
quantizer.Init(range(), max_quantized_value);
@@ -181,7 +255,6 @@ AttributeQuantizationTransform::GeneratePortableAttribute(
portable_attribute_data[dst_index++] = q_val;
}
}
- return portable_attribute;
}
} // namespace draco
diff --git a/extern/draco/draco/src/draco/attributes/attribute_quantization_transform.h b/extern/draco/draco/src/draco/attributes/attribute_quantization_transform.h
index 934856f2db7..f1122b680ab 100644
--- a/extern/draco/draco/src/draco/attributes/attribute_quantization_transform.h
+++ b/extern/draco/draco/src/draco/attributes/attribute_quantization_transform.h
@@ -37,14 +37,24 @@ class AttributeQuantizationTransform : public AttributeTransform {
void CopyToAttributeTransformData(
AttributeTransformData *out_data) const override;
- void SetParameters(int quantization_bits, const float *min_values,
+ bool TransformAttribute(const PointAttribute &attribute,
+ const std::vector<PointIndex> &point_ids,
+ PointAttribute *target_attribute) override;
+
+ bool InverseTransformAttribute(const PointAttribute &attribute,
+ PointAttribute *target_attribute) override;
+
+ bool SetParameters(int quantization_bits, const float *min_values,
int num_components, float range);
bool ComputeParameters(const PointAttribute &attribute,
const int quantization_bits);
// Encode relevant parameters into buffer.
- bool EncodeParameters(EncoderBuffer *encoder_buffer) const;
+ bool EncodeParameters(EncoderBuffer *encoder_buffer) const override;
+
+ bool DecodeParameters(const PointAttribute &attribute,
+ DecoderBuffer *decoder_buffer) override;
int32_t quantization_bits() const { return quantization_bits_; }
float min_value(int axis) const { return min_values_[axis]; }
@@ -52,16 +62,30 @@ class AttributeQuantizationTransform : public AttributeTransform {
float range() const { return range_; }
bool is_initialized() const { return quantization_bits_ != -1; }
+ protected:
// Create portable attribute using 1:1 mapping between points in the input and
// output attribute.
- std::unique_ptr<PointAttribute> GeneratePortableAttribute(
- const PointAttribute &attribute, int num_points) const;
+ void GeneratePortableAttribute(const PointAttribute &attribute,
+ int num_points,
+ PointAttribute *target_attribute) const;
// Create portable attribute using custom mapping between input and output
// points.
- std::unique_ptr<PointAttribute> GeneratePortableAttribute(
- const PointAttribute &attribute, const std::vector<PointIndex> &point_ids,
- int num_points) const;
+ void GeneratePortableAttribute(const PointAttribute &attribute,
+ const std::vector<PointIndex> &point_ids,
+ int num_points,
+ PointAttribute *target_attribute) const;
+
+ DataType GetTransformedDataType(
+ const PointAttribute &attribute) const override {
+ return DT_UINT32;
+ }
+ int GetTransformedNumComponents(
+ const PointAttribute &attribute) const override {
+ return attribute.num_components();
+ }
+
+ static bool IsQuantizationValid(int quantization_bits);
private:
int32_t quantization_bits_;
diff --git a/extern/draco/draco/src/draco/attributes/attribute_transform.cc b/extern/draco/draco/src/draco/attributes/attribute_transform.cc
index 55af630ac07..fb2ed18297a 100644
--- a/extern/draco/draco/src/draco/attributes/attribute_transform.cc
+++ b/extern/draco/draco/src/draco/attributes/attribute_transform.cc
@@ -24,21 +24,18 @@ bool AttributeTransform::TransferToAttribute(PointAttribute *attribute) const {
return true;
}
-std::unique_ptr<PointAttribute> AttributeTransform::InitPortableAttribute(
- int num_entries, int num_components, int num_points,
- const PointAttribute &attribute, bool is_unsigned) const {
- const DataType dt = is_unsigned ? DT_UINT32 : DT_INT32;
- GeometryAttribute va;
- va.Init(attribute.attribute_type(), nullptr, num_components, dt, false,
+std::unique_ptr<PointAttribute> AttributeTransform::InitTransformedAttribute(
+ const PointAttribute &src_attribute, int num_entries) {
+ const int num_components = GetTransformedNumComponents(src_attribute);
+ const DataType dt = GetTransformedDataType(src_attribute);
+ GeometryAttribute ga;
+ ga.Init(src_attribute.attribute_type(), nullptr, num_components, dt, false,
num_components * DataTypeLength(dt), 0);
- std::unique_ptr<PointAttribute> portable_attribute(new PointAttribute(va));
- portable_attribute->Reset(num_entries);
- if (num_points) {
- portable_attribute->SetExplicitMapping(num_points);
- } else {
- portable_attribute->SetIdentityMapping();
- }
- return portable_attribute;
+ std::unique_ptr<PointAttribute> transformed_attribute(new PointAttribute(ga));
+ transformed_attribute->Reset(num_entries);
+ transformed_attribute->SetIdentityMapping();
+ transformed_attribute->set_unique_id(src_attribute.unique_id());
+ return transformed_attribute;
}
} // namespace draco
diff --git a/extern/draco/draco/src/draco/attributes/attribute_transform.h b/extern/draco/draco/src/draco/attributes/attribute_transform.h
index d746fbf6eea..62aad60db91 100644
--- a/extern/draco/draco/src/draco/attributes/attribute_transform.h
+++ b/extern/draco/draco/src/draco/attributes/attribute_transform.h
@@ -17,6 +17,8 @@
#include "draco/attributes/attribute_transform_data.h"
#include "draco/attributes/point_attribute.h"
+#include "draco/core/decoder_buffer.h"
+#include "draco/core/encoder_buffer.h"
namespace draco {
@@ -35,10 +37,38 @@ class AttributeTransform {
AttributeTransformData *out_data) const = 0;
bool TransferToAttribute(PointAttribute *attribute) const;
+ // Applies the transform to |attribute| and stores the result in
+ // |target_attribute|. |point_ids| is an optional vector that can be used to
+ // remap values during the transform.
+ virtual bool TransformAttribute(const PointAttribute &attribute,
+ const std::vector<PointIndex> &point_ids,
+ PointAttribute *target_attribute) = 0;
+
+ // Applies an inverse transform to |attribute| and stores the result in
+ // |target_attribute|. In this case, |attribute| is an attribute that was
+ // already transformed (e.g. quantized) and |target_attribute| is the
+ // attribute before the transformation.
+ virtual bool InverseTransformAttribute(const PointAttribute &attribute,
+ PointAttribute *target_attribute) = 0;
+
+ // Encodes all data needed by the transformation into the |encoder_buffer|.
+ virtual bool EncodeParameters(EncoderBuffer *encoder_buffer) const = 0;
+
+ // Decodes all data needed to transform |attribute| back to the original
+ // format.
+ virtual bool DecodeParameters(const PointAttribute &attribute,
+ DecoderBuffer *decoder_buffer) = 0;
+
+ // Initializes a transformed attribute that can be used as target in the
+ // TransformAttribute() function call.
+ virtual std::unique_ptr<PointAttribute> InitTransformedAttribute(
+ const PointAttribute &src_attribute, int num_entries);
+
protected:
- std::unique_ptr<PointAttribute> InitPortableAttribute(
- int num_entries, int num_components, int num_points,
- const PointAttribute &attribute, bool is_unsigned) const;
+ virtual DataType GetTransformedDataType(
+ const PointAttribute &attribute) const = 0;
+ virtual int GetTransformedNumComponents(
+ const PointAttribute &attribute) const = 0;
};
} // namespace draco
diff --git a/extern/draco/draco/src/draco/attributes/geometry_attribute.cc b/extern/draco/draco/src/draco/attributes/geometry_attribute.cc
index f7ed6a86915..b624784261d 100644
--- a/extern/draco/draco/src/draco/attributes/geometry_attribute.cc
+++ b/extern/draco/draco/src/draco/attributes/geometry_attribute.cc
@@ -43,10 +43,6 @@ void GeometryAttribute::Init(GeometryAttribute::Type attribute_type,
}
bool GeometryAttribute::CopyFrom(const GeometryAttribute &src_att) {
- if (buffer_ == nullptr || src_att.buffer_ == nullptr) {
- return false;
- }
- buffer_->Update(src_att.buffer_->data(), src_att.buffer_->data_size());
num_components_ = src_att.num_components_;
data_type_ = src_att.data_type_;
normalized_ = src_att.normalized_;
@@ -55,6 +51,14 @@ bool GeometryAttribute::CopyFrom(const GeometryAttribute &src_att) {
attribute_type_ = src_att.attribute_type_;
buffer_descriptor_ = src_att.buffer_descriptor_;
unique_id_ = src_att.unique_id_;
+ if (src_att.buffer_ == nullptr) {
+ buffer_ = nullptr;
+ } else {
+ if (buffer_ == nullptr) {
+ return false;
+ }
+ buffer_->Update(src_att.buffer_->data(), src_att.buffer_->data_size());
+ }
return true;
}
diff --git a/extern/draco/draco/src/draco/attributes/geometry_attribute.h b/extern/draco/draco/src/draco/attributes/geometry_attribute.h
index b94ba8e22dd..c5faccc1b83 100644
--- a/extern/draco/draco/src/draco/attributes/geometry_attribute.h
+++ b/extern/draco/draco/src/draco/attributes/geometry_attribute.h
@@ -21,6 +21,7 @@
#include "draco/attributes/geometry_indices.h"
#include "draco/core/data_buffer.h"
#include "draco/core/hash_utils.h"
+#include "draco/draco_features.h"
namespace draco {
@@ -51,6 +52,16 @@ class GeometryAttribute {
// predefined use case. Such attributes are often used for a shader specific
// data.
GENERIC,
+#ifdef DRACO_TRANSCODER_SUPPORTED
+ // TODO(ostava): Adding a new attribute would be bit-stream change for GLTF.
+ // Older decoders wouldn't know what to do with this attribute type. This
+ // should be open-sourced only when we are ready to increase our bit-stream
+ // version.
+ TANGENT,
+ MATERIAL,
+ JOINTS,
+ WEIGHTS,
+#endif
// Total number of different attribute types.
// Always keep behind all named attributes.
NAMED_ATTRIBUTES_COUNT,
@@ -111,6 +122,9 @@ class GeometryAttribute {
const int64_t byte_pos = GetBytePos(att_index);
return buffer_->data() + byte_pos;
}
+ inline bool IsAddressValid(const uint8_t *address) const {
+ return ((buffer_->data() + buffer_->data_size()) > address);
+ }
// Fills out_data with the raw value of the requested attribute entry.
// out_data must be at least byte_stride_ long.
@@ -263,7 +277,35 @@ class GeometryAttribute {
// Convert all components available in both the original and output formats.
for (int i = 0; i < std::min(num_components_, out_num_components); ++i) {
+ if (!IsAddressValid(src_address)) {
+ return false;
+ }
const T in_value = *reinterpret_cast<const T *>(src_address);
+
+ // Make sure the in_value fits within the range of values that OutT
+ // is able to represent. Perform the check only for integral types.
+ if (std::is_integral<T>::value && std::is_integral<OutT>::value) {
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable:4804)
+#endif
+#if defined(__GNUC__) && !defined(__clang__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wbool-compare"
+#endif
+ static constexpr OutT kOutMin =
+ std::is_signed<T>::value ? std::numeric_limits<OutT>::lowest() : 0;
+ if (in_value < kOutMin || in_value > std::numeric_limits<OutT>::max()) {
+ return false;
+ }
+#ifdef __GNUC__
+# pragma GCC diagnostic pop
+#endif
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+ }
+
out_value[i] = static_cast<OutT>(in_value);
// When converting integer to floating point, normalize the value if
// necessary.
diff --git a/extern/draco/draco/src/draco/attributes/point_attribute.cc b/extern/draco/draco/src/draco/attributes/point_attribute.cc
index b28f860c15d..e54ab54278f 100644
--- a/extern/draco/draco/src/draco/attributes/point_attribute.cc
+++ b/extern/draco/draco/src/draco/attributes/point_attribute.cc
@@ -222,4 +222,47 @@ AttributeValueIndex::ValueType PointAttribute::DeduplicateFormattedValues(
}
#endif
+#ifdef DRACO_TRANSCODER_SUPPORTED
+void PointAttribute::RemoveUnusedValues() {
+ if (is_mapping_identity()) {
+ return; // For identity mapping, all values are always used.
+ }
+ // For explicit mapping we need to check if any point is mapped to a value.
+ // If not we can delete the value.
+ IndexTypeVector<AttributeValueIndex, bool> is_value_used(size(), false);
+ int num_used_values = 0;
+ for (PointIndex pi(0); pi < indices_map_.size(); ++pi) {
+ const AttributeValueIndex avi = indices_map_[pi];
+ if (!is_value_used[avi]) {
+ is_value_used[avi] = true;
+ num_used_values++;
+ }
+ }
+ if (num_used_values == size()) {
+ return; // All values are used.
+ }
+
+ // Remap the values and update the point to value mapping.
+ IndexTypeVector<AttributeValueIndex, AttributeValueIndex>
+ old_to_new_value_map(size(), kInvalidAttributeValueIndex);
+ AttributeValueIndex new_avi(0);
+ for (AttributeValueIndex avi(0); avi < size(); ++avi) {
+ if (!is_value_used[avi]) {
+ continue;
+ }
+ if (avi != new_avi) {
+ SetAttributeValue(new_avi, GetAddress(avi));
+ }
+ old_to_new_value_map[avi] = new_avi++;
+ }
+
+ // Remap all points to the new attribute values.
+ for (PointIndex pi(0); pi < indices_map_.size(); ++pi) {
+ indices_map_[pi] = old_to_new_value_map[indices_map_[pi]];
+ }
+
+ num_unique_entries_ = num_used_values;
+}
+#endif
+
} // namespace draco
diff --git a/extern/draco/draco/src/draco/attributes/point_attribute.h b/extern/draco/draco/src/draco/attributes/point_attribute.h
index ee36620313e..d55c50c8a57 100644
--- a/extern/draco/draco/src/draco/attributes/point_attribute.h
+++ b/extern/draco/draco/src/draco/attributes/point_attribute.h
@@ -133,6 +133,12 @@ class PointAttribute : public GeometryAttribute {
return attribute_transform_data_.get();
}
+#ifdef DRACO_TRANSCODER_SUPPORTED
+ // Removes unused values from the attribute. Value is unused when no point
+ // is mapped to the value. Only applicable when the mapping is not identity.
+ void RemoveUnusedValues();
+#endif
+
private:
#ifdef DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED
template <typename T>
diff --git a/extern/draco/draco/src/draco/compression/attributes/attributes_decoder.cc b/extern/draco/draco/src/draco/compression/attributes/attributes_decoder.cc
index ce5b8b9c756..007dd2f4303 100644
--- a/extern/draco/draco/src/draco/compression/attributes/attributes_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/attributes_decoder.cc
@@ -43,9 +43,18 @@ bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) {
return false;
}
}
+
+ // Check that decoded number of attributes is valid.
if (num_attributes == 0) {
return false;
}
+ if (num_attributes > 5 * in_buffer->remaining_size()) {
+ // The decoded number of attributes is unreasonably high, because at least
+ // five bytes of attribute descriptor data per attribute are expected.
+ return false;
+ }
+
+ // Decode attribute descriptor data.
point_attribute_ids_.resize(num_attributes);
PointCloud *pc = point_cloud_;
for (uint32_t i = 0; i < num_attributes; ++i) {
@@ -69,9 +78,14 @@ bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) {
if (data_type == DT_INVALID || data_type >= DT_TYPES_COUNT) {
return false;
}
- const DataType draco_dt = static_cast<DataType>(data_type);
- // Add the attribute to the point cloud
+ // Check decoded attribute descriptor data.
+ if (num_components == 0) {
+ return false;
+ }
+
+ // Add the attribute to the point cloud.
+ const DataType draco_dt = static_cast<DataType>(data_type);
GeometryAttribute ga;
ga.Init(static_cast<GeometryAttribute::Type>(att_type), nullptr,
num_components, draco_dt, normalized > 0,
@@ -90,7 +104,9 @@ bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) {
} else
#endif
{
- DecodeVarint(&unique_id, in_buffer);
+ if (!DecodeVarint(&unique_id, in_buffer)) {
+ return false;
+ }
ga.set_unique_id(unique_id);
}
const int att_id = pc->AddAttribute(
diff --git a/extern/draco/draco/src/draco/compression/attributes/attributes_encoder.cc b/extern/draco/draco/src/draco/compression/attributes/attributes_encoder.cc
index 797c62f30aa..480e3ff3436 100644
--- a/extern/draco/draco/src/draco/compression/attributes/attributes_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/attributes_encoder.cc
@@ -15,14 +15,16 @@
#include "draco/compression/attributes/attributes_encoder.h"
#include "draco/core/varint_encoding.h"
+#include "draco/draco_features.h"
namespace draco {
AttributesEncoder::AttributesEncoder()
: point_cloud_encoder_(nullptr), point_cloud_(nullptr) {}
-AttributesEncoder::AttributesEncoder(int att_id) : AttributesEncoder() {
- AddAttributeId(att_id);
+AttributesEncoder::AttributesEncoder(int point_attrib_id)
+ : AttributesEncoder() {
+ AddAttributeId(point_attrib_id);
}
bool AttributesEncoder::Init(PointCloudEncoder *encoder, const PointCloud *pc) {
@@ -37,7 +39,15 @@ bool AttributesEncoder::EncodeAttributesEncoderData(EncoderBuffer *out_buffer) {
for (uint32_t i = 0; i < num_attributes(); ++i) {
const int32_t att_id = point_attribute_ids_[i];
const PointAttribute *const pa = point_cloud_->attribute(att_id);
- out_buffer->Encode(static_cast<uint8_t>(pa->attribute_type()));
+ GeometryAttribute::Type type = pa->attribute_type();
+#ifdef DRACO_TRANSCODER_SUPPORTED
+ // Attribute types TANGENT, MATERIAL, JOINTS, and WEIGHTS are not supported
+ // in the official bitstream. They will be encoded as GENERIC.
+ if (type > GeometryAttribute::GENERIC) {
+ type = GeometryAttribute::GENERIC;
+ }
+#endif
+ out_buffer->Encode(static_cast<uint8_t>(type));
out_buffer->Encode(static_cast<uint8_t>(pa->data_type()));
out_buffer->Encode(static_cast<uint8_t>(pa->num_components()));
out_buffer->Encode(static_cast<uint8_t>(pa->normalized()));
diff --git a/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.cc b/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.cc
index 99469f94590..c7c96d77007 100644
--- a/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.cc
@@ -72,7 +72,7 @@ class PointAttributeVectorOutputIterator {
Self &operator*() { return *this; }
// Still needed in some cases.
- // TODO(hemmer): remove.
+ // TODO(b/199760123): Remove.
// hardcoded to 3 based on legacy usage.
const Self &operator=(const VectorD<CoeffT, 3> &val) {
DRACO_DCHECK_EQ(attributes_.size(), 1); // Expect only ONE attribute.
@@ -278,8 +278,10 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
return false;
}
AttributeQuantizationTransform transform;
- transform.SetParameters(quantization_bits, min_value.data(),
- num_components, max_value_dif);
+ if (!transform.SetParameters(quantization_bits, min_value.data(),
+ num_components, max_value_dif)) {
+ return false;
+ }
const int num_transforms =
static_cast<int>(attribute_quantization_transforms_.size());
if (!transform.TransferToAttribute(
@@ -293,7 +295,9 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
// Decode transform data for signed integer attributes.
for (int i = 0; i < min_signed_values_.size(); ++i) {
int32_t val;
- DecodeVarint(&val, in_buffer);
+ if (!DecodeVarint(&val, in_buffer)) {
+ return false;
+ }
min_signed_values_[i] = val;
}
return true;
@@ -353,8 +357,9 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
return false;
}
if (6 < compression_level) {
- LOGE("KdTreeAttributesDecoder: compression level %i not supported.\n",
- compression_level);
+ DRACO_LOGE(
+ "KdTreeAttributesDecoder: compression level %i not supported.\n",
+ compression_level);
return false;
}
@@ -371,7 +376,7 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
GetDecoder()->point_cloud()->attribute(att_id);
attr->Reset(num_points);
attr->SetIdentityMapping();
- };
+ }
PointAttributeVectorOutputIterator<uint32_t> out_it(atts);
diff --git a/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.cc b/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.cc
index 0f9c31565e5..b70deb9e01f 100644
--- a/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.cc
@@ -71,16 +71,21 @@ bool KdTreeAttributesEncoder::TransformAttributesToPortableFormat() {
att->num_components(), range);
} else {
// Compute quantization settings from the attribute values.
- attribute_quantization_transform.ComputeParameters(*att,
- quantization_bits);
+ if (!attribute_quantization_transform.ComputeParameters(
+ *att, quantization_bits)) {
+ return false;
+ }
}
attribute_quantization_transforms_.push_back(
attribute_quantization_transform);
// Store the quantized attribute in an array that will be used when we do
// the actual encoding of the data.
- quantized_portable_attributes_.push_back(
- attribute_quantization_transform.GeneratePortableAttribute(
- *att, static_cast<int>(num_points)));
+ auto portable_att =
+ attribute_quantization_transform.InitTransformedAttribute(*att,
+ num_points);
+ attribute_quantization_transform.TransformAttribute(*att, {},
+ portable_att.get());
+ quantized_portable_attributes_.push_back(std::move(portable_att));
} else if (att->data_type() == DT_INT32 || att->data_type() == DT_INT16 ||
att->data_type() == DT_INT8) {
// For signed types, find the minimum value for each component. These
diff --git a/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.h b/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.h
index 8b4c4e2faab..80748e0bf5d 100644
--- a/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.h
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
-#ifndef DRACO_COMPRESSION_ATTRIBUTES_POINT_CLOUD_KD_TREE_ATTRIBUTES_ENCODER_H_
-#define DRACO_COMPRESSION_ATTRIBUTES_POINT_CLOUD_KD_TREE_ATTRIBUTES_ENCODER_H_
+#ifndef DRACO_COMPRESSION_ATTRIBUTES_KD_TREE_ATTRIBUTES_ENCODER_H_
+#define DRACO_COMPRESSION_ATTRIBUTES_KD_TREE_ATTRIBUTES_ENCODER_H_
#include "draco/attributes/attribute_quantization_transform.h"
#include "draco/compression/attributes/attributes_encoder.h"
@@ -48,4 +48,4 @@ class KdTreeAttributesEncoder : public AttributesEncoder {
} // namespace draco
-#endif // DRACO_COMPRESSION_ATTRIBUTES_POINT_CLOUD_KD_TREE_ATTRIBUTES_ENCODER_H_
+#endif // DRACO_COMPRESSION_ATTRIBUTES_KD_TREE_ATTRIBUTES_ENCODER_H_
diff --git a/extern/draco/draco/src/draco/compression/attributes/normal_compression_utils.h b/extern/draco/draco/src/draco/compression/attributes/normal_compression_utils.h
index 32e27c711e3..be5ee5b09e3 100644
--- a/extern/draco/draco/src/draco/compression/attributes/normal_compression_utils.h
+++ b/extern/draco/draco/src/draco/compression/attributes/normal_compression_utils.h
@@ -53,6 +53,7 @@ class OctahedronToolBox {
: quantization_bits_(-1),
max_quantized_value_(-1),
max_value_(-1),
+ dequantization_scale_(1.f),
center_value_(-1) {}
bool SetQuantizationBits(int32_t q) {
@@ -62,6 +63,7 @@ class OctahedronToolBox {
quantization_bits_ = q;
max_quantized_value_ = (1 << quantization_bits_) - 1;
max_value_ = max_quantized_value_ - 1;
+ dequantization_scale_ = 2.f / max_value_;
center_value_ = max_value_ / 2;
return true;
}
@@ -192,64 +194,11 @@ class OctahedronToolBox {
}
}
- // TODO(b/149328891): Change function to not use templates as |T| is only
- // float.
- template <typename T>
- void OctaherdalCoordsToUnitVector(T in_s, T in_t, T *out_vector) const {
- DRACO_DCHECK_GE(in_s, 0);
- DRACO_DCHECK_GE(in_t, 0);
- DRACO_DCHECK_LE(in_s, 1);
- DRACO_DCHECK_LE(in_t, 1);
- T s = in_s;
- T t = in_t;
- T spt = s + t;
- T smt = s - t;
- T x_sign = 1.0;
- if (spt >= 0.5 && spt <= 1.5 && smt >= -0.5 && smt <= 0.5) {
- // Right hemisphere. Don't do anything.
- } else {
- // Left hemisphere.
- x_sign = -1.0;
- if (spt <= 0.5) {
- s = 0.5 - in_t;
- t = 0.5 - in_s;
- } else if (spt >= 1.5) {
- s = 1.5 - in_t;
- t = 1.5 - in_s;
- } else if (smt <= -0.5) {
- s = in_t - 0.5;
- t = in_s + 0.5;
- } else {
- s = in_t + 0.5;
- t = in_s - 0.5;
- }
- spt = s + t;
- smt = s - t;
- }
- const T y = 2.0 * s - 1.0;
- const T z = 2.0 * t - 1.0;
- const T x = std::min(std::min(2.0 * spt - 1.0, 3.0 - 2.0 * spt),
- std::min(2.0 * smt + 1.0, 1.0 - 2.0 * smt)) *
- x_sign;
- // Normalize the computed vector.
- const T normSquared = x * x + y * y + z * z;
- if (normSquared < 1e-6) {
- out_vector[0] = 0;
- out_vector[1] = 0;
- out_vector[2] = 0;
- } else {
- const T d = 1.0 / std::sqrt(normSquared);
- out_vector[0] = x * d;
- out_vector[1] = y * d;
- out_vector[2] = z * d;
- }
- }
-
- template <typename T>
- void QuantizedOctaherdalCoordsToUnitVector(int32_t in_s, int32_t in_t,
- T *out_vector) const {
- T scale = 1.0 / static_cast<T>(max_value_);
- OctaherdalCoordsToUnitVector(in_s * scale, in_t * scale, out_vector);
+ inline void QuantizedOctahedralCoordsToUnitVector(int32_t in_s, int32_t in_t,
+ float *out_vector) const {
+ OctahedralCoordsToUnitVector(in_s * dequantization_scale_ - 1.f,
+ in_t * dequantization_scale_ - 1.f,
+ out_vector);
}
// |s| and |t| are expected to be signed values.
@@ -333,9 +282,77 @@ class OctahedronToolBox {
int32_t center_value() const { return center_value_; }
private:
+ inline void OctahedralCoordsToUnitVector(float in_s_scaled, float in_t_scaled,
+ float *out_vector) const {
+ // Background about the encoding:
+ // A normal is encoded in a normalized space <s, t> depicted below. The
+ // encoding correponds to an octahedron that is unwrapped to a 2D plane.
+ // During encoding, a normal is projected to the surface of the octahedron
+ // and the projection is then unwrapped to the 2D plane. Decoding is the
+ // reverse of this process.
+ // All points in the central diamond are located on triangles on the
+ // right "hemisphere" of the octahedron while all points outside of the
+ // diamond are on the left hemisphere (basically, they would have to be
+ // wrapped along the diagonal edges to form the octahedron). The central
+ // point corresponds to the right most vertex of the octahedron and all
+ // corners of the plane correspond to the left most vertex of the
+ // octahedron.
+ //
+ // t
+ // ^ *-----*-----*
+ // | | /|\ |
+ // | / | \ |
+ // | / | \ |
+ // | / | \ |
+ // *-----*---- *
+ // | \ | / |
+ // | \ | / |
+ // | \ | / |
+ // | \|/ |
+ // *-----*-----* --> s
+
+ // Note that the input |in_s_scaled| and |in_t_scaled| are already scaled to
+ // <-1, 1> range. This way, the central point is at coordinate (0, 0).
+ float y = in_s_scaled;
+ float z = in_t_scaled;
+
+ // Remaining coordinate can be computed by projecting the (y, z) values onto
+ // the surface of the octahedron.
+ const float x = 1.f - std::abs(y) - std::abs(z);
+
+ // |x| is essentially a signed distance from the diagonal edges of the
+ // diamond shown on the figure above. It is positive for all points in the
+ // diamond (right hemisphere) and negative for all points outside the
+ // diamond (left hemisphere). For all points on the left hemisphere we need
+ // to update their (y, z) coordinates to account for the wrapping along
+ // the edges of the diamond.
+ float x_offset = -x;
+ x_offset = x_offset < 0 ? 0 : x_offset;
+
+ // This will do nothing for the points on the right hemisphere but it will
+ // mirror the (y, z) location along the nearest diagonal edge of the
+ // diamond.
+ y += y < 0 ? x_offset : -x_offset;
+ z += z < 0 ? x_offset : -x_offset;
+
+ // Normalize the computed vector.
+ const float norm_squared = x * x + y * y + z * z;
+ if (norm_squared < 1e-6) {
+ out_vector[0] = 0;
+ out_vector[1] = 0;
+ out_vector[2] = 0;
+ } else {
+ const float d = 1.0f / std::sqrt(norm_squared);
+ out_vector[0] = x * d;
+ out_vector[1] = y * d;
+ out_vector[2] = z * d;
+ }
+ }
+
int32_t quantization_bits_;
int32_t max_quantized_value_;
int32_t max_value_;
+ float dequantization_scale_;
int32_t center_value_;
};
} // namespace draco
diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h
index f712952556a..2960a5e71b4 100644
--- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
-#ifndef DRACO_COMPRESSION_ATTRIBUTES_MESH_PREDICTION_SCHEMES_PREDICTION_SCHEME_DATA_H_
-#define DRACO_COMPRESSION_ATTRIBUTES_MESH_PREDICTION_SCHEMES_PREDICTION_SCHEME_DATA_H_
+#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_DATA_H_
+#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_DATA_H_
#include "draco/mesh/corner_table.h"
#include "draco/mesh/mesh.h"
diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h
index bf1a6146111..775eded6b55 100644
--- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h
@@ -69,7 +69,14 @@ class MeshPredictionSchemeGeometricNormalPredictorArea
// Computing cross product.
const VectorD<int64_t, 3> cross = CrossProduct(delta_next, delta_prev);
- normal = normal + cross;
+
+ // Prevent signed integer overflows by doing math as unsigned.
+ auto normal_data = reinterpret_cast<uint64_t *>(normal.data());
+ auto cross_data = reinterpret_cast<const uint64_t *>(cross.data());
+ normal_data[0] = normal_data[0] + cross_data[0];
+ normal_data[1] = normal_data[1] + cross_data[1];
+ normal_data[2] = normal_data[2] + cross_data[2];
+
cit.Next();
}
diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h
index 485d457ccf6..fd10fb524b3 100644
--- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h
@@ -60,8 +60,13 @@ inline bool ComputeParallelogramPrediction(
const int v_next_off = vert_next * num_components;
const int v_prev_off = vert_prev * num_components;
for (int c = 0; c < num_components; ++c) {
- out_prediction[c] = (in_data[v_next_off + c] + in_data[v_prev_off + c]) -
- in_data[v_opp_off + c];
+ const int64_t in_data_next_off = in_data[v_next_off + c];
+ const int64_t in_data_prev_off = in_data[v_prev_off + c];
+ const int64_t in_data_opp_off = in_data[v_opp_off + c];
+ const int64_t result =
+ (in_data_next_off + in_data_prev_off) - in_data_opp_off;
+
+ out_prediction[c] = static_cast<DataTypeT>(result);
}
return true;
}
diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h
index 5d8a5060133..f05e5ddd713 100644
--- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h
@@ -156,6 +156,13 @@ bool MeshPredictionSchemeTexCoordsPortablePredictor<
const VectorD<int64_t, 2> x_uv =
n_uv * pn_norm2_squared + (cn_dot_pn * pn_uv);
+ const int64_t pn_absmax_element =
+ std::max(std::max(std::abs(pn[0]), std::abs(pn[1])), std::abs(pn[2]));
+ if (cn_dot_pn > std::numeric_limits<int64_t>::max() / pn_absmax_element) {
+ // return false if squared length calculation would overflow.
+ return false;
+ }
+
// Compute squared length of vector CX in position coordinate system:
const VectorD<int64_t, 3> x_pos =
next_pos + (cn_dot_pn * pn) / pn_norm2_squared;
diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc
index 428340da013..60429d5c779 100644
--- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc
@@ -18,34 +18,51 @@ namespace draco {
PredictionSchemeMethod SelectPredictionMethod(
int att_id, const PointCloudEncoder *encoder) {
- if (encoder->options()->GetSpeed() >= 10) {
+ return SelectPredictionMethod(att_id, *encoder->options(), encoder);
+}
+
+PredictionSchemeMethod SelectPredictionMethod(
+ int att_id, const EncoderOptions &options,
+ const PointCloudEncoder *encoder) {
+ if (options.GetSpeed() >= 10) {
// Selected fastest, though still doing some compression.
return PREDICTION_DIFFERENCE;
}
if (encoder->GetGeometryType() == TRIANGULAR_MESH) {
// Use speed setting to select the best encoding method.
const PointAttribute *const att = encoder->point_cloud()->attribute(att_id);
- if (att->attribute_type() == GeometryAttribute::TEX_COORD) {
- if (encoder->options()->GetSpeed() < 4) {
+ if (att->attribute_type() == GeometryAttribute::TEX_COORD &&
+ att->num_components() == 2) {
+ if (options.GetSpeed() < 4) {
// Use texture coordinate prediction for speeds 0, 1, 2, 3.
return MESH_PREDICTION_TEX_COORDS_PORTABLE;
}
}
if (att->attribute_type() == GeometryAttribute::NORMAL) {
#ifdef DRACO_NORMAL_ENCODING_SUPPORTED
- if (encoder->options()->GetSpeed() < 4) {
+ if (options.GetSpeed() < 4) {
// Use geometric normal prediction for speeds 0, 1, 2, 3.
- return MESH_PREDICTION_GEOMETRIC_NORMAL;
+ // For this prediction, the position attribute needs to be either
+ // integer or quantized as well.
+ const int pos_att_id = encoder->point_cloud()->GetNamedAttributeId(
+ GeometryAttribute::POSITION);
+ const PointAttribute *const pos_att =
+ encoder->point_cloud()->GetNamedAttribute(
+ GeometryAttribute::POSITION);
+ if (pos_att && (IsDataTypeIntegral(pos_att->data_type()) ||
+ options.GetAttributeInt(pos_att_id, "quantization_bits",
+ -1) > 0)) {
+ return MESH_PREDICTION_GEOMETRIC_NORMAL;
+ }
}
#endif
return PREDICTION_DIFFERENCE; // default
}
// Handle other attribute types.
- if (encoder->options()->GetSpeed() >= 8) {
+ if (options.GetSpeed() >= 8) {
return PREDICTION_DIFFERENCE;
}
- if (encoder->options()->GetSpeed() >= 2 ||
- encoder->point_cloud()->num_points() < 40) {
+ if (options.GetSpeed() >= 2 || encoder->point_cloud()->num_points() < 40) {
// Parallelogram prediction is used for speeds 2 - 7 or when the overhead
// of using constrained multi-parallelogram would be too high.
return MESH_PREDICTION_PARALLELOGRAM;
diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h
index 40a7683aa0d..b7e21224fad 100644
--- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h
@@ -38,6 +38,10 @@ namespace draco {
PredictionSchemeMethod SelectPredictionMethod(int att_id,
const PointCloudEncoder *encoder);
+PredictionSchemeMethod SelectPredictionMethod(int att_id,
+ const EncoderOptions &options,
+ const PointCloudEncoder *encoder);
+
// Factory class for creating mesh prediction schemes.
template <typename DataTypeT>
struct MeshPredictionSchemeEncoderFactory {
diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h
index ab64bce7114..37aa9f76a9c 100644
--- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
-#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODING_INTERFACE_H_
-#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODING_INTERFACE_H_
+#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODER_INTERFACE_H_
+#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODER_INTERFACE_H_
#include "draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h"
#include "draco/core/encoder_buffer.h"
@@ -52,4 +52,4 @@ class PredictionSchemeTypedEncoderInterface
} // namespace draco
-#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODING_INTERFACE_H_
+#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODER_INTERFACE_H_
diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h
index 0a14d0d9ba4..e100c738a6c 100644
--- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h
@@ -36,9 +36,25 @@ class PredictionSchemeWrapDecodingTransform
inline void ComputeOriginalValue(const DataTypeT *predicted_vals,
const CorrTypeT *corr_vals,
DataTypeT *out_original_vals) const {
+ // For now we assume both |DataTypeT| and |CorrTypeT| are equal.
+ static_assert(std::is_same<DataTypeT, CorrTypeT>::value,
+ "Predictions and corrections must have the same type.");
+
+ // The only valid implementation right now is for int32_t.
+ static_assert(std::is_same<DataTypeT, int32_t>::value,
+ "Only int32_t is supported for predicted values.");
+
predicted_vals = this->ClampPredictedValue(predicted_vals);
+
+ // Perform the wrapping using unsigned coordinates to avoid potential signed
+ // integer overflows caused by malformed input.
+ const uint32_t *const uint_predicted_vals =
+ reinterpret_cast<const uint32_t *>(predicted_vals);
+ const uint32_t *const uint_corr_vals =
+ reinterpret_cast<const uint32_t *>(corr_vals);
for (int i = 0; i < this->num_components(); ++i) {
- out_original_vals[i] = predicted_vals[i] + corr_vals[i];
+ out_original_vals[i] =
+ static_cast<DataTypeT>(uint_predicted_vals[i] + uint_corr_vals[i]);
if (out_original_vals[i] > this->max_value()) {
out_original_vals[i] -= this->max_dif();
} else if (out_original_vals[i] < this->min_value()) {
diff --git a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h
index 26f61fbaf6a..979c63c3d11 100644
--- a/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h
@@ -73,7 +73,7 @@ class PredictionSchemeWrapTransformBase {
return &clamped_value_[0];
}
- // TODO(hemmer): Consider refactoring to avoid this dummy.
+ // TODO(b/199760123): Consider refactoring to avoid this dummy.
int quantization_bits() const {
DRACO_DCHECK(false);
return -1;
diff --git a/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.cc
index 521935c1e99..7d5d1eeff26 100644
--- a/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.cc
@@ -26,8 +26,8 @@ SequentialAttributeEncodersController::SequentialAttributeEncodersController(
: sequencer_(std::move(sequencer)) {}
SequentialAttributeEncodersController::SequentialAttributeEncodersController(
- std::unique_ptr<PointsSequencer> sequencer, int att_id)
- : AttributesEncoder(att_id), sequencer_(std::move(sequencer)) {}
+ std::unique_ptr<PointsSequencer> sequencer, int point_attrib_id)
+ : AttributesEncoder(point_attrib_id), sequencer_(std::move(sequencer)) {}
bool SequentialAttributeEncodersController::Init(PointCloudEncoder *encoder,
const PointCloud *pc) {
diff --git a/extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.cc
index d01fb26aad4..17f32fc1612 100644
--- a/extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.cc
@@ -53,6 +53,11 @@ bool SequentialIntegerAttributeDecoder::DecodeValues(
if (!in_buffer->Decode(&prediction_transform_type)) {
return false;
}
+ // Check that decoded prediction scheme transform type is valid.
+ if (prediction_transform_type < PREDICTION_TRANSFORM_NONE ||
+ prediction_transform_type >= NUM_PREDICTION_SCHEME_TRANSFORM_TYPES) {
+ return false;
+ }
prediction_scheme_ = CreateIntPredictionScheme(
static_cast<PredictionSchemeMethod>(prediction_scheme_method),
static_cast<PredictionSchemeTransformType>(prediction_transform_type));
@@ -143,8 +148,9 @@ bool SequentialIntegerAttributeDecoder::DecodeIntegerValues(
return false;
}
for (size_t i = 0; i < num_values; ++i) {
- if (!in_buffer->Decode(portable_attribute_data + i, num_bytes))
+ if (!in_buffer->Decode(portable_attribute_data + i, num_bytes)) {
return false;
+ }
}
}
}
@@ -223,12 +229,13 @@ void SequentialIntegerAttributeDecoder::StoreTypedValues(uint32_t num_values) {
void SequentialIntegerAttributeDecoder::PreparePortableAttribute(
int num_entries, int num_components) {
- GeometryAttribute va;
- va.Init(attribute()->attribute_type(), nullptr, num_components, DT_INT32,
+ GeometryAttribute ga;
+ ga.Init(attribute()->attribute_type(), nullptr, num_components, DT_INT32,
false, num_components * DataTypeLength(DT_INT32), 0);
- std::unique_ptr<PointAttribute> port_att(new PointAttribute(va));
+ std::unique_ptr<PointAttribute> port_att(new PointAttribute(ga));
port_att->SetIdentityMapping();
port_att->Reset(num_entries);
+ port_att->set_unique_id(attribute()->unique_id());
SetPortableAttribute(std::move(port_att));
}
diff --git a/extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.cc
index 2889e0521a0..e66a0a8a40a 100644
--- a/extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.cc
@@ -81,6 +81,9 @@ bool SequentialIntegerAttributeEncoder::TransformAttributeToPortableFormat(
value_to_value_map[orig_att->mapped_index(point_ids[i])] =
AttributeValueIndex(i);
}
+ if (portable_att->is_mapping_identity()) {
+ portable_att->SetExplicitMapping(encoder()->point_cloud()->num_points());
+ }
// Go over all points of the original attribute and update the mapping in
// the portable attribute.
for (PointIndex i(0); i < encoder()->point_cloud()->num_points(); ++i) {
diff --git a/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.cc
index 017344393dc..de36c1c36f2 100644
--- a/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.cc
@@ -14,18 +14,17 @@
//
#include "draco/compression/attributes/sequential_normal_attribute_decoder.h"
-#include "draco/attributes/attribute_octahedron_transform.h"
#include "draco/compression/attributes/normal_compression_utils.h"
namespace draco {
-SequentialNormalAttributeDecoder::SequentialNormalAttributeDecoder()
- : quantization_bits_(-1) {}
+SequentialNormalAttributeDecoder::SequentialNormalAttributeDecoder() {}
bool SequentialNormalAttributeDecoder::Init(PointCloudDecoder *decoder,
int attribute_id) {
- if (!SequentialIntegerAttributeDecoder::Init(decoder, attribute_id))
+ if (!SequentialIntegerAttributeDecoder::Init(decoder, attribute_id)) {
return false;
+ }
// Currently, this encoder works only for 3-component normal vectors.
if (attribute()->num_components() != 3) {
return false;
@@ -41,11 +40,13 @@ bool SequentialNormalAttributeDecoder::DecodeIntegerValues(
const std::vector<PointIndex> &point_ids, DecoderBuffer *in_buffer) {
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
- uint8_t quantization_bits;
- if (!in_buffer->Decode(&quantization_bits)) {
+ // Note: in older bitstreams, we do not have a PortableAttribute() decoded
+ // at this stage so we cannot pass it down to the DecodeParameters() call.
+ // It still works fine for octahedral transform because it does not need to
+ // use any data from the attribute.
+ if (!octahedral_transform_.DecodeParameters(*attribute(), in_buffer)) {
return false;
}
- quantization_bits_ = quantization_bits;
}
#endif
return SequentialIntegerAttributeDecoder::DecodeIntegerValues(point_ids,
@@ -56,39 +57,20 @@ bool SequentialNormalAttributeDecoder::DecodeDataNeededByPortableTransform(
const std::vector<PointIndex> &point_ids, DecoderBuffer *in_buffer) {
if (decoder()->bitstream_version() >= DRACO_BITSTREAM_VERSION(2, 0)) {
// For newer file version, decode attribute transform data here.
- uint8_t quantization_bits;
- if (!in_buffer->Decode(&quantization_bits)) {
+ if (!octahedral_transform_.DecodeParameters(*GetPortableAttribute(),
+ in_buffer)) {
return false;
}
- quantization_bits_ = quantization_bits;
}
// Store the decoded transform data in portable attribute.
- AttributeOctahedronTransform octahedral_transform;
- octahedral_transform.SetParameters(quantization_bits_);
- return octahedral_transform.TransferToAttribute(portable_attribute());
+ return octahedral_transform_.TransferToAttribute(portable_attribute());
}
bool SequentialNormalAttributeDecoder::StoreValues(uint32_t num_points) {
// Convert all quantized values back to floats.
- const int num_components = attribute()->num_components();
- const int entry_size = sizeof(float) * num_components;
- float att_val[3];
- int quant_val_id = 0;
- int out_byte_pos = 0;
- const int32_t *const portable_attribute_data = GetPortableAttributeData();
- OctahedronToolBox octahedron_tool_box;
- if (!octahedron_tool_box.SetQuantizationBits(quantization_bits_))
- return false;
- for (uint32_t i = 0; i < num_points; ++i) {
- const int32_t s = portable_attribute_data[quant_val_id++];
- const int32_t t = portable_attribute_data[quant_val_id++];
- octahedron_tool_box.QuantizedOctaherdalCoordsToUnitVector(s, t, att_val);
- // Store the decoded floating point value into the attribute buffer.
- attribute()->buffer()->Write(out_byte_pos, att_val, entry_size);
- out_byte_pos += entry_size;
- }
- return true;
+ return octahedral_transform_.InverseTransformAttribute(
+ *GetPortableAttribute(), attribute());
}
} // namespace draco
diff --git a/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.h b/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.h
index 860eacb4c84..8c2d801b763 100644
--- a/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.h
@@ -15,6 +15,7 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_NORMAL_ATTRIBUTE_DECODER_H_
#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_NORMAL_ATTRIBUTE_DECODER_H_
+#include "draco/attributes/attribute_octahedron_transform.h"
#include "draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h"
#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h"
#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h"
@@ -42,7 +43,7 @@ class SequentialNormalAttributeDecoder
bool StoreValues(uint32_t num_points) override;
private:
- int32_t quantization_bits_;
+ AttributeOctahedronTransform octahedral_transform_;
std::unique_ptr<PredictionSchemeTypedDecoderInterface<int32_t>>
CreateIntPredictionScheme(
diff --git a/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.cc
index 23fa8bb7b39..3c5ef0ebcbc 100644
--- a/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.cc
@@ -20,8 +20,9 @@ namespace draco {
bool SequentialNormalAttributeEncoder::Init(PointCloudEncoder *encoder,
int attribute_id) {
- if (!SequentialIntegerAttributeEncoder::Init(encoder, attribute_id))
+ if (!SequentialIntegerAttributeEncoder::Init(encoder, attribute_id)) {
return false;
+ }
// Currently this encoder works only for 3-component normal vectors.
if (attribute()->num_components() != 3) {
return false;
@@ -44,9 +45,13 @@ bool SequentialNormalAttributeEncoder::EncodeDataNeededByPortableTransform(
bool SequentialNormalAttributeEncoder::PrepareValues(
const std::vector<PointIndex> &point_ids, int num_points) {
- SetPortableAttribute(
- attribute_octahedron_transform_.GeneratePortableAttribute(
- *(attribute()), point_ids, num_points));
+ auto portable_att = attribute_octahedron_transform_.InitTransformedAttribute(
+ *(attribute()), point_ids.size());
+ if (!attribute_octahedron_transform_.TransformAttribute(
+ *(attribute()), point_ids, portable_att.get())) {
+ return false;
+ }
+ SetPortableAttribute(std::move(portable_att));
return true;
}
diff --git a/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc
index bf925c4a595..3d306e7dae6 100644
--- a/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc
@@ -14,13 +14,12 @@
//
#include "draco/compression/attributes/sequential_quantization_attribute_decoder.h"
-#include "draco/attributes/attribute_quantization_transform.h"
#include "draco/core/quantization_utils.h"
namespace draco {
-SequentialQuantizationAttributeDecoder::SequentialQuantizationAttributeDecoder()
- : quantization_bits_(-1), max_value_dif_(0.f) {}
+SequentialQuantizationAttributeDecoder::
+ SequentialQuantizationAttributeDecoder() {}
bool SequentialQuantizationAttributeDecoder::Init(PointCloudDecoder *decoder,
int attribute_id) {
@@ -59,62 +58,31 @@ bool SequentialQuantizationAttributeDecoder::
}
// Store the decoded transform data in portable attribute;
- AttributeQuantizationTransform transform;
- transform.SetParameters(quantization_bits_, min_value_.get(),
- attribute()->num_components(), max_value_dif_);
- return transform.TransferToAttribute(portable_attribute());
+ return quantization_transform_.TransferToAttribute(portable_attribute());
}
-bool SequentialQuantizationAttributeDecoder::StoreValues(uint32_t num_values) {
- return DequantizeValues(num_values);
+bool SequentialQuantizationAttributeDecoder::StoreValues(uint32_t num_points) {
+ return DequantizeValues(num_points);
}
bool SequentialQuantizationAttributeDecoder::DecodeQuantizedDataInfo() {
- const int num_components = attribute()->num_components();
- min_value_ = std::unique_ptr<float[]>(new float[num_components]);
- if (!decoder()->buffer()->Decode(min_value_.get(),
- sizeof(float) * num_components)) {
- return false;
- }
- if (!decoder()->buffer()->Decode(&max_value_dif_)) {
- return false;
+ // Get attribute used as source for decoding.
+ auto att = GetPortableAttribute();
+ if (att == nullptr) {
+ // This should happen only in the backward compatibility mode. It will still
+ // work fine for this case because the only thing the quantization transform
+ // cares about is the number of components that is the same for both source
+ // and target attributes.
+ att = attribute();
}
- uint8_t quantization_bits;
- if (!decoder()->buffer()->Decode(&quantization_bits) ||
- quantization_bits > 31) {
- return false;
- }
- quantization_bits_ = quantization_bits;
- return true;
+ return quantization_transform_.DecodeParameters(*att, decoder()->buffer());
}
bool SequentialQuantizationAttributeDecoder::DequantizeValues(
uint32_t num_values) {
// Convert all quantized values back to floats.
- const int32_t max_quantized_value =
- (1u << static_cast<uint32_t>(quantization_bits_)) - 1;
- const int num_components = attribute()->num_components();
- const int entry_size = sizeof(float) * num_components;
- const std::unique_ptr<float[]> att_val(new float[num_components]);
- int quant_val_id = 0;
- int out_byte_pos = 0;
- Dequantizer dequantizer;
- if (!dequantizer.Init(max_value_dif_, max_quantized_value)) {
- return false;
- }
- const int32_t *const portable_attribute_data = GetPortableAttributeData();
- for (uint32_t i = 0; i < num_values; ++i) {
- for (int c = 0; c < num_components; ++c) {
- float value =
- dequantizer.DequantizeFloat(portable_attribute_data[quant_val_id++]);
- value = value + min_value_[c];
- att_val[c] = value;
- }
- // Store the floating point value into the attribute buffer.
- attribute()->buffer()->Write(out_byte_pos, att_val.get(), entry_size);
- out_byte_pos += entry_size;
- }
- return true;
+ return quantization_transform_.InverseTransformAttribute(
+ *GetPortableAttribute(), attribute());
}
} // namespace draco
diff --git a/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.h b/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.h
index c0b7637a750..ad372dcd8a6 100644
--- a/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.h
@@ -15,6 +15,7 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_QUANTIZATION_ATTRIBUTE_DECODER_H_
#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_QUANTIZATION_ATTRIBUTE_DECODER_H_
+#include "draco/attributes/attribute_quantization_transform.h"
#include "draco/compression/attributes/sequential_integer_attribute_decoder.h"
#include "draco/draco_features.h"
@@ -43,12 +44,7 @@ class SequentialQuantizationAttributeDecoder
virtual bool DequantizeValues(uint32_t num_values);
private:
- // Max number of quantization bits used to encode each component of the
- // attribute.
- int32_t quantization_bits_;
-
- std::unique_ptr<float[]> min_value_;
- float max_value_dif_;
+ AttributeQuantizationTransform quantization_transform_;
};
} // namespace draco
diff --git a/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc
index cd5b8b141e0..d3666f7a411 100644
--- a/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc
@@ -50,9 +50,11 @@ bool SequentialQuantizationAttributeEncoder::Init(PointCloudEncoder *encoder,
&quantization_origin[0]);
const float range = encoder->options()->GetAttributeFloat(
attribute_id, "quantization_range", 1.f);
- attribute_quantization_transform_.SetParameters(
- quantization_bits, quantization_origin.data(),
- attribute->num_components(), range);
+ if (!attribute_quantization_transform_.SetParameters(
+ quantization_bits, quantization_origin.data(),
+ attribute->num_components(), range)) {
+ return false;
+ }
} else {
// Compute quantization settings from the attribute values.
if (!attribute_quantization_transform_.ComputeParameters(
@@ -70,9 +72,14 @@ bool SequentialQuantizationAttributeEncoder::
bool SequentialQuantizationAttributeEncoder::PrepareValues(
const std::vector<PointIndex> &point_ids, int num_points) {
- SetPortableAttribute(
- attribute_quantization_transform_.GeneratePortableAttribute(
- *(attribute()), point_ids, num_points));
+ auto portable_attribute =
+ attribute_quantization_transform_.InitTransformedAttribute(
+ *attribute(), point_ids.size());
+ if (!attribute_quantization_transform_.TransformAttribute(
+ *(attribute()), point_ids, portable_attribute.get())) {
+ return false;
+ }
+ SetPortableAttribute(std::move(portable_attribute));
return true;
}
diff --git a/extern/draco/draco/src/draco/compression/config/compression_shared.h b/extern/draco/draco/src/draco/compression/config/compression_shared.h
index 40061d3cd48..c43f303bd15 100644
--- a/extern/draco/draco/src/draco/compression/config/compression_shared.h
+++ b/extern/draco/draco/src/draco/compression/config/compression_shared.h
@@ -42,6 +42,7 @@ enum EncodedGeometryType {
INVALID_GEOMETRY_TYPE = -1,
POINT_CLOUD = 0,
TRIANGULAR_MESH,
+ NUM_ENCODED_GEOMETRY_TYPES
};
// List of encoding methods for point clouds.
@@ -105,6 +106,8 @@ enum PredictionSchemeTransformType {
// Specialized transform for normal coordinates using canonicalized inverted
// tiles.
PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON_CANONICALIZED = 3,
+ // The number of valid (non-negative) prediction scheme transform types.
+ NUM_PREDICTION_SCHEME_TRANSFORM_TYPES
};
// List of all mesh traversal methods supported by Draco framework.
diff --git a/extern/draco/draco/src/draco/compression/config/draco_options.h b/extern/draco/draco/src/draco/compression/config/draco_options.h
index 0d1247b2ad1..2bd4a3b6761 100644
--- a/extern/draco/draco/src/draco/compression/config/draco_options.h
+++ b/extern/draco/draco/src/draco/compression/config/draco_options.h
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
-#ifndef DRACO_SRC_DRACO_COMPRESSION_CONFIG_DRACO_OPTIONS_H_
-#define DRACO_SRC_DRACO_COMPRESSION_CONFIG_DRACO_OPTIONS_H_
+#ifndef DRACO_COMPRESSION_CONFIG_DRACO_OPTIONS_H_
+#define DRACO_COMPRESSION_CONFIG_DRACO_OPTIONS_H_
#include <map>
#include <memory>
@@ -246,4 +246,4 @@ void DracoOptions<AttributeKeyT>::SetAttributeOptions(
} // namespace draco
-#endif // DRACO_SRC_DRACO_COMPRESSION_CONFIG_DRACO_OPTIONS_H_
+#endif // DRACO_COMPRESSION_CONFIG_DRACO_OPTIONS_H_
diff --git a/extern/draco/draco/src/draco/compression/decode.cc b/extern/draco/draco/src/draco/compression/decode.cc
index ab70ef1ec60..92ae4ff66f9 100644
--- a/extern/draco/draco/src/draco/compression/decode.cc
+++ b/extern/draco/draco/src/draco/compression/decode.cc
@@ -56,7 +56,10 @@ StatusOr<EncodedGeometryType> Decoder::GetEncodedGeometryType(
DecoderBuffer *in_buffer) {
DecoderBuffer temp_buffer(*in_buffer);
DracoHeader header;
- DRACO_RETURN_IF_ERROR(PointCloudDecoder::DecodeHeader(&temp_buffer, &header))
+ DRACO_RETURN_IF_ERROR(PointCloudDecoder::DecodeHeader(&temp_buffer, &header));
+ if (header.encoder_type >= NUM_ENCODED_GEOMETRY_TYPES) {
+ return Status(Status::DRACO_ERROR, "Unsupported geometry type.");
+ }
return static_cast<EncodedGeometryType>(header.encoder_type);
}
diff --git a/extern/draco/draco/src/draco/compression/encode_base.h b/extern/draco/draco/src/draco/compression/encode_base.h
index 0c63a972bf4..6211efc221b 100644
--- a/extern/draco/draco/src/draco/compression/encode_base.h
+++ b/extern/draco/draco/src/draco/compression/encode_base.h
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
-#ifndef DRACO_SRC_DRACO_COMPRESSION_ENCODE_BASE_H_
-#define DRACO_SRC_DRACO_COMPRESSION_ENCODE_BASE_H_
+#ifndef DRACO_COMPRESSION_ENCODE_BASE_H_
+#define DRACO_COMPRESSION_ENCODE_BASE_H_
#include "draco/attributes/geometry_attribute.h"
#include "draco/compression/config/compression_shared.h"
@@ -98,7 +98,7 @@ class EncoderBase {
"Invalid prediction scheme for attribute type.");
}
}
- // TODO(hemmer): Try to enable more prediction schemes for normals.
+ // TODO(b/199760123): Try to enable more prediction schemes for normals.
if (att_type == GeometryAttribute::NORMAL) {
if (!(prediction_scheme == PREDICTION_DIFFERENCE ||
prediction_scheme == MESH_PREDICTION_GEOMETRIC_NORMAL)) {
@@ -128,4 +128,4 @@ void EncoderBase<EncoderOptionsT>::SetTrackEncodedProperties(bool flag) {
} // namespace draco
-#endif // DRACO_SRC_DRACO_COMPRESSION_ENCODE_BASE_H_
+#endif // DRACO_COMPRESSION_ENCODE_BASE_H_
diff --git a/extern/draco/draco/src/draco/compression/entropy/ans.h b/extern/draco/draco/src/draco/compression/entropy/ans.h
index c765256b96e..313546fee20 100644
--- a/extern/draco/draco/src/draco/compression/entropy/ans.h
+++ b/extern/draco/draco/src/draco/compression/entropy/ans.h
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
-#ifndef DRACO_CORE_ANS_H_
-#define DRACO_CORE_ANS_H_
+#ifndef DRACO_COMPRESSION_ENTROPY_ANS_H_
+#define DRACO_COMPRESSION_ENTROPY_ANS_H_
// An implementation of Asymmetric Numeral Systems (rANS).
// See http://arxiv.org/abs/1311.2540v2 for more information on rANS.
// This file is based off libvpx's ans.h.
@@ -391,7 +391,6 @@ class RAnsEncoder {
ans_.buf[ans_.buf_offset++] = ans_.state % DRACO_ANS_IO_BASE;
ans_.state /= DRACO_ANS_IO_BASE;
}
- // TODO(ostava): The division and multiplication should be optimized.
ans_.state =
(ans_.state / p) * rans_precision + ans_.state % p + sym->cum_prob;
}
@@ -524,4 +523,4 @@ class RAnsDecoder {
} // namespace draco
-#endif // DRACO_CORE_ANS_H_
+#endif // DRACO_COMPRESSION_ENTROPY_ANS_H_
diff --git a/extern/draco/draco/src/draco/compression/entropy/rans_symbol_coding.h b/extern/draco/draco/src/draco/compression/entropy/rans_symbol_coding.h
index 0a68e29fe26..cd4271193bf 100644
--- a/extern/draco/draco/src/draco/compression/entropy/rans_symbol_coding.h
+++ b/extern/draco/draco/src/draco/compression/entropy/rans_symbol_coding.h
@@ -31,11 +31,10 @@ constexpr int ComputeRAnsUnclampedPrecision(int symbols_bit_length) {
// our rANS library (which is between 12 to 20 bits).
constexpr int ComputeRAnsPrecisionFromUniqueSymbolsBitLength(
int symbols_bit_length) {
- return ComputeRAnsUnclampedPrecision(symbols_bit_length) < 12
- ? 12
- : ComputeRAnsUnclampedPrecision(symbols_bit_length) > 20
- ? 20
- : ComputeRAnsUnclampedPrecision(symbols_bit_length);
+ return ComputeRAnsUnclampedPrecision(symbols_bit_length) < 12 ? 12
+ : ComputeRAnsUnclampedPrecision(symbols_bit_length) > 20
+ ? 20
+ : ComputeRAnsUnclampedPrecision(symbols_bit_length);
}
// Compute approximate frequency table size needed for storing the provided
diff --git a/extern/draco/draco/src/draco/compression/entropy/rans_symbol_encoder.h b/extern/draco/draco/src/draco/compression/entropy/rans_symbol_encoder.h
index 4e07ec87123..4b738b50a9d 100644
--- a/extern/draco/draco/src/draco/compression/entropy/rans_symbol_encoder.h
+++ b/extern/draco/draco/src/draco/compression/entropy/rans_symbol_encoder.h
@@ -125,8 +125,8 @@ bool RAnsSymbolEncoder<unique_symbols_bit_length_t>::Create(
for (int i = 0; i < num_symbols; ++i) {
sorted_probabilities[i] = i;
}
- std::sort(sorted_probabilities.begin(), sorted_probabilities.end(),
- ProbabilityLess(&probability_table_));
+ std::stable_sort(sorted_probabilities.begin(), sorted_probabilities.end(),
+ ProbabilityLess(&probability_table_));
if (total_rans_prob < rans_precision_) {
// This happens rather infrequently, just add the extra needed precision
// to the most frequent symbol.
diff --git a/extern/draco/draco/src/draco/compression/entropy/symbol_decoding.cc b/extern/draco/draco/src/draco/compression/entropy/symbol_decoding.cc
index 93d29971c89..79e81181830 100644
--- a/extern/draco/draco/src/draco/compression/entropy/symbol_decoding.cc
+++ b/extern/draco/draco/src/draco/compression/entropy/symbol_decoding.cc
@@ -72,7 +72,7 @@ bool DecodeTaggedSymbols(uint32_t num_values, int num_components,
int value_id = 0;
for (uint32_t i = 0; i < num_values; i += num_components) {
// Decode the tag.
- const int bit_length = tag_decoder.DecodeSymbol();
+ const uint32_t bit_length = tag_decoder.DecodeSymbol();
// Decode the actual value.
for (int j = 0; j < num_components; ++j) {
uint32_t val;
diff --git a/extern/draco/draco/src/draco/compression/expert_encode.cc b/extern/draco/draco/src/draco/compression/expert_encode.cc
index 4c70a72a765..f9aec15eb27 100644
--- a/extern/draco/draco/src/draco/compression/expert_encode.cc
+++ b/extern/draco/draco/src/draco/compression/expert_encode.cc
@@ -67,7 +67,7 @@ Status ExpertEncoder::EncodePointCloudToBuffer(const PointCloud &pc,
kd_tree_possible = false;
}
if (kd_tree_possible && att->data_type() == DT_FLOAT32 &&
- options().GetAttributeInt(0, "quantization_bits", -1) <= 0) {
+ options().GetAttributeInt(i, "quantization_bits", -1) <= 0) {
kd_tree_possible = false; // Quantization not enabled.
}
if (!kd_tree_possible) {
diff --git a/extern/draco/draco/src/draco/compression/expert_encode.h b/extern/draco/draco/src/draco/compression/expert_encode.h
index a1aa7b8b3a8..ea59393d3d2 100644
--- a/extern/draco/draco/src/draco/compression/expert_encode.h
+++ b/extern/draco/draco/src/draco/compression/expert_encode.h
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
-#ifndef DRACO_SRC_DRACO_COMPRESSION_EXPERT_ENCODE_H_
-#define DRACO_SRC_DRACO_COMPRESSION_EXPERT_ENCODE_H_
+#ifndef DRACO_COMPRESSION_EXPERT_ENCODE_H_
+#define DRACO_COMPRESSION_EXPERT_ENCODE_H_
#include "draco/compression/config/compression_shared.h"
#include "draco/compression/config/encoder_options.h"
@@ -144,4 +144,4 @@ class ExpertEncoder : public EncoderBase<EncoderOptions> {
} // namespace draco
-#endif // DRACO_SRC_DRACO_COMPRESSION_EXPERT_ENCODE_H_
+#endif // DRACO_COMPRESSION_EXPERT_ENCODE_H_
diff --git a/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc
index 50d1971c15b..6d22e2f2a32 100644
--- a/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc
@@ -162,6 +162,10 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::CreateAttributesDecoder(
if (!decoder_->buffer()->Decode(&traversal_method_encoded)) {
return false;
}
+ // Check that decoded traversal method is valid.
+ if (traversal_method_encoded >= NUM_TRAVERSAL_METHODS) {
+ return false;
+ }
traversal_method =
static_cast<MeshTraversalMethod>(traversal_method_encoded);
}
@@ -450,7 +454,7 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity() {
#endif
// Decode connectivity of non-position attributes.
- if (attribute_data_.size() > 0) {
+ if (!attribute_data_.empty()) {
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 1)) {
for (CornerIndex ci(0); ci < corner_table_->num_corners(); ci += 3) {
@@ -577,11 +581,16 @@ int MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity(
SetOppositeCorners(corner_b, corner + 2);
// Update vertex mapping.
- corner_table_->MapCornerToVertex(corner, vertex_x);
- corner_table_->MapCornerToVertex(
- corner + 1, corner_table_->Vertex(corner_table_->Next(corner_b)));
const VertexIndex vert_a_prev =
corner_table_->Vertex(corner_table_->Previous(corner_a));
+ const VertexIndex vert_b_next =
+ corner_table_->Vertex(corner_table_->Next(corner_b));
+ if (vertex_x == vert_a_prev || vertex_x == vert_b_next) {
+ // Encoding is invalid, because face vertices are degenerate.
+ return -1;
+ }
+ corner_table_->MapCornerToVertex(corner, vertex_x);
+ corner_table_->MapCornerToVertex(corner + 1, vert_b_next);
corner_table_->MapCornerToVertex(corner + 2, vert_a_prev);
corner_table_->SetLeftMostCorner(vert_a_prev, corner + 2);
// Mark the vertex |x| as interior.
@@ -791,7 +800,7 @@ int MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity(
return -1; // Unexpected number of decoded vertices.
}
// Decode start faces and connect them to the faces from the active stack.
- while (active_corner_stack.size() > 0) {
+ while (!active_corner_stack.empty()) {
const CornerIndex corner = active_corner_stack.back();
active_corner_stack.pop_back();
const bool interior_face =
@@ -952,9 +961,13 @@ MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeHoleAndTopologySplitEvents(
for (uint32_t i = 0; i < num_topology_splits; ++i) {
TopologySplitEventData event_data;
uint32_t delta;
- DecodeVarint<uint32_t>(&delta, decoder_buffer);
+ if (!DecodeVarint<uint32_t>(&delta, decoder_buffer)) {
+ return -1;
+ }
event_data.source_symbol_id = delta + last_source_symbol_id;
- DecodeVarint<uint32_t>(&delta, decoder_buffer);
+ if (!DecodeVarint<uint32_t>(&delta, decoder_buffer)) {
+ return -1;
+ }
if (delta > event_data.source_symbol_id) {
return -1;
}
@@ -1009,7 +1022,9 @@ MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeHoleAndTopologySplitEvents(
for (uint32_t i = 0; i < num_hole_events; ++i) {
HoleEventData event_data;
uint32_t delta;
- DecodeVarint<uint32_t>(&delta, decoder_buffer);
+ if (!DecodeVarint<uint32_t>(&delta, decoder_buffer)) {
+ return -1;
+ }
event_data.symbol_id = delta + last_symbol_id;
last_symbol_id = event_data.symbol_id;
hole_event_data_.push_back(event_data);
diff --git a/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder.cc b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder.cc
index 5aff5d8cc10..a7f381480f1 100644
--- a/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder.cc
@@ -31,7 +31,6 @@ bool MeshEdgebreakerEncoder::InitializeEncoder() {
impl_ = nullptr;
// For tiny meshes it's usually better to use the basic edgebreaker as the
// overhead of the predictive one may turn out to be too big.
- // TODO(b/111065939): Check if this can be improved.
const bool is_tiny_mesh = mesh()->num_faces() < 1000;
int selected_edgebreaker_method =
diff --git a/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.cc b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.cc
index 0791dc6705a..4bf6aa92070 100644
--- a/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.cc
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.cc
@@ -408,7 +408,7 @@ Status MeshEdgebreakerEncoderImpl<TraversalEncoder>::EncodeConnectivity() {
init_face_connectivity_corners.begin(),
init_face_connectivity_corners.end());
// Encode connectivity for all non-position attributes.
- if (attribute_data_.size() > 0) {
+ if (!attribute_data_.empty()) {
// Use the same order of corner that will be used by the decoder.
visited_faces_.assign(mesh_->num_faces(), false);
for (CornerIndex ci : processed_connectivity_corners_) {
diff --git a/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h
index fb33771637e..979e1d373d8 100644
--- a/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h
@@ -177,7 +177,6 @@ class MeshEdgebreakerEncoderImpl : public MeshEdgebreakerEncoderImplInterface {
uint32_t num_split_symbols_;
// Struct holding data used for encoding each non-position attribute.
- // TODO(ostava): This should be probably renamed to something better.
struct AttributeData {
AttributeData() : attribute_index(-1), is_connectivity_used(true) {}
int attribute_index;
diff --git a/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_shared.h b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_shared.h
index cb3c29dd669..c650bc35210 100644
--- a/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_shared.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_shared.h
@@ -50,8 +50,6 @@ namespace draco {
// \ / S \ / / E \
// *-------* *-------*
//
-// TODO(ostava): Get rid of the topology bit pattern. It's important only for
-// encoding but the algorithms should use EdgebreakerSymbol instead.
enum EdgebreakerTopologyBitPattern {
TOPOLOGY_C = 0x0, // 0
TOPOLOGY_S = 0x1, // 1 0 0
diff --git a/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h
index 621883a5f1f..c00373727df 100644
--- a/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h
@@ -106,7 +106,12 @@ class MeshEdgebreakerTraversalValenceDecoder
context_counters_.resize(context_symbols_.size());
for (int i = 0; i < context_symbols_.size(); ++i) {
uint32_t num_symbols;
- DecodeVarint<uint32_t>(&num_symbols, out_buffer);
+ if (!DecodeVarint<uint32_t>(&num_symbols, out_buffer)) {
+ return false;
+ }
+ if (num_symbols > static_cast<uint32_t>(corner_table_->num_faces())) {
+ return false;
+ }
if (num_symbols > 0) {
context_symbols_[i].resize(num_symbols);
DecodeSymbols(num_symbols, 1, out_buffer, context_symbols_[i].data());
diff --git a/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_decoder.cc b/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_decoder.cc
index 53f5e8651b8..fbc7383eef1 100644
--- a/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_decoder.cc
@@ -53,6 +53,11 @@ bool MeshSequentialDecoder::DecodeConnectivity() {
if (faces_64 > 0xffffffff / 3) {
return false;
}
+ if (faces_64 > buffer()->remaining_size() / 3) {
+ // The number of faces is unreasonably high, because face indices do not
+ // fit in the remaining size of the buffer.
+ return false;
+ }
if (points_64 > faces_64 * 3) {
return false;
}
@@ -91,7 +96,7 @@ bool MeshSequentialDecoder::DecodeConnectivity() {
}
mesh()->AddFace(face);
}
- } else if (mesh()->num_points() < (1 << 21) &&
+ } else if (num_points < (1 << 21) &&
bitstream_version() >= DRACO_BITSTREAM_VERSION(2, 2)) {
// Decode indices as uint32_t.
for (uint32_t i = 0; i < num_faces; ++i) {
diff --git a/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_encoder.cc b/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_encoder.cc
index 02ac7779ea3..fd8b1139253 100644
--- a/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_encoder.cc
@@ -32,8 +32,6 @@ Status MeshSequentialEncoder::EncodeConnectivity() {
EncodeVarint(static_cast<uint32_t>(mesh()->num_points()), buffer());
// We encode all attributes in the original (possibly duplicated) format.
- // TODO(ostava): This may not be optimal if we have only one attribute or if
- // all attributes share the same index mapping.
if (options()->GetGlobalBool("compress_connectivity", false)) {
// 0 = Encode compressed indices.
buffer()->Encode(static_cast<uint8_t>(0));
@@ -44,8 +42,6 @@ Status MeshSequentialEncoder::EncodeConnectivity() {
// 1 = Encode indices directly.
buffer()->Encode(static_cast<uint8_t>(1));
// Store vertex indices using a smallest data type that fits their range.
- // TODO(ostava): This can be potentially improved by using a tighter
- // fit that is not bound by a bit-length of any particular data type.
if (mesh()->num_points() < 256) {
// Serialize indices as uint8_t.
for (FaceIndex i(0); i < num_faces; ++i) {
diff --git a/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_encoder.h b/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_encoder.h
index 672609642b0..6e2b05877ab 100644
--- a/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_encoder.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_encoder.h
@@ -33,7 +33,6 @@ namespace draco {
// Class that encodes mesh data using a simple binary representation of mesh's
// connectivity and geometry.
-// TODO(ostava): Use a better name.
class MeshSequentialEncoder : public MeshEncoder {
public:
MeshSequentialEncoder();
diff --git a/extern/draco/draco/src/draco/compression/mesh/traverser/mesh_attribute_indices_encoding_observer.h b/extern/draco/draco/src/draco/compression/mesh/traverser/mesh_attribute_indices_encoding_observer.h
index e66dd14b238..dd9738ba2d5 100644
--- a/extern/draco/draco/src/draco/compression/mesh/traverser/mesh_attribute_indices_encoding_observer.h
+++ b/extern/draco/draco/src/draco/compression/mesh/traverser/mesh_attribute_indices_encoding_observer.h
@@ -25,7 +25,7 @@ namespace draco {
// values based on the traversal of the encoded mesh. The class should be used
// as the TraversalObserverT member of a Traverser class such as the
// DepthFirstTraverser (depth_first_traverser.h).
-// TODO(hemmer): rename to AttributeIndicesCodingTraverserObserver
+// TODO(b/199760123): Rename to AttributeIndicesCodingTraverserObserver.
template <class CornerTableT>
class MeshAttributeIndicesEncodingObserver {
public:
diff --git a/extern/draco/draco/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h b/extern/draco/draco/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h
index ebe1d5f7a9e..e55c93a7969 100644
--- a/extern/draco/draco/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h
+++ b/extern/draco/draco/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h
@@ -25,7 +25,7 @@ namespace draco {
// Sequencer that generates point sequence in an order given by a deterministic
// traversal on the mesh surface. Note that all attributes encoded with this
// sequence must share the same connectivity.
-// TODO(hemmer): Consider refactoring such that this is an observer.
+// TODO(b/199760123): Consider refactoring such that this is an observer.
template <class TraverserT>
class MeshTraversalSequencer : public PointsSequencer {
public:
diff --git a/extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h
index 87bc2b7ef3e..fa1b1e203e5 100644
--- a/extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h
@@ -227,7 +227,7 @@ bool DynamicIntegerPointsKdTreeDecoder<compression_level_t>::DecodeInternal(
std::stack<Status> status_stack;
status_stack.push(init_status);
- // TODO(hemmer): use preallocated vector instead of stack.
+ // TODO(b/199760123): Use preallocated vector instead of stack.
while (!status_stack.empty()) {
const DecodingStatus status = status_stack.top();
status_stack.pop();
@@ -263,7 +263,8 @@ bool DynamicIntegerPointsKdTreeDecoder<compression_level_t>::DecodeInternal(
// Fast decoding of remaining bits if number of points is 1 or 2.
if (num_remaining_points <= 2) {
- // TODO(hemmer): axes_ not necessary, remove would change bitstream!
+ // TODO(b/199760123): |axes_| not necessary, remove would change
+ // bitstream!
axes_[0] = axis;
for (uint32_t i = 1; i < dimension_; i++) {
axes_[i] = DRACO_INCREMENT_MOD(axes_[i - 1], dimension_);
diff --git a/extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h
index 14fa32d7083..65b3d07a6ad 100644
--- a/extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h
@@ -280,7 +280,7 @@ void DynamicIntegerPointsKdTreeEncoder<compression_level_t>::EncodeInternal(
std::stack<Status> status_stack;
status_stack.push(init_status);
- // TODO(hemmer): use preallocated vector instead of stack.
+ // TODO(b/199760123): Use preallocated vector instead of stack.
while (!status_stack.empty()) {
Status status = status_stack.top();
status_stack.pop();
@@ -305,7 +305,8 @@ void DynamicIntegerPointsKdTreeEncoder<compression_level_t>::EncodeInternal(
// Fast encoding of remaining bits if number of points is 1 or 2.
// Doing this also for 2 gives a slight additional speed up.
if (num_remaining_points <= 2) {
- // TODO(hemmer): axes_ not necessary, remove would change bitstream!
+ // TODO(b/199760123): |axes_| not necessary, remove would change
+ // bitstream!
axes_[0] = axis;
for (uint32_t i = 1; i < dimension_; i++) {
axes_[i] = DRACO_INCREMENT_MOD(axes_[i - 1], dimension_);
diff --git a/extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.cc b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.cc
index 9e8d895f176..dffaa4c8d20 100644
--- a/extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.cc
@@ -69,18 +69,29 @@ FloatPointsTreeDecoder::FloatPointsTreeDecoder()
bool FloatPointsTreeDecoder::DecodePointCloudKdTreeInternal(
DecoderBuffer *buffer, std::vector<Point3ui> *qpoints) {
- if (!buffer->Decode(&qinfo_.quantization_bits)) return false;
- if (qinfo_.quantization_bits > 31) return false;
- if (!buffer->Decode(&qinfo_.range)) return false;
- if (!buffer->Decode(&num_points_)) return false;
- if (num_points_from_header_ > 0 && num_points_ != num_points_from_header_)
+ if (!buffer->Decode(&qinfo_.quantization_bits)) {
return false;
- if (!buffer->Decode(&compression_level_)) return false;
+ }
+ if (qinfo_.quantization_bits > 31) {
+ return false;
+ }
+ if (!buffer->Decode(&qinfo_.range)) {
+ return false;
+ }
+ if (!buffer->Decode(&num_points_)) {
+ return false;
+ }
+ if (num_points_from_header_ > 0 && num_points_ != num_points_from_header_) {
+ return false;
+ }
+ if (!buffer->Decode(&compression_level_)) {
+ return false;
+ }
// Only allow compression level in [0..6].
if (6 < compression_level_) {
- LOGE("FloatPointsTreeDecoder: compression level %i not supported.\n",
- compression_level_);
+ DRACO_LOGE("FloatPointsTreeDecoder: compression level %i not supported.\n",
+ compression_level_);
return false;
}
diff --git a/extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.h b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.h
index 26ba94f1f59..44c1b3d3a97 100644
--- a/extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.h
@@ -44,7 +44,7 @@ namespace draco {
// there are more leading zeros, which is then compressed better by the
// arithmetic encoding.
-// TODO(hemmer): Remove class because it duplicates quantization code.
+// TODO(b/199760123): Remove class because it duplicates quantization code.
class FloatPointsTreeEncoder {
public:
explicit FloatPointsTreeEncoder(PointCloudCompressionMethod method);
@@ -91,7 +91,7 @@ bool FloatPointsTreeEncoder::EncodePointCloud(InputIteratorT points_begin,
// Collect necessary data for encoding.
num_points_ = std::distance(points_begin, points_end);
- // TODO(hemmer): Extend quantization tools to make this more automatic.
+ // TODO(b/199760123): Extend quantization tools to make this more automatic.
// Compute range of points for quantization
std::vector<Point3ui> qpoints;
qpoints.reserve(num_points_);
diff --git a/extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.h b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.h
index 94e523cadaf..bc31af58613 100644
--- a/extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.h
@@ -12,7 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
-// TODO(hemmer): Make this a wrapper using DynamicIntegerPointsKdTreeDecoder.
+// TODO(b/199760123): Make this a wrapper using
+// DynamicIntegerPointsKdTreeDecoder.
//
// See integer_points_kd_tree_encoder.h for documentation.
diff --git a/extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.h b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.h
index b8811092ed7..654f14a7866 100644
--- a/extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.h
@@ -12,7 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
-// TODO(hemmer): Make this a wrapper using DynamicIntegerPointsKdTreeEncoder.
+// TODO(b/199760123): Make this a wrapper using
+// DynamicIntegerPointsKdTreeEncoder.
#ifndef DRACO_COMPRESSION_POINT_CLOUD_ALGORITHMS_INTEGER_POINTS_KD_TREE_ENCODER_H_
#define DRACO_COMPRESSION_POINT_CLOUD_ALGORITHMS_INTEGER_POINTS_KD_TREE_ENCODER_H_
diff --git a/extern/draco/draco/src/draco/compression/point_cloud/algorithms/quantize_points_3.h b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/quantize_points_3.h
index 01943ad9e6c..04aa1d95e11 100644
--- a/extern/draco/draco/src/draco/compression/point_cloud/algorithms/quantize_points_3.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/quantize_points_3.h
@@ -22,7 +22,7 @@
namespace draco {
-// TODO(hemmer): Make this a stable bounding box.
+// TODO(b/199760123): Make this a stable bounding box.
struct QuantizationInfo {
uint32_t quantization_bits;
float range;
diff --git a/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_decoder.cc b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_decoder.cc
index 5196edf960c..85f7bc94e33 100644
--- a/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_decoder.cc
@@ -88,7 +88,9 @@ Status PointCloudDecoder::Decode(const DecoderOptions &options,
const uint8_t max_supported_minor_version =
header.encoder_type == POINT_CLOUD ? kDracoPointCloudBitstreamVersionMinor
: kDracoMeshBitstreamVersionMinor;
+
// Check for version compatibility.
+#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (version_major_ < 1 || version_major_ > max_supported_major_version) {
return Status(Status::UNKNOWN_VERSION, "Unknown major version.");
}
@@ -96,6 +98,14 @@ Status PointCloudDecoder::Decode(const DecoderOptions &options,
version_minor_ > max_supported_minor_version) {
return Status(Status::UNKNOWN_VERSION, "Unknown minor version.");
}
+#else
+ if (version_major_ != max_supported_major_version) {
+ return Status(Status::UNKNOWN_VERSION, "Unsupported major version.");
+ }
+ if (version_minor_ != max_supported_minor_version) {
+ return Status(Status::UNKNOWN_VERSION, "Unsupported minor version.");
+ }
+#endif
buffer_->set_bitstream_version(
DRACO_BITSTREAM_VERSION(version_major_, version_minor_));
diff --git a/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_encoder.cc b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_encoder.cc
index b4b0ee94093..a1fda8d5a50 100644
--- a/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_encoder.cc
@@ -62,12 +62,14 @@ Status PointCloudEncoder::EncodeHeader() {
buffer_->Encode("DRACO", 5);
// Version (major, minor).
const uint8_t encoder_type = GetGeometryType();
- const uint8_t version_major = encoder_type == POINT_CLOUD
- ? kDracoPointCloudBitstreamVersionMajor
- : kDracoMeshBitstreamVersionMajor;
- const uint8_t version_minor = encoder_type == POINT_CLOUD
- ? kDracoPointCloudBitstreamVersionMinor
- : kDracoMeshBitstreamVersionMinor;
+ uint8_t version_major, version_minor;
+ version_major = encoder_type == POINT_CLOUD
+ ? kDracoPointCloudBitstreamVersionMajor
+ : kDracoMeshBitstreamVersionMajor;
+ version_minor = encoder_type == POINT_CLOUD
+ ? kDracoPointCloudBitstreamVersionMinor
+ : kDracoMeshBitstreamVersionMinor;
+
buffer_->Encode(version_major);
buffer_->Encode(version_minor);
// Type of the encoder (point cloud, mesh, ...).
diff --git a/extern/draco/draco/src/draco/core/bounding_box.cc b/extern/draco/draco/src/draco/core/bounding_box.cc
index d95b1e90759..be0d209d857 100644
--- a/extern/draco/draco/src/draco/core/bounding_box.cc
+++ b/extern/draco/draco/src/draco/core/bounding_box.cc
@@ -16,8 +16,15 @@
namespace draco {
-BoundingBox::BoundingBox(const Vector3f &min_point_in,
- const Vector3f &max_point_in)
- : min_point_(min_point_in), max_point_(max_point_in) {}
+BoundingBox::BoundingBox()
+ : BoundingBox(Vector3f(std::numeric_limits<float>::max(),
+ std::numeric_limits<float>::max(),
+ std::numeric_limits<float>::max()),
+ Vector3f(std::numeric_limits<float>::lowest(),
+ std::numeric_limits<float>::lowest(),
+ std::numeric_limits<float>::lowest())) {}
+
+BoundingBox::BoundingBox(const Vector3f &min_point, const Vector3f &max_point)
+ : min_point_(min_point), max_point_(max_point) {}
} // namespace draco
diff --git a/extern/draco/draco/src/draco/core/bounding_box.h b/extern/draco/draco/src/draco/core/bounding_box.h
index 1c20fad8bf2..31ba2d68340 100644
--- a/extern/draco/draco/src/draco/core/bounding_box.h
+++ b/extern/draco/draco/src/draco/core/bounding_box.h
@@ -19,22 +19,27 @@
namespace draco {
-// Class for detecting the bounding box of a point_cloud or mesh.
-// Use the minimum point and the maximum point to define the bounding box.
-// TODO(xiaoxumeng): Change the class of BoundingBox to a template, similar to
-// draco/src/draco/core/vector_d.h
+// Class for computing the bounding box of points in 3D space.
class BoundingBox {
public:
- // Initialization
- BoundingBox(const Vector3f &min_point_in, const Vector3f &max_point_in);
+ // Creates bounding box object with minimum and maximum points initialized to
+ // the largest positive and the smallest negative values, respectively. The
+ // resulting abstract bounding box effectively has no points and can be
+ // updated by providing any point to Update() method.
+ BoundingBox();
- inline const Vector3f &min_point() const { return min_point_; }
- inline const Vector3f &max_point() const { return max_point_; }
+ // Creates bounding box object with minimum and maximum points initialized to
+ // |min_point| and |max_point|, respectively.
+ BoundingBox(const Vector3f &min_point, const Vector3f &max_point);
- // Conditionally updates the bounding box.
- // TODO(xiaoxumeng): Change the function to a template function and change the
- // argument to an iterator.
- inline void update_bounding_box(const Vector3f &new_point) {
+ // Returns the minimum point of the bounding box.
+ inline const Vector3f &GetMinPoint() const { return min_point_; }
+
+ // Returns the maximum point of the bounding box.
+ inline const Vector3f &GetMaxPoint() const { return max_point_; }
+
+ // Conditionally updates the bounding box with a given |new_point|.
+ void Update(const Vector3f &new_point) {
for (int i = 0; i < 3; i++) {
if (new_point[i] < min_point_[i]) {
min_point_[i] = new_point[i];
@@ -45,6 +50,19 @@ class BoundingBox {
}
}
+ // Updates bounding box with minimum and maximum points of the |other|
+ // bounding box.
+ void Update(const BoundingBox &other) {
+ Update(other.GetMinPoint());
+ Update(other.GetMaxPoint());
+ }
+
+ // Returns the size of the bounding box along each axis.
+ Vector3f Size() const { return max_point_ - min_point_; }
+
+ // Returns the center of the bounding box.
+ Vector3f Center() const { return (min_point_ + max_point_) / 2; }
+
private:
Vector3f min_point_;
Vector3f max_point_;
diff --git a/extern/draco/draco/src/draco/core/cycle_timer.cc b/extern/draco/draco/src/draco/core/cycle_timer.cc
index 94b4b28b2f9..58df4df77de 100644
--- a/extern/draco/draco/src/draco/core/cycle_timer.cc
+++ b/extern/draco/draco/src/draco/core/cycle_timer.cc
@@ -17,31 +17,31 @@
namespace draco {
void DracoTimer::Start() {
#ifdef _WIN32
- QueryPerformanceCounter(&tv_start);
+ QueryPerformanceCounter(&tv_start_);
#else
- gettimeofday(&tv_start, nullptr);
+ gettimeofday(&tv_start_, nullptr);
#endif
}
void DracoTimer::Stop() {
#ifdef _WIN32
- QueryPerformanceCounter(&tv_end);
+ QueryPerformanceCounter(&tv_end_);
#else
- gettimeofday(&tv_end, nullptr);
+ gettimeofday(&tv_end_, nullptr);
#endif
}
int64_t DracoTimer::GetInMs() {
#ifdef _WIN32
LARGE_INTEGER elapsed = {0};
- elapsed.QuadPart = tv_end.QuadPart - tv_start.QuadPart;
+ elapsed.QuadPart = tv_end_.QuadPart - tv_start_.QuadPart;
LARGE_INTEGER frequency = {0};
QueryPerformanceFrequency(&frequency);
return elapsed.QuadPart * 1000 / frequency.QuadPart;
#else
- const int64_t seconds = (tv_end.tv_sec - tv_start.tv_sec) * 1000;
- const int64_t milliseconds = (tv_end.tv_usec - tv_start.tv_usec) / 1000;
+ const int64_t seconds = (tv_end_.tv_sec - tv_start_.tv_sec) * 1000;
+ const int64_t milliseconds = (tv_end_.tv_usec - tv_start_.tv_usec) / 1000;
return seconds + milliseconds;
#endif
}
diff --git a/extern/draco/draco/src/draco/core/cycle_timer.h b/extern/draco/draco/src/draco/core/cycle_timer.h
index 172f1c2e9b5..f480cc9d389 100644
--- a/extern/draco/draco/src/draco/core/cycle_timer.h
+++ b/extern/draco/draco/src/draco/core/cycle_timer.h
@@ -20,9 +20,10 @@
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
-typedef LARGE_INTEGER timeval;
+typedef LARGE_INTEGER DracoTimeVal;
#else
#include <sys/time.h>
+typedef timeval DracoTimeVal;
#endif
#include <cinttypes>
@@ -39,8 +40,8 @@ class DracoTimer {
int64_t GetInMs();
private:
- timeval tv_start;
- timeval tv_end;
+ DracoTimeVal tv_start_;
+ DracoTimeVal tv_end_;
};
typedef DracoTimer CycleTimer;
diff --git a/extern/draco/draco/src/draco/core/data_buffer.cc b/extern/draco/draco/src/draco/core/data_buffer.cc
index f0b43d67dbd..96a3787987c 100644
--- a/extern/draco/draco/src/draco/core/data_buffer.cc
+++ b/extern/draco/draco/src/draco/core/data_buffer.cc
@@ -52,7 +52,7 @@ void DataBuffer::Resize(int64_t size) {
}
void DataBuffer::WriteDataToStream(std::ostream &stream) {
- if (data_.size() == 0) {
+ if (data_.empty()) {
return;
}
stream.write(reinterpret_cast<char *>(data_.data()), data_.size());
diff --git a/extern/draco/draco/src/draco/core/decoder_buffer.h b/extern/draco/draco/src/draco/core/decoder_buffer.h
index 0559abbe415..be98e52d60e 100644
--- a/extern/draco/draco/src/draco/core/decoder_buffer.h
+++ b/extern/draco/draco/src/draco/core/decoder_buffer.h
@@ -54,12 +54,11 @@ class DecoderBuffer {
// Decodes up to 32 bits into out_val. Can be called only in between
// StartBitDecoding and EndBitDecoding. Otherwise returns false.
- bool DecodeLeastSignificantBits32(int nbits, uint32_t *out_value) {
+ bool DecodeLeastSignificantBits32(uint32_t nbits, uint32_t *out_value) {
if (!bit_decoder_active()) {
return false;
}
- bit_decoder_.GetBits(nbits, out_value);
- return true;
+ return bit_decoder_.GetBits(nbits, out_value);
}
// Decodes an arbitrary data type.
@@ -158,9 +157,10 @@ class DecoderBuffer {
inline void ConsumeBits(int k) { bit_offset_ += k; }
// Returns |nbits| bits in |x|.
- inline bool GetBits(int32_t nbits, uint32_t *x) {
- DRACO_DCHECK_GE(nbits, 0);
- DRACO_DCHECK_LE(nbits, 32);
+ inline bool GetBits(uint32_t nbits, uint32_t *x) {
+ if (nbits > 32) {
+ return false;
+ }
uint32_t value = 0;
for (int32_t bit = 0; bit < nbits; ++bit) {
value |= GetBit() << bit;
diff --git a/extern/draco/draco/src/draco/core/draco_index_type_vector.h b/extern/draco/draco/src/draco/core/draco_index_type_vector.h
index d47ab3b04eb..0fefc43b23d 100644
--- a/extern/draco/draco/src/draco/core/draco_index_type_vector.h
+++ b/extern/draco/draco/src/draco/core/draco_index_type_vector.h
@@ -28,7 +28,6 @@ namespace draco {
// draco_index_type.h .
// TODO(ostava): Make the interface more complete. It's currently missing
// features such as iterators.
-// TODO(vytyaz): Add more unit tests for this class.
template <class IndexTypeT, class ValueTypeT>
class IndexTypeVector {
public:
@@ -56,7 +55,7 @@ class IndexTypeVector {
void push_back(ValueTypeT &&val) { vector_.push_back(std::move(val)); }
template <typename... Args>
- void emplace_back(Args &&... args) {
+ void emplace_back(Args &&...args) {
vector_.emplace_back(std::forward<Args>(args)...);
}
diff --git a/extern/draco/draco/src/draco/core/draco_version.h b/extern/draco/draco/src/draco/core/draco_version.h
index ffd7948c64d..5f2676ad7e9 100644
--- a/extern/draco/draco/src/draco/core/draco_version.h
+++ b/extern/draco/draco/src/draco/core/draco_version.h
@@ -18,7 +18,7 @@
namespace draco {
// Draco version is comprised of <major>.<minor>.<revision>.
-static const char kDracoVersion[] = "1.3.6";
+static const char kDracoVersion[] = "1.5.2";
const char *Version() { return kDracoVersion; }
diff --git a/extern/draco/draco/src/draco/core/macros.h b/extern/draco/draco/src/draco/core/macros.h
index 89b706e53a5..64647d129d5 100644
--- a/extern/draco/draco/src/draco/core/macros.h
+++ b/extern/draco/draco/src/draco/core/macros.h
@@ -21,11 +21,13 @@
#ifdef ANDROID_LOGGING
#include <android/log.h>
#define LOG_TAG "draco"
-#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
-#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
+#define DRACO_LOGI(...) \
+ __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
+#define DRACO_LOGE(...) \
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#else
-#define LOGI printf
-#define LOGE printf
+#define DRACO_LOGI printf
+#define DRACO_LOGE printf
#endif
#include <iostream>
@@ -88,6 +90,10 @@ namespace draco {
#define DRACO_MACROS_IMPL_CONCAT_INNER_(x, y) x##y
#define DRACO_MACROS_IMPL_CONCAT_(x, y) DRACO_MACROS_IMPL_CONCAT_INNER_(x, y)
+#define DRACO_MACROS_IMPL_CONCAT_INNER_3_(x, y, z) x##y##z
+#define DRACO_MACROS_IMPL_CONCAT_3_(x, y, z) \
+ DRACO_MACROS_IMPL_CONCAT_INNER_3_(x, y, z)
+
// Expand the n-th argument of the macro. Used to select an argument based on
// the number of entries in a variadic macro argument. Example usage:
//
@@ -98,13 +104,20 @@ namespace draco {
// #define VARIADIC_MACRO(...)
// DRACO_SELECT_NTH_FROM_3(__VA_ARGS__, FUNC_3, FUNC_2, FUNC_1) __VA_ARGS__
//
-#define DRACO_SELECT_NTH_FROM_2(_1, _2, NAME) NAME
-#define DRACO_SELECT_NTH_FROM_3(_1, _2, _3, NAME) NAME
-#define DRACO_SELECT_NTH_FROM_4(_1, _2, _3, _4, NAME) NAME
+#define DRACO_SELECT_NTH_FROM_2(_1, _2, NAME, ...) NAME
+#define DRACO_SELECT_NTH_FROM_3(_1, _2, _3, NAME, ...) NAME
+#define DRACO_SELECT_NTH_FROM_4(_1, _2, _3, _4, NAME, ...) NAME
// Macro that converts the Draco bit-stream into one uint16_t number.
// Useful mostly when checking version numbers.
#define DRACO_BITSTREAM_VERSION(MAJOR, MINOR) \
((static_cast<uint16_t>(MAJOR) << 8) | MINOR)
+// Macro that converts the uint16_t Draco bit-stream number into the major
+// and minor components respectively.
+#define DRACO_BISTREAM_VERSION_MAJOR(VERSION) \
+ (static_cast<uint8_t>(VERSION >> 8))
+#define DRACO_BISTREAM_VERSION_MINOR(VERSION) \
+ (static_cast<uint8_t>(VERSION & 0xFF))
+
#endif // DRACO_CORE_MACROS_H_
diff --git a/extern/draco/draco/src/draco/core/options.h b/extern/draco/draco/src/draco/core/options.h
index 1bc4dc0fb7b..9dc22ce16c2 100644
--- a/extern/draco/draco/src/draco/core/options.h
+++ b/extern/draco/draco/src/draco/core/options.h
@@ -71,8 +71,6 @@ class Options {
private:
// All entries are internally stored as strings and converted to the desired
// return type based on the used Get* method.
- // TODO(ostava): Consider adding type safety mechanism that would prevent
- // unsafe operations such as a conversion from vector to int.
std::map<std::string, std::string> options_;
};
diff --git a/extern/draco/draco/src/draco/core/status.h b/extern/draco/draco/src/draco/core/status.h
index 449ad8566de..ee7f43ee59c 100644
--- a/extern/draco/draco/src/draco/core/status.h
+++ b/extern/draco/draco/src/draco/core/status.h
@@ -15,6 +15,7 @@
#ifndef DRACO_CORE_STATUS_H_
#define DRACO_CORE_STATUS_H_
+#include <ostream>
#include <string>
namespace draco {
@@ -61,6 +62,9 @@ inline std::ostream &operator<<(std::ostream &os, const Status &status) {
}
inline Status OkStatus() { return Status(Status::OK); }
+inline Status ErrorStatus(const std::string &msg) {
+ return Status(Status::DRACO_ERROR, msg);
+}
// Evaluates an expression that returns draco::Status. If the status is not OK,
// the macro returns the status object.
diff --git a/extern/draco/draco/src/draco/core/varint_decoding.h b/extern/draco/draco/src/draco/core/varint_decoding.h
index 4e86df732e0..cff47e930b4 100644
--- a/extern/draco/draco/src/draco/core/varint_decoding.h
+++ b/extern/draco/draco/src/draco/core/varint_decoding.h
@@ -58,6 +58,7 @@ bool DecodeVarintUnsigned(int depth, IntTypeT *out_val, DecoderBuffer *buffer) {
// Decodes a specified integer as varint. Note that the IntTypeT must be the
// same as the one used in the corresponding EncodeVarint() call.
+// out_val is undefined if this returns false.
template <typename IntTypeT>
bool DecodeVarint(IntTypeT *out_val, DecoderBuffer *buffer) {
if (std::is_unsigned<IntTypeT>::value) {
diff --git a/extern/draco/draco/src/draco/core/vector_d.h b/extern/draco/draco/src/draco/core/vector_d.h
index bed97304feb..a0ec2dedf2e 100644
--- a/extern/draco/draco/src/draco/core/vector_d.h
+++ b/extern/draco/draco/src/draco/core/vector_d.h
@@ -20,6 +20,7 @@
#include <algorithm>
#include <array>
#include <cmath>
+#include <limits>
#include "draco/core/macros.h"
@@ -33,7 +34,7 @@ class VectorD {
typedef ScalarT Scalar;
typedef VectorD<Scalar, dimension_t> Self;
- // TODO(hemmer): Deprecate.
+ // TODO(b/199760123): Deprecate.
typedef ScalarT CoefficientType;
VectorD() {
@@ -44,7 +45,7 @@ class VectorD {
// The following constructor does not compile in opt mode, which for now led
// to the constructors further down, which is not ideal.
- // TODO(hemmer): fix constructor below and remove others.
+ // TODO(b/199760123): Fix constructor below and remove others.
// template <typename... Args>
// explicit VectorD(Args... args) : v_({args...}) {}
@@ -110,7 +111,7 @@ class VectorD {
Scalar &operator[](int i) { return v_[i]; }
const Scalar &operator[](int i) const { return v_[i]; }
- // TODO(hemmer): remove.
+ // TODO(b/199760123): Remove.
// Similar to interface of Eigen library.
Scalar &operator()(int i) { return v_[i]; }
const Scalar &operator()(int i) const { return v_[i]; }
@@ -236,7 +237,12 @@ class VectorD {
Scalar AbsSum() const {
Scalar result(0);
for (int i = 0; i < dimension; ++i) {
- result += std::abs(v_[i]);
+ Scalar next_value = std::abs(v_[i]);
+ if (result > std::numeric_limits<Scalar>::max() - next_value) {
+ // Return the max if adding would have caused an overflow.
+ return std::numeric_limits<Scalar>::max();
+ }
+ result += next_value;
}
return result;
}
diff --git a/extern/draco/draco/src/draco/draco_features.h b/extern/draco/draco/src/draco/draco_features.h
index 27e3d7f136a..d0a630e5465 100644
--- a/extern/draco/draco/src/draco/draco_features.h
+++ b/extern/draco/draco/src/draco/draco_features.h
@@ -4,7 +4,5 @@
#define DRACO_MESH_COMPRESSION_SUPPORTED
#define DRACO_NORMAL_ENCODING_SUPPORTED
#define DRACO_STANDARD_EDGEBREAKER_SUPPORTED
-#define DRACO_ATTRIBUTE_INDICES_DEDUPLICATION_SUPPORTED
-#define DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED
#endif // DRACO_FEATURES_H_
diff --git a/extern/draco/draco/src/draco/mesh/corner_table.cc b/extern/draco/draco/src/draco/mesh/corner_table.cc
index 6066e58bd8b..3f92f651ab6 100644
--- a/extern/draco/draco/src/draco/mesh/corner_table.cc
+++ b/extern/draco/draco/src/draco/mesh/corner_table.cc
@@ -66,12 +66,13 @@ bool CornerTable::Reset(int num_faces, int num_vertices) {
if (num_faces < 0 || num_vertices < 0) {
return false;
}
- if (static_cast<unsigned int>(num_faces) >
+ const unsigned int num_faces_unsigned = num_faces;
+ if (num_faces_unsigned >
std::numeric_limits<CornerIndex::ValueType>::max() / 3) {
return false;
}
- corner_to_vertex_map_.assign(num_faces * 3, kInvalidVertexIndex);
- opposite_corners_.assign(num_faces * 3, kInvalidCornerIndex);
+ corner_to_vertex_map_.assign(num_faces_unsigned * 3, kInvalidVertexIndex);
+ opposite_corners_.assign(num_faces_unsigned * 3, kInvalidCornerIndex);
vertex_corners_.reserve(num_vertices);
valence_cache_.ClearValenceCache();
valence_cache_.ClearValenceCacheInaccurate();
diff --git a/extern/draco/draco/src/draco/mesh/mesh.h b/extern/draco/draco/src/draco/mesh/mesh.h
index f4506da81c9..b1577c03986 100644
--- a/extern/draco/draco/src/draco/mesh/mesh.h
+++ b/extern/draco/draco/src/draco/mesh/mesh.h
@@ -119,6 +119,10 @@ class Mesh : public PointCloud {
const std::vector<PointIndex> &unique_point_ids) override;
#endif
+ // Exposes |faces_|. Use |faces_| at your own risk. DO NOT store the
+ // reference: the |faces_| object is destroyed with the mesh.
+ IndexTypeVector<FaceIndex, Face> &faces() { return faces_; }
+
private:
// Mesh specific per-attribute data.
std::vector<AttributeData> attribute_data_;
diff --git a/extern/draco/draco/src/draco/mesh/mesh_attribute_corner_table.h b/extern/draco/draco/src/draco/mesh/mesh_attribute_corner_table.h
index 7dad25cf1d2..6f02453d2d4 100644
--- a/extern/draco/draco/src/draco/mesh/mesh_attribute_corner_table.h
+++ b/extern/draco/draco/src/draco/mesh/mesh_attribute_corner_table.h
@@ -130,6 +130,12 @@ class MeshAttributeCornerTable {
return false;
}
+ bool IsDegenerated(FaceIndex face) const {
+ // Introducing seams can't change the degeneracy of the individual faces,
+ // therefore we can delegate the check to the original |corner_table_|.
+ return corner_table_->IsDegenerated(face);
+ }
+
bool no_interior_seams() const { return no_interior_seams_; }
const CornerTable *corner_table() const { return corner_table_; }
diff --git a/extern/draco/draco/src/draco/mesh/mesh_cleanup.cc b/extern/draco/draco/src/draco/mesh/mesh_cleanup.cc
index 773c1e18fe6..bc44c831c4e 100644
--- a/extern/draco/draco/src/draco/mesh/mesh_cleanup.cc
+++ b/extern/draco/draco/src/draco/mesh/mesh_cleanup.cc
@@ -14,25 +14,42 @@
//
#include "draco/mesh/mesh_cleanup.h"
+#include <unordered_set>
+
+#include "draco/core/hash_utils.h"
+
namespace draco {
-bool MeshCleanup::operator()(Mesh *mesh, const MeshCleanupOptions &options) {
- if (!options.remove_degenerated_faces && !options.remove_unused_attributes) {
- return true; // Nothing to cleanup.
+Status MeshCleanup::Cleanup(Mesh *mesh, const MeshCleanupOptions &options) {
+ if (!options.remove_degenerated_faces && !options.remove_unused_attributes &&
+ !options.remove_duplicate_faces && !options.make_geometry_manifold) {
+ return OkStatus(); // Nothing to cleanup.
}
const PointAttribute *const pos_att =
mesh->GetNamedAttribute(GeometryAttribute::POSITION);
if (pos_att == nullptr) {
- return false;
+ return Status(Status::DRACO_ERROR, "Missing position attribute.");
}
- // Array that is going to store whether a corresponding point is used.
- std::vector<bool> is_point_used;
+
+ if (options.remove_degenerated_faces) {
+ RemoveDegeneratedFaces(mesh);
+ }
+
+ if (options.remove_duplicate_faces) {
+ RemoveDuplicateFaces(mesh);
+ }
+
if (options.remove_unused_attributes) {
- is_point_used.resize(mesh->num_points(), false);
+ RemoveUnusedAttributes(mesh);
}
+ return OkStatus();
+}
+
+void MeshCleanup::RemoveDegeneratedFaces(Mesh *mesh) {
+ const PointAttribute *const pos_att =
+ mesh->GetNamedAttribute(GeometryAttribute::POSITION);
FaceIndex::ValueType num_degenerated_faces = 0;
- PointIndex::ValueType num_new_points = 0;
// Array for storing position indices on a face.
std::array<AttributeValueIndex, 3> pos_indices;
for (FaceIndex f(0); f < mesh->num_faces(); ++f) {
@@ -40,149 +57,195 @@ bool MeshCleanup::operator()(Mesh *mesh, const MeshCleanupOptions &options) {
for (int p = 0; p < 3; ++p) {
pos_indices[p] = pos_att->mapped_index(face[p]);
}
- bool is_face_valid = true;
- if (options.remove_degenerated_faces) {
- if (pos_indices[0] == pos_indices[1] ||
- pos_indices[0] == pos_indices[2] ||
- pos_indices[1] == pos_indices[2]) {
- ++num_degenerated_faces;
- is_face_valid = false;
- } else if (num_degenerated_faces > 0) {
- // Copy the face to its new location.
- mesh->SetFace(f - num_degenerated_faces, face);
- }
- }
- if (options.remove_unused_attributes && is_face_valid) {
- for (int p = 0; p < 3; ++p) {
- if (!is_point_used[face[p].value()]) {
- is_point_used[face[p].value()] = true;
- ++num_new_points;
- }
- }
+ if (pos_indices[0] == pos_indices[1] || pos_indices[0] == pos_indices[2] ||
+ pos_indices[1] == pos_indices[2]) {
+ ++num_degenerated_faces;
+ } else if (num_degenerated_faces > 0) {
+ // Copy the face to its new location.
+ mesh->SetFace(f - num_degenerated_faces, face);
}
}
if (num_degenerated_faces > 0) {
mesh->SetNumFaces(mesh->num_faces() - num_degenerated_faces);
}
- if (options.remove_unused_attributes) {
- bool points_changed = false;
- const PointIndex::ValueType num_original_points = mesh->num_points();
- // Map from old points to the new ones.
- IndexTypeVector<PointIndex, PointIndex> point_map(num_original_points);
- if (num_new_points < static_cast<int>(mesh->num_points())) {
- // Some of the points were removed. We need to remap the old points to the
- // new ones.
- num_new_points = 0;
- for (PointIndex i(0); i < num_original_points; ++i) {
- if (is_point_used[i.value()]) {
- point_map[i] = num_new_points++;
- } else {
- point_map[i] = kInvalidPointIndex;
- }
+}
+
+void MeshCleanup::RemoveDuplicateFaces(Mesh *mesh) {
+ const PointAttribute *const pos_att =
+ mesh->GetNamedAttribute(GeometryAttribute::POSITION);
+
+ typedef std::array<AttributeValueIndex::ValueType, 3> PosTriplet;
+ PosTriplet pos_indices;
+ std::unordered_set<PosTriplet, HashArray<PosTriplet>> is_face_used;
+
+ uint32_t num_duplicate_faces = 0;
+ for (FaceIndex fi(0); fi < mesh->num_faces(); ++fi) {
+ const auto f = mesh->face(fi);
+ for (int c = 0; c < 3; ++c) {
+ pos_indices[c] = pos_att->mapped_index(f[c]).value();
+ }
+ // Shift the position indices until the smallest index is the first one.
+ while (pos_indices[0] > pos_indices[1] || pos_indices[0] > pos_indices[2]) {
+ // Shift to the left.
+ std::swap(pos_indices[0], pos_indices[1]);
+ std::swap(pos_indices[1], pos_indices[2]);
+ }
+ // Check if have encountered the same position triplet on a different face.
+ if (is_face_used.find(pos_indices) != is_face_used.end()) {
+ // Duplicate face. Ignore it.
+ num_duplicate_faces++;
+ } else {
+ // Insert new face to the set.
+ is_face_used.insert(pos_indices);
+ if (num_duplicate_faces > 0) {
+ // Copy the face to its new location.
+ mesh->SetFace(fi - num_duplicate_faces, f);
}
- // Go over faces and update their points.
- for (FaceIndex f(0); f < mesh->num_faces(); ++f) {
- Mesh::Face face = mesh->face(f);
- for (int p = 0; p < 3; ++p) {
- face[p] = point_map[face[p]];
- }
- mesh->SetFace(f, face);
+ }
+ }
+ if (num_duplicate_faces > 0) {
+ mesh->SetNumFaces(mesh->num_faces() - num_duplicate_faces);
+ }
+}
+
+void MeshCleanup::RemoveUnusedAttributes(Mesh *mesh) {
+ // Array that is going to store whether a corresponding point is used.
+ std::vector<bool> is_point_used;
+ PointIndex::ValueType num_new_points = 0;
+ is_point_used.resize(mesh->num_points(), false);
+ for (FaceIndex f(0); f < mesh->num_faces(); ++f) {
+ const Mesh::Face &face = mesh->face(f);
+ for (int p = 0; p < 3; ++p) {
+ if (!is_point_used[face[p].value()]) {
+ is_point_used[face[p].value()] = true;
+ ++num_new_points;
}
- // Set the new number of points.
- mesh->set_num_points(num_new_points);
- points_changed = true;
- } else {
- // No points were removed. Initialize identity map between the old and new
- // points.
- for (PointIndex i(0); i < num_original_points; ++i) {
- point_map[i] = i;
+ }
+ }
+
+ bool points_changed = false;
+ const PointIndex::ValueType num_original_points = mesh->num_points();
+ // Map from old points to the new ones.
+ IndexTypeVector<PointIndex, PointIndex> point_map(num_original_points);
+ if (num_new_points < static_cast<int>(mesh->num_points())) {
+ // Some of the points were removed. We need to remap the old points to the
+ // new ones.
+ num_new_points = 0;
+ for (PointIndex i(0); i < num_original_points; ++i) {
+ if (is_point_used[i.value()]) {
+ point_map[i] = num_new_points++;
+ } else {
+ point_map[i] = kInvalidPointIndex;
+ }
+ }
+ // Go over faces and update their points.
+ for (FaceIndex f(0); f < mesh->num_faces(); ++f) {
+ Mesh::Face face = mesh->face(f);
+ for (int p = 0; p < 3; ++p) {
+ face[p] = point_map[face[p]];
}
+ mesh->SetFace(f, face);
}
+ // Set the new number of points.
+ mesh->set_num_points(num_new_points);
+ points_changed = true;
+ } else {
+ // No points were removed. Initialize identity map between the old and new
+ // points.
+ for (PointIndex i(0); i < num_original_points; ++i) {
+ point_map[i] = i;
+ }
+ }
- // Update index mapping for attributes.
- IndexTypeVector<AttributeValueIndex, uint8_t> is_att_index_used;
- IndexTypeVector<AttributeValueIndex, AttributeValueIndex> att_index_map;
- for (int a = 0; a < mesh->num_attributes(); ++a) {
- PointAttribute *const att = mesh->attribute(a);
- // First detect which attribute entries are used (included in a point).
- is_att_index_used.assign(att->size(), 0);
- att_index_map.clear();
- AttributeValueIndex::ValueType num_used_entries = 0;
- for (PointIndex i(0); i < num_original_points; ++i) {
- if (point_map[i] != kInvalidPointIndex) {
- const AttributeValueIndex entry_id = att->mapped_index(i);
- if (!is_att_index_used[entry_id]) {
- is_att_index_used[entry_id] = 1;
- ++num_used_entries;
- }
+ // Update index mapping for attributes.
+ IndexTypeVector<AttributeValueIndex, uint8_t> is_att_index_used;
+ IndexTypeVector<AttributeValueIndex, AttributeValueIndex> att_index_map;
+ for (int a = 0; a < mesh->num_attributes(); ++a) {
+ PointAttribute *const att = mesh->attribute(a);
+ // First detect which attribute entries are used (included in a point).
+ is_att_index_used.assign(att->size(), 0);
+ att_index_map.clear();
+ AttributeValueIndex::ValueType num_used_entries = 0;
+ for (PointIndex i(0); i < num_original_points; ++i) {
+ if (point_map[i] != kInvalidPointIndex) {
+ const AttributeValueIndex entry_id = att->mapped_index(i);
+ if (!is_att_index_used[entry_id]) {
+ is_att_index_used[entry_id] = 1;
+ ++num_used_entries;
}
}
- bool att_indices_changed = false;
- // If there are some unused attribute entries, remap the attribute values
- // in the attribute buffer.
- if (num_used_entries < static_cast<int>(att->size())) {
- att_index_map.resize(att->size());
- num_used_entries = 0;
- for (AttributeValueIndex i(0); i < static_cast<uint32_t>(att->size());
- ++i) {
- if (is_att_index_used[i]) {
- att_index_map[i] = num_used_entries;
- if (i > num_used_entries) {
- const uint8_t *const src_add = att->GetAddress(i);
- att->buffer()->Write(
- att->GetBytePos(AttributeValueIndex(num_used_entries)),
- src_add, att->byte_stride());
- }
- ++num_used_entries;
+ }
+ bool att_indices_changed = false;
+ // If there are some unused attribute entries, remap the attribute values
+ // in the attribute buffer.
+ if (num_used_entries < static_cast<int>(att->size())) {
+ att_index_map.resize(att->size());
+ num_used_entries = 0;
+ for (AttributeValueIndex i(0); i < static_cast<uint32_t>(att->size());
+ ++i) {
+ if (is_att_index_used[i]) {
+ att_index_map[i] = num_used_entries;
+ if (i > num_used_entries) {
+ const uint8_t *const src_add = att->GetAddress(i);
+ att->buffer()->Write(
+ att->GetBytePos(AttributeValueIndex(num_used_entries)), src_add,
+ att->byte_stride());
}
+ ++num_used_entries;
}
- // Update the number of unique entries in the vertex buffer.
- att->Resize(num_used_entries);
- att_indices_changed = true;
}
- // If either the points or attribute indices have changed, we need to
- // update the attribute index mapping.
- if (points_changed || att_indices_changed) {
- if (att->is_mapping_identity()) {
- // The mapping was identity. It'll remain identity only if the
- // number of point and attribute indices is still the same.
- if (num_used_entries != static_cast<int>(mesh->num_points())) {
- // We need to create an explicit mapping.
- // First we need to initialize the explicit map to the original
- // number of points to recreate the original identity map.
- att->SetExplicitMapping(num_original_points);
- // Set the entries of the explicit map to identity.
- for (PointIndex::ValueType i = 0; i < num_original_points; ++i) {
- att->SetPointMapEntry(PointIndex(i), AttributeValueIndex(i));
- }
+ // Update the number of unique entries in the vertex buffer.
+ att->Resize(num_used_entries);
+ att_indices_changed = true;
+ }
+ // If either the points or attribute indices have changed, we need to
+ // update the attribute index mapping.
+ if (points_changed || att_indices_changed) {
+ if (att->is_mapping_identity()) {
+ // The mapping was identity. It'll remain identity only if the
+ // number of point and attribute indices is still the same.
+ if (num_used_entries != static_cast<int>(mesh->num_points())) {
+ // We need to create an explicit mapping.
+ // First we need to initialize the explicit map to the original
+ // number of points to recreate the original identity map.
+ att->SetExplicitMapping(num_original_points);
+ // Set the entries of the explicit map to identity.
+ for (PointIndex::ValueType i = 0; i < num_original_points; ++i) {
+ att->SetPointMapEntry(PointIndex(i), AttributeValueIndex(i));
}
}
- if (!att->is_mapping_identity()) {
- // Explicit mapping between points and local attribute indices.
- for (PointIndex i(0); i < num_original_points; ++i) {
- // The new point id that maps to the currently processed attribute
- // entry.
- const PointIndex new_point_id = point_map[i];
- if (new_point_id == kInvalidPointIndex) {
- continue;
- }
- // Index of the currently processed attribute entry in the original
- // mesh.
- const AttributeValueIndex original_entry_index =
- att->mapped_index(i);
- // New index of the same entry after unused entries were removed.
- const AttributeValueIndex new_entry_index =
- att_index_map[original_entry_index];
- att->SetPointMapEntry(new_point_id, new_entry_index);
+ }
+ if (!att->is_mapping_identity()) {
+ // Explicit mapping between points and local attribute indices.
+ for (PointIndex i(0); i < num_original_points; ++i) {
+ // The new point id that maps to the currently processed attribute
+ // entry.
+ const PointIndex new_point_id = point_map[i];
+ if (new_point_id == kInvalidPointIndex) {
+ continue;
}
- // If the number of points changed, we need to set a new explicit map
- // size.
- att->SetExplicitMapping(mesh->num_points());
+ // Index of the currently processed attribute entry in the original
+ // mesh.
+ const AttributeValueIndex original_entry_index = att->mapped_index(i);
+ // New index of the same entry after unused entries were removed.
+ const AttributeValueIndex new_entry_index =
+ att_indices_changed ? att_index_map[original_entry_index]
+ : original_entry_index;
+
+ // Update the mapping. Note that the new point index is always smaller
+ // than the processed index |i|, making this operation safe.
+ att->SetPointMapEntry(new_point_id, new_entry_index);
}
+ // If the number of points changed, we need to set a new explicit map
+ // size.
+ att->SetExplicitMapping(mesh->num_points());
}
}
}
- return true;
+}
+
+Status MeshCleanup::MakeGeometryManifold(Mesh *mesh) {
+ return Status(Status::DRACO_ERROR, "Unsupported function.");
}
} // namespace draco
diff --git a/extern/draco/draco/src/draco/mesh/mesh_cleanup.h b/extern/draco/draco/src/draco/mesh/mesh_cleanup.h
index b56129dce58..0acdc2ae5b8 100644
--- a/extern/draco/draco/src/draco/mesh/mesh_cleanup.h
+++ b/extern/draco/draco/src/draco/mesh/mesh_cleanup.h
@@ -15,27 +15,44 @@
#ifndef DRACO_MESH_MESH_CLEANUP_H_
#define DRACO_MESH_MESH_CLEANUP_H_
+#include "draco/core/status.h"
#include "draco/mesh/mesh.h"
namespace draco {
// Options used by the MeshCleanup class.
struct MeshCleanupOptions {
- MeshCleanupOptions()
- : remove_degenerated_faces(true), remove_unused_attributes(true) {}
// If true, the cleanup tool removes any face where two or more vertices
// share the same position index.
- bool remove_degenerated_faces;
+ bool remove_degenerated_faces = true;
+
+ // If true, the cleanup tool removes all duplicate faces. A pair of faces is
+ // duplicate if both faces share the same position indices on all vertices
+ // (that is, position values have to be duduplicated). Note that all
+ // non-position properties are currently ignored.
+ bool remove_duplicate_faces = true;
+
// If true, the cleanup tool removes any unused attribute value or unused
// point id. For example, it can be used to remove isolated vertices.
- bool remove_unused_attributes;
+ bool remove_unused_attributes = true;
+
+ // If true, the cleanup tool splits vertices along non-manifold edges and
+ // vertices. This ensures that the connectivity defined by position indices
+ // is manifold.
+ bool make_geometry_manifold = false;
};
// Tool that can be used for removing bad or unused data from draco::Meshes.
class MeshCleanup {
public:
// Performs in-place cleanup of the input mesh according to the input options.
- bool operator()(Mesh *mesh, const MeshCleanupOptions &options);
+ static Status Cleanup(Mesh *mesh, const MeshCleanupOptions &options);
+
+ private:
+ static void RemoveDegeneratedFaces(Mesh *mesh);
+ static void RemoveDuplicateFaces(Mesh *mesh);
+ static void RemoveUnusedAttributes(Mesh *mesh);
+ static Status MakeGeometryManifold(Mesh *mesh);
};
} // namespace draco
diff --git a/extern/draco/draco/src/draco/mesh/mesh_misc_functions.h b/extern/draco/draco/src/draco/mesh/mesh_misc_functions.h
index b450bc80cd8..0a3bcf49782 100644
--- a/extern/draco/draco/src/draco/mesh/mesh_misc_functions.h
+++ b/extern/draco/draco/src/draco/mesh/mesh_misc_functions.h
@@ -67,7 +67,6 @@ inline bool IsCornerOppositeToAttributeSeam(CornerIndex ci,
// Interpolates an attribute value on a face using given barycentric
// coordinates. InterpolatedVectorT should be a VectorD that corresponds to the
// values stored in the attribute.
-// TODO(ostava): Find a better place for this.
template <typename InterpolatedVectorT>
InterpolatedVectorT ComputeInterpolatedAttributeValueOnMeshFace(
const Mesh &mesh, const PointAttribute &attribute, FaceIndex fi,
diff --git a/extern/draco/draco/src/draco/mesh/mesh_stripifier.h b/extern/draco/draco/src/draco/mesh/mesh_stripifier.h
index 0c298f48e86..8e8d8d9f21f 100644
--- a/extern/draco/draco/src/draco/mesh/mesh_stripifier.h
+++ b/extern/draco/draco/src/draco/mesh/mesh_stripifier.h
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
-#ifndef DRACO_SRC_DRACO_MESH_MESH_STRIPIFIER_H_
-#define DRACO_SRC_DRACO_MESH_MESH_STRIPIFIER_H_
+#ifndef DRACO_MESH_MESH_STRIPIFIER_H_
+#define DRACO_MESH_MESH_STRIPIFIER_H_
#include "draco/mesh/mesh_misc_functions.h"
@@ -71,8 +71,6 @@ class MeshStripifier {
mesh_ = &mesh;
num_strips_ = 0;
num_encoded_faces_ = 0;
- // TODO(ostava): We may be able to avoid computing the corner table if we
- // already have it stored somewhere.
corner_table_ = CreateCornerTableFromPositionAttribute(mesh_);
if (corner_table_ == nullptr) {
return false;
@@ -257,4 +255,4 @@ bool MeshStripifier::GenerateTriangleStripsWithDegenerateTriangles(
} // namespace draco
-#endif // DRACO_SRC_DRACO_MESH_MESH_STRIPIFIER_H_
+#endif // DRACO_MESH_MESH_STRIPIFIER_H_
diff --git a/extern/draco/draco/src/draco/mesh/triangle_soup_mesh_builder.cc b/extern/draco/draco/src/draco/mesh/triangle_soup_mesh_builder.cc
index 60b0c50b8d5..cb767f871a9 100644
--- a/extern/draco/draco/src/draco/mesh/triangle_soup_mesh_builder.cc
+++ b/extern/draco/draco/src/draco/mesh/triangle_soup_mesh_builder.cc
@@ -41,8 +41,6 @@ void TriangleSoupMeshBuilder::SetAttributeValuesForFace(
att->SetAttributeValue(AttributeValueIndex(start_index), corner_value_0);
att->SetAttributeValue(AttributeValueIndex(start_index + 1), corner_value_1);
att->SetAttributeValue(AttributeValueIndex(start_index + 2), corner_value_2);
- // TODO(ostava): The below code should be called only for one attribute.
- // It will work OK even for multiple attributes, but it's redundant.
mesh_->SetFace(face_id,
{{PointIndex(start_index), PointIndex(start_index + 1),
PointIndex(start_index + 2)}});
diff --git a/extern/draco/draco/src/draco/metadata/geometry_metadata.cc b/extern/draco/draco/src/draco/metadata/geometry_metadata.cc
index b83898140ae..b6a882c0b1b 100644
--- a/extern/draco/draco/src/draco/metadata/geometry_metadata.cc
+++ b/extern/draco/draco/src/draco/metadata/geometry_metadata.cc
@@ -18,6 +18,19 @@
namespace draco {
+AttributeMetadata::AttributeMetadata(const AttributeMetadata &metadata)
+ : Metadata(metadata) {
+ att_unique_id_ = metadata.att_unique_id_;
+}
+
+GeometryMetadata::GeometryMetadata(const GeometryMetadata &metadata)
+ : Metadata(metadata) {
+ for (size_t i = 0; i < metadata.att_metadatas_.size(); ++i) {
+ att_metadatas_.push_back(std::unique_ptr<AttributeMetadata>(
+ new AttributeMetadata(*metadata.att_metadatas_[i])));
+ }
+}
+
const AttributeMetadata *GeometryMetadata::GetAttributeMetadataByStringEntry(
const std::string &entry_name, const std::string &entry_value) const {
for (auto &&att_metadata : att_metadatas_) {
@@ -35,7 +48,7 @@ const AttributeMetadata *GeometryMetadata::GetAttributeMetadataByStringEntry(
bool GeometryMetadata::AddAttributeMetadata(
std::unique_ptr<AttributeMetadata> att_metadata) {
- if (!att_metadata.get()) {
+ if (!att_metadata) {
return false;
}
att_metadatas_.push_back(std::move(att_metadata));
diff --git a/extern/draco/draco/src/draco/metadata/geometry_metadata.h b/extern/draco/draco/src/draco/metadata/geometry_metadata.h
index ec7ecb9ee68..531bdef2540 100644
--- a/extern/draco/draco/src/draco/metadata/geometry_metadata.h
+++ b/extern/draco/draco/src/draco/metadata/geometry_metadata.h
@@ -25,6 +25,7 @@ namespace draco {
class AttributeMetadata : public Metadata {
public:
AttributeMetadata() : att_unique_id_(0) {}
+ AttributeMetadata(const AttributeMetadata &metadata);
explicit AttributeMetadata(const Metadata &metadata)
: Metadata(metadata), att_unique_id_(0) {}
@@ -57,6 +58,7 @@ struct AttributeMetadataHasher {
class GeometryMetadata : public Metadata {
public:
GeometryMetadata() {}
+ GeometryMetadata(const GeometryMetadata &metadata);
explicit GeometryMetadata(const Metadata &metadata) : Metadata(metadata) {}
const AttributeMetadata *GetAttributeMetadataByStringEntry(
diff --git a/extern/draco/draco/src/draco/metadata/metadata.cc b/extern/draco/draco/src/draco/metadata/metadata.cc
index 9141907ed71..51b4e93a328 100644
--- a/extern/draco/draco/src/draco/metadata/metadata.cc
+++ b/extern/draco/draco/src/draco/metadata/metadata.cc
@@ -122,6 +122,14 @@ const Metadata *Metadata::GetSubMetadata(const std::string &name) const {
return sub_ptr->second.get();
}
+Metadata *Metadata::sub_metadata(const std::string &name) {
+ auto sub_ptr = sub_metadatas_.find(name);
+ if (sub_ptr == sub_metadatas_.end()) {
+ return nullptr;
+ }
+ return sub_ptr->second.get();
+}
+
void Metadata::RemoveEntry(const std::string &name) {
// Actually just remove "name", no need to check if it exists.
auto entry_ptr = entries_.find(name);
diff --git a/extern/draco/draco/src/draco/metadata/metadata.h b/extern/draco/draco/src/draco/metadata/metadata.h
index 56d05e46a3e..12c1ba97439 100644
--- a/extern/draco/draco/src/draco/metadata/metadata.h
+++ b/extern/draco/draco/src/draco/metadata/metadata.h
@@ -147,6 +147,7 @@ class Metadata {
bool AddSubMetadata(const std::string &name,
std::unique_ptr<Metadata> sub_metadata);
const Metadata *GetSubMetadata(const std::string &name) const;
+ Metadata *sub_metadata(const std::string &name);
void RemoveEntry(const std::string &name);
diff --git a/extern/draco/draco/src/draco/metadata/metadata_decoder.cc b/extern/draco/draco/src/draco/metadata/metadata_decoder.cc
index e664e4fa524..a8e66f854cf 100644
--- a/extern/draco/draco/src/draco/metadata/metadata_decoder.cc
+++ b/extern/draco/draco/src/draco/metadata/metadata_decoder.cc
@@ -78,8 +78,10 @@ bool MetadataDecoder::DecodeMetadata(Metadata *metadata) {
std::unique_ptr<Metadata> sub_metadata =
std::unique_ptr<Metadata>(new Metadata());
metadata = sub_metadata.get();
- mp.parent_metadata->AddSubMetadata(sub_metadata_name,
- std::move(sub_metadata));
+ if (!mp.parent_metadata->AddSubMetadata(sub_metadata_name,
+ std::move(sub_metadata))) {
+ return false;
+ }
}
if (metadata == nullptr) {
return false;
@@ -98,6 +100,10 @@ bool MetadataDecoder::DecodeMetadata(Metadata *metadata) {
if (!DecodeVarint(&num_sub_metadata, buffer_)) {
return false;
}
+ if (num_sub_metadata > buffer_->remaining_size()) {
+ // The decoded number of metadata items is unreasonably high.
+ return false;
+ }
for (uint32_t i = 0; i < num_sub_metadata; ++i) {
metadata_stack.push_back({metadata, nullptr});
}
diff --git a/extern/draco/draco/src/draco/point_cloud/point_cloud.cc b/extern/draco/draco/src/draco/point_cloud/point_cloud.cc
index 8eb638f80d4..55ad6670da5 100644
--- a/extern/draco/draco/src/draco/point_cloud/point_cloud.cc
+++ b/extern/draco/draco/src/draco/point_cloud/point_cloud.cc
@@ -241,7 +241,7 @@ void PointCloud::ApplyPointIdDeduplication(
bool PointCloud::DeduplicateAttributeValues() {
// Go over all attributes and create mapping between duplicate entries.
if (num_points() == 0) {
- return false; // Unexpected attribute size.
+ return true; // Nothing to deduplicate.
}
// Deduplicate all attributes.
for (int32_t att_id = 0; att_id < num_attributes(); ++att_id) {
@@ -253,17 +253,11 @@ bool PointCloud::DeduplicateAttributeValues() {
}
#endif
-// TODO(xiaoxumeng): Consider to cash the BBox.
+// TODO(b/199760503): Consider to cache the BBox.
BoundingBox PointCloud::ComputeBoundingBox() const {
- BoundingBox bounding_box =
- BoundingBox(Vector3f(std::numeric_limits<float>::max(),
- std::numeric_limits<float>::max(),
- std::numeric_limits<float>::max()),
- Vector3f(-std::numeric_limits<float>::max(),
- -std::numeric_limits<float>::max(),
- -std::numeric_limits<float>::max()));
+ BoundingBox bounding_box;
auto pc_att = GetNamedAttribute(GeometryAttribute::POSITION);
- // TODO(xiaoxumeng): Make the BoundingBox a template type, it may not be easy
+ // TODO(b/199760503): Make the BoundingBox a template type, it may not be easy
// because PointCloud is not a template.
// Or simply add some preconditioning here to make sure the position attribute
// is valid, because the current code works only if the position attribute is
@@ -274,7 +268,7 @@ BoundingBox PointCloud::ComputeBoundingBox() const {
for (AttributeValueIndex i(0); i < static_cast<uint32_t>(pc_att->size());
++i) {
pc_att->GetValue(i, &p[0]);
- bounding_box.update_bounding_box(p);
+ bounding_box.Update(p);
}
return bounding_box;
}
diff --git a/extern/draco/patches/blender.patch b/extern/draco/patches/blender.patch
new file mode 100644
index 00000000000..de39260367b
--- /dev/null
+++ b/extern/draco/patches/blender.patch
@@ -0,0 +1,30 @@
+diff --git a/draco/src/draco/attributes/geometry_attribute.h b/draco/src/draco/attributes/geometry_attribute.h
+index fd478a4..c1c0148 100644
+--- a/draco/src/draco/attributes/geometry_attribute.h
++++ b/draco/src/draco/attributes/geometry_attribute.h
+@@ -285,11 +285,25 @@ class GeometryAttribute {
+ // Make sure the in_value fits within the range of values that OutT
+ // is able to represent. Perform the check only for integral types.
+ if (std::is_integral<T>::value && std::is_integral<OutT>::value) {
++#ifdef _MSC_VER
++# pragma warning(push)
++# pragma warning(disable:4804)
++#endif
++#if defined(__GNUC__) && !defined(__clang__)
++# pragma GCC diagnostic push
++# pragma GCC diagnostic ignored "-Wbool-compare"
++#endif
+ static constexpr OutT kOutMin =
+ std::is_signed<T>::value ? std::numeric_limits<OutT>::lowest() : 0;
+ if (in_value < kOutMin || in_value > std::numeric_limits<OutT>::max()) {
+ return false;
+ }
++#ifdef __GNUC__
++# pragma GCC diagnostic pop
++#endif
++#ifdef _MSC_VER
++# pragma warning(pop)
++#endif
+ }
+
+ out_value[i] = static_cast<OutT>(in_value);
diff --git a/extern/draco/src/common.cpp b/extern/draco/src/common.cpp
index 6f98d8db7ef..3a11c126ece 100644
--- a/extern/draco/src/common.cpp
+++ b/extern/draco/src/common.cpp
@@ -54,20 +54,20 @@ size_t getComponentByteLength(size_t componentType)
{
switch (componentType)
{
- case ComponentType::Byte:
- case ComponentType::UnsignedByte:
- return 1;
-
- case ComponentType::Short:
- case ComponentType::UnsignedShort:
- return 2;
-
- case ComponentType::UnsignedInt:
- case ComponentType::Float:
- return 4;
-
- default:
- return 0;
+ case ComponentType::Byte:
+ case ComponentType::UnsignedByte:
+ return 1;
+
+ case ComponentType::Short:
+ case ComponentType::UnsignedShort:
+ return 2;
+
+ case ComponentType::UnsignedInt:
+ case ComponentType::Float:
+ return 4;
+
+ default:
+ return 0;
}
}
diff --git a/extern/draco/src/common.h b/extern/draco/src/common.h
index beaf7d91adb..eef50596350 100644
--- a/extern/draco/src/common.h
+++ b/extern/draco/src/common.h
@@ -33,7 +33,7 @@
#define API(returnType) extern "C" returnType
#endif
-enum ComponentType: size_t
+enum ComponentType : size_t
{
Byte = 5120,
UnsignedByte = 5121,
diff --git a/extern/draco/src/decoder.cpp b/extern/draco/src/decoder.cpp
index 3f3e03bd9f2..e5ec2b65e6c 100644
--- a/extern/draco/src/decoder.cpp
+++ b/extern/draco/src/decoder.cpp
@@ -17,7 +17,6 @@
* @date 2020-11-18
*/
-
#include "decoder.h"
#include <memory>
@@ -30,7 +29,8 @@
#define LOG_PREFIX "DracoDecoder | "
-struct Decoder {
+struct Decoder
+{
std::unique_ptr<draco::Mesh> mesh;
std::vector<uint8_t> indexBuffer;
std::map<uint32_t, std::vector<uint8_t>> buffers;
@@ -54,20 +54,20 @@ bool decoderDecode(Decoder *decoder, void *data, size_t byteLength)
draco::Decoder dracoDecoder;
draco::DecoderBuffer dracoDecoderBuffer;
dracoDecoderBuffer.Init(reinterpret_cast<char *>(data), byteLength);
-
+
auto decoderStatus = dracoDecoder.DecodeMeshFromBuffer(&dracoDecoderBuffer);
if (!decoderStatus.ok())
{
printf(LOG_PREFIX "Error during Draco decoding: %s\n", decoderStatus.status().error_msg());
return false;
}
-
+
decoder->mesh = std::move(decoderStatus).value();
decoder->vertexCount = decoder->mesh->num_points();
decoder->indexCount = decoder->mesh->num_faces() * 3;
-
+
printf(LOG_PREFIX "Decoded %" PRIu32 " vertices, %" PRIu32 " indices\n", decoder->vertexCount, decoder->indexCount);
-
+
return true;
}
@@ -83,32 +83,32 @@ uint32_t decoderGetIndexCount(Decoder *decoder)
bool decoderAttributeIsNormalized(Decoder *decoder, uint32_t id)
{
- const draco::PointAttribute* attribute = decoder->mesh->GetAttributeByUniqueId(id);
+ const draco::PointAttribute *attribute = decoder->mesh->GetAttributeByUniqueId(id);
return attribute != nullptr && attribute->normalized();
}
bool decoderReadAttribute(Decoder *decoder, uint32_t id, size_t componentType, char *dataType)
{
- const draco::PointAttribute* attribute = decoder->mesh->GetAttributeByUniqueId(id);
-
+ const draco::PointAttribute *attribute = decoder->mesh->GetAttributeByUniqueId(id);
+
if (attribute == nullptr)
{
printf(LOG_PREFIX "Attribute with id=%" PRIu32 " does not exist in Draco data\n", id);
return false;
}
-
+
size_t stride = getAttributeStride(componentType, dataType);
-
+
std::vector<uint8_t> decodedData;
decodedData.resize(stride * decoder->vertexCount);
-
+
for (uint32_t i = 0; i < decoder->vertexCount; ++i)
{
auto index = attribute->mapped_index(draco::PointIndex(i));
uint8_t *value = decodedData.data() + i * stride;
-
+
bool converted = false;
-
+
switch (componentType)
{
case ComponentType::Byte:
@@ -139,7 +139,7 @@ bool decoderReadAttribute(Decoder *decoder, uint32_t id, size_t componentType, c
return false;
}
}
-
+
decoder->buffers[id] = decodedData;
return true;
}
@@ -166,13 +166,13 @@ void decoderCopyAttribute(Decoder *decoder, size_t id, void *output)
}
}
-template<class T>
+template <class T>
void decodeIndices(Decoder *decoder)
{
std::vector<uint8_t> decodedIndices;
decodedIndices.resize(decoder->indexCount * sizeof(T));
T *typedView = reinterpret_cast<T *>(decodedIndices.data());
-
+
for (uint32_t faceIndex = 0; faceIndex < decoder->mesh->num_faces(); ++faceIndex)
{
const draco::Mesh::Face &face = decoder->mesh->face(draco::FaceIndex(faceIndex));
@@ -180,7 +180,7 @@ void decodeIndices(Decoder *decoder)
typedView[faceIndex * 3 + 1] = face[1].value();
typedView[faceIndex * 3 + 2] = face[2].value();
}
-
+
decoder->indexBuffer = decodedIndices;
}
@@ -188,26 +188,26 @@ bool decoderReadIndices(Decoder *decoder, size_t indexComponentType)
{
switch (indexComponentType)
{
- case ComponentType::Byte:
- decodeIndices<int8_t>(decoder);
- break;
- case ComponentType::UnsignedByte:
- decodeIndices<uint8_t>(decoder);
- break;
- case ComponentType::Short:
- decodeIndices<int16_t>(decoder);
- break;
- case ComponentType::UnsignedShort:
- decodeIndices<uint16_t>(decoder);
- break;
- case ComponentType::UnsignedInt:
- decodeIndices<uint32_t>(decoder);
- break;
- default:
- printf(LOG_PREFIX "Index component type %zu not supported\n", indexComponentType);
- return false;
+ case ComponentType::Byte:
+ decodeIndices<int8_t>(decoder);
+ break;
+ case ComponentType::UnsignedByte:
+ decodeIndices<uint8_t>(decoder);
+ break;
+ case ComponentType::Short:
+ decodeIndices<int16_t>(decoder);
+ break;
+ case ComponentType::UnsignedShort:
+ decodeIndices<uint16_t>(decoder);
+ break;
+ case ComponentType::UnsignedInt:
+ decodeIndices<uint32_t>(decoder);
+ break;
+ default:
+ printf(LOG_PREFIX "Index component type %zu not supported\n", indexComponentType);
+ return false;
}
-
+
return true;
}
diff --git a/extern/draco/src/decoder.h b/extern/draco/src/decoder.h
index 914eb776e8f..c154b426c59 100644
--- a/extern/draco/src/decoder.h
+++ b/extern/draco/src/decoder.h
@@ -28,26 +28,38 @@
struct Decoder;
-API(Decoder *) decoderCreate();
+API(Decoder *)
+decoderCreate();
-API(void) decoderRelease(Decoder *decoder);
+API(void)
+decoderRelease(Decoder *decoder);
-API(bool) decoderDecode(Decoder *decoder, void *data, size_t byteLength);
+API(bool)
+decoderDecode(Decoder *decoder, void *data, size_t byteLength);
-API(uint32_t) decoderGetVertexCount(Decoder *decoder);
+API(uint32_t)
+decoderGetVertexCount(Decoder *decoder);
-API(uint32_t) decoderGetIndexCount(Decoder *decoder);
+API(uint32_t)
+decoderGetIndexCount(Decoder *decoder);
-API(bool) decoderAttributeIsNormalized(Decoder *decoder, uint32_t id);
+API(bool)
+decoderAttributeIsNormalized(Decoder *decoder, uint32_t id);
-API(bool) decoderReadAttribute(Decoder *decoder, uint32_t id, size_t componentType, char *dataType);
+API(bool)
+decoderReadAttribute(Decoder *decoder, uint32_t id, size_t componentType, char *dataType);
-API(size_t) decoderGetAttributeByteLength(Decoder *decoder, size_t id);
+API(size_t)
+decoderGetAttributeByteLength(Decoder *decoder, size_t id);
-API(void) decoderCopyAttribute(Decoder *decoder, size_t id, void *output);
+API(void)
+decoderCopyAttribute(Decoder *decoder, size_t id, void *output);
-API(bool) decoderReadIndices(Decoder *decoder, size_t indexComponentType);
+API(bool)
+decoderReadIndices(Decoder *decoder, size_t indexComponentType);
-API(size_t) decoderGetIndicesByteLength(Decoder *decoder);
+API(size_t)
+decoderGetIndicesByteLength(Decoder *decoder);
-API(void) decoderCopyIndices(Decoder *decoder, void *output);
+API(void)
+decoderCopyIndices(Decoder *decoder, void *output);
diff --git a/extern/draco/src/encoder.cpp b/extern/draco/src/encoder.cpp
index ff7570ecfcd..34282ced8c6 100644
--- a/extern/draco/src/encoder.cpp
+++ b/extern/draco/src/encoder.cpp
@@ -59,7 +59,8 @@ void encoderRelease(Encoder *encoder)
delete encoder;
}
-void encoderSetCompressionLevel(Encoder *encoder, uint32_t compressionLevel) {
+void encoderSetCompressionLevel(Encoder *encoder, uint32_t compressionLevel)
+{
encoder->compressionLevel = compressionLevel;
}
@@ -75,7 +76,7 @@ void encoderSetQuantizationBits(Encoder *encoder, uint32_t position, uint32_t no
bool encoderEncode(Encoder *encoder, uint8_t preserveTriangleOrder)
{
printf(LOG_PREFIX "Preserve triangle order: %s\n", preserveTriangleOrder ? "yes" : "no");
-
+
draco::Encoder dracoEncoder;
int speed = 10 - static_cast<int>(encoder->compressionLevel);
@@ -87,12 +88,12 @@ bool encoderEncode(Encoder *encoder, uint8_t preserveTriangleOrder)
dracoEncoder.SetAttributeQuantization(draco::GeometryAttribute::COLOR, encoder->quantization.color);
dracoEncoder.SetAttributeQuantization(draco::GeometryAttribute::GENERIC, encoder->quantization.generic);
dracoEncoder.SetTrackEncodedProperties(true);
-
+
if (preserveTriangleOrder)
{
dracoEncoder.SetEncodingMethod(draco::MESH_SEQUENTIAL_ENCODING);
}
-
+
auto encoderStatus = dracoEncoder.EncodeMeshToBuffer(encoder->mesh, &encoder->encoderBuffer);
if (encoderStatus.ok())
{
@@ -130,20 +131,19 @@ void encoderCopy(Encoder *encoder, uint8_t *data)
memcpy(data, encoder->encoderBuffer.data(), encoder->encoderBuffer.size());
}
-template<class T>
+template <class T>
void encodeIndices(Encoder *encoder, uint32_t indexCount, T *indices)
{
int face_count = indexCount / 3;
encoder->mesh.SetNumFaces(static_cast<size_t>(face_count));
encoder->rawSize += indexCount * sizeof(T);
-
+
for (int i = 0; i < face_count; ++i)
{
draco::Mesh::Face face = {
draco::PointIndex(indices[3 * i + 0]),
draco::PointIndex(indices[3 * i + 1]),
- draco::PointIndex(indices[3 * i + 2])
- };
+ draco::PointIndex(indices[3 * i + 2])};
encoder->mesh.SetFace(draco::FaceIndex(static_cast<uint32_t>(i)), face);
}
}
@@ -152,23 +152,23 @@ void encoderSetIndices(Encoder *encoder, size_t indexComponentType, uint32_t ind
{
switch (indexComponentType)
{
- case ComponentType::Byte:
- encodeIndices(encoder, indexCount, reinterpret_cast<int8_t *>(indices));
- break;
- case ComponentType::UnsignedByte:
- encodeIndices(encoder, indexCount, reinterpret_cast<uint8_t *>(indices));
- break;
- case ComponentType::Short:
- encodeIndices(encoder, indexCount, reinterpret_cast<int16_t *>(indices));
- break;
- case ComponentType::UnsignedShort:
- encodeIndices(encoder, indexCount, reinterpret_cast<uint16_t *>(indices));
- break;
- case ComponentType::UnsignedInt:
- encodeIndices(encoder, indexCount, reinterpret_cast<uint32_t *>(indices));
- break;
- default:
- printf(LOG_PREFIX "Index component type %zu not supported\n", indexComponentType);
+ case ComponentType::Byte:
+ encodeIndices(encoder, indexCount, reinterpret_cast<int8_t *>(indices));
+ break;
+ case ComponentType::UnsignedByte:
+ encodeIndices(encoder, indexCount, reinterpret_cast<uint8_t *>(indices));
+ break;
+ case ComponentType::Short:
+ encodeIndices(encoder, indexCount, reinterpret_cast<int16_t *>(indices));
+ break;
+ case ComponentType::UnsignedShort:
+ encodeIndices(encoder, indexCount, reinterpret_cast<uint16_t *>(indices));
+ break;
+ case ComponentType::UnsignedInt:
+ encodeIndices(encoder, indexCount, reinterpret_cast<uint32_t *>(indices));
+ break;
+ default:
+ printf(LOG_PREFIX "Index component type %zu not supported\n", indexComponentType);
}
}
@@ -190,7 +190,7 @@ draco::GeometryAttribute::Type getAttributeSemantics(char *attribute)
{
return draco::GeometryAttribute::COLOR;
}
-
+
return draco::GeometryAttribute::GENERIC;
}
@@ -198,37 +198,38 @@ draco::DataType getDataType(size_t componentType)
{
switch (componentType)
{
- case ComponentType::Byte:
- return draco::DataType::DT_INT8;
-
- case ComponentType::UnsignedByte:
- return draco::DataType::DT_UINT8;
-
- case ComponentType::Short:
- return draco::DataType::DT_INT16;
-
- case ComponentType::UnsignedShort:
- return draco::DataType::DT_UINT16;
-
- case ComponentType::UnsignedInt:
- return draco::DataType::DT_UINT32;
-
- case ComponentType::Float:
- return draco::DataType::DT_FLOAT32;
-
- default:
- return draco::DataType::DT_INVALID;
+ case ComponentType::Byte:
+ return draco::DataType::DT_INT8;
+
+ case ComponentType::UnsignedByte:
+ return draco::DataType::DT_UINT8;
+
+ case ComponentType::Short:
+ return draco::DataType::DT_INT16;
+
+ case ComponentType::UnsignedShort:
+ return draco::DataType::DT_UINT16;
+
+ case ComponentType::UnsignedInt:
+ return draco::DataType::DT_UINT32;
+
+ case ComponentType::Float:
+ return draco::DataType::DT_FLOAT32;
+
+ default:
+ return draco::DataType::DT_INVALID;
}
}
-API(uint32_t) encoderSetAttribute(Encoder *encoder, char *attributeName, size_t componentType, char *dataType, void *data)
+API(uint32_t)
+encoderSetAttribute(Encoder *encoder, char *attributeName, size_t componentType, char *dataType, void *data)
{
auto buffer = std::make_unique<draco::DataBuffer>();
uint32_t count = encoder->mesh.num_points();
size_t componentCount = getNumberOfComponents(dataType);
size_t stride = getAttributeStride(componentType, dataType);
draco::DataType dracoDataType = getDataType(componentType);
-
+
draco::GeometryAttribute::Type semantics = getAttributeSemantics(attributeName);
draco::GeometryAttribute attribute;
attribute.Init(semantics, &*buffer, componentCount, getDataType(componentType), false, stride, 0);
diff --git a/extern/draco/src/encoder.h b/extern/draco/src/encoder.h
index 2f7f21a469b..c6fdc30295b 100644
--- a/extern/draco/src/encoder.h
+++ b/extern/draco/src/encoder.h
@@ -28,24 +28,35 @@
struct Encoder;
-API(Encoder *) encoderCreate(uint32_t vertexCount);
+API(Encoder *)
+encoderCreate(uint32_t vertexCount);
-API(void) encoderRelease(Encoder *encoder);
+API(void)
+encoderRelease(Encoder *encoder);
-API(void) encoderSetCompressionLevel(Encoder *encoder, uint32_t compressionLevel);
+API(void)
+encoderSetCompressionLevel(Encoder *encoder, uint32_t compressionLevel);
-API(void) encoderSetQuantizationBits(Encoder *encoder, uint32_t position, uint32_t normal, uint32_t uv, uint32_t color, uint32_t generic);
+API(void)
+encoderSetQuantizationBits(Encoder *encoder, uint32_t position, uint32_t normal, uint32_t uv, uint32_t color, uint32_t generic);
-API(bool) encoderEncode(Encoder *encoder, uint8_t preserveTriangleOrder);
+API(bool)
+encoderEncode(Encoder *encoder, uint8_t preserveTriangleOrder);
-API(uint64_t) encoderGetByteLength(Encoder *encoder);
+API(uint64_t)
+encoderGetByteLength(Encoder *encoder);
-API(void) encoderCopy(Encoder *encoder, uint8_t *data);
+API(void)
+encoderCopy(Encoder *encoder, uint8_t *data);
-API(void) encoderSetIndices(Encoder *encoder, size_t indexComponentType, uint32_t indexCount, void *indices);
+API(void)
+encoderSetIndices(Encoder *encoder, size_t indexComponentType, uint32_t indexCount, void *indices);
-API(uint32_t) encoderSetAttribute(Encoder *encoder, char *attributeName, size_t componentType, char *dataType, void *data);
+API(uint32_t)
+encoderSetAttribute(Encoder *encoder, char *attributeName, size_t componentType, char *dataType, void *data);
-API(uint32_t) encoderGetEncodedVertexCount(Encoder *encoder);
+API(uint32_t)
+encoderGetEncodedVertexCount(Encoder *encoder);
-API(uint32_t) encoderGetEncodedIndexCount(Encoder *encoder);
+API(uint32_t)
+encoderGetEncodedIndexCount(Encoder *encoder);
diff --git a/intern/cycles/blender/camera.cpp b/intern/cycles/blender/camera.cpp
index 402fd7c4ec6..2ab5f02a337 100644
--- a/intern/cycles/blender/camera.cpp
+++ b/intern/cycles/blender/camera.cpp
@@ -643,7 +643,7 @@ void BlenderSync::sync_camera_motion(
/* TODO(sergey): De-duplicate calculation with camera sync. */
float fov = 2.0f * atanf((0.5f * sensor_size) / bcam.lens / aspectratio);
if (fov != cam->get_fov()) {
- VLOG(3) << "Camera " << b_ob.name() << " FOV change detected.";
+ VLOG_WORK << "Camera " << b_ob.name() << " FOV change detected.";
if (motion_time == 0.0f) {
cam->set_fov(fov);
}
diff --git a/intern/cycles/blender/curves.cpp b/intern/cycles/blender/curves.cpp
index 4e9f4f62087..b01cb85711a 100644
--- a/intern/cycles/blender/curves.cpp
+++ b/intern/cycles/blender/curves.cpp
@@ -341,7 +341,7 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
/* check allocation */
if ((hair->get_curve_keys().size() != num_keys) || (hair->num_curves() != num_curves)) {
- VLOG(1) << "Hair memory allocation failed, clearing data.";
+ VLOG_WARNING << "Hair memory allocation failed, clearing data.";
hair->clear(true);
}
}
@@ -397,7 +397,7 @@ static void export_hair_motion_validate_attribute(Hair *hair,
if (num_motion_keys != num_keys || !have_motion) {
/* No motion or hair "topology" changed, remove attributes again. */
if (num_motion_keys != num_keys) {
- VLOG(1) << "Hair topology changed, removing motion attribute.";
+ VLOG_WORK << "Hair topology changed, removing motion attribute.";
}
hair->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
}
diff --git a/intern/cycles/blender/display_driver.cpp b/intern/cycles/blender/display_driver.cpp
index ee67073a9a4..a1bc064be68 100644
--- a/intern/cycles/blender/display_driver.cpp
+++ b/intern/cycles/blender/display_driver.cpp
@@ -982,10 +982,8 @@ void BlenderDisplayDriver::draw(const Params &params)
gl_render_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glFlush();
- if (VLOG_IS_ON(5)) {
- VLOG(5) << "Number of textures: " << GLTexture::num_used;
- VLOG(5) << "Number of PBOs: " << GLPixelBufferObject::num_used;
- }
+ VLOG_DEVICE_STATS << "Display driver number of textures: " << GLTexture::num_used;
+ VLOG_DEVICE_STATS << "Display driver number of PBOs: " << GLPixelBufferObject::num_used;
if (use_gl_context_) {
gl_context_mutex_.unlock();
diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp
index e2db52cc5c1..63913b7cd7f 100644
--- a/intern/cycles/blender/mesh.cpp
+++ b/intern/cycles/blender/mesh.cpp
@@ -1212,17 +1212,17 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
memcmp(mP, &mesh->get_verts()[0], sizeof(float3) * numverts) == 0) {
/* no motion, remove attributes again */
if (b_mesh.vertices.length() != numverts) {
- VLOG(1) << "Topology differs, disabling motion blur for object " << ob_name;
+ VLOG_WARNING << "Topology differs, disabling motion blur for object " << ob_name;
}
else {
- VLOG(1) << "No actual deformation motion for object " << ob_name;
+ VLOG_DEBUG << "No actual deformation motion for object " << ob_name;
}
mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
if (attr_mN)
mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
}
else if (motion_step > 0) {
- VLOG(1) << "Filling deformation motion for object " << ob_name;
+ VLOG_DEBUG << "Filling deformation motion for object " << ob_name;
/* motion, fill up previous steps that we might have skipped because
* they had no motion, but we need them anyway now */
float3 *P = &mesh->get_verts()[0];
@@ -1236,8 +1236,8 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
}
else {
if (b_mesh.vertices.length() != numverts) {
- VLOG(1) << "Topology differs, discarding motion blur for object " << ob_name << " at time "
- << motion_step;
+ VLOG_WARNING << "Topology differs, discarding motion blur for object " << ob_name
+ << " at time " << motion_step;
memcpy(mP, &mesh->get_verts()[0], sizeof(float3) * numverts);
if (mN != NULL) {
memcpy(mN, attr_N->data_float3(), sizeof(float3) * numverts);
diff --git a/intern/cycles/blender/object.cpp b/intern/cycles/blender/object.cpp
index 9b08b564b25..ca1aa6329d9 100644
--- a/intern/cycles/blender/object.cpp
+++ b/intern/cycles/blender/object.cpp
@@ -762,7 +762,7 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render,
continue;
}
- VLOG(1) << "Synchronizing motion for the relative time " << relative_time << ".";
+ VLOG_WORK << "Synchronizing motion for the relative time " << relative_time << ".";
/* fixed shutter time to get previous and next frame for motion pass */
float shuttertime = scene->motion_shutter_time();
diff --git a/intern/cycles/blender/session.cpp b/intern/cycles/blender/session.cpp
index 87f051ba50b..6d27b8e7d87 100644
--- a/intern/cycles/blender/session.cpp
+++ b/intern/cycles/blender/session.cpp
@@ -458,8 +458,8 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
double total_time, render_time;
session->progress.get_time(total_time, render_time);
- VLOG(1) << "Total render time: " << total_time;
- VLOG(1) << "Render time (without synchronization): " << render_time;
+ VLOG_INFO << "Total render time: " << total_time;
+ VLOG_INFO << "Render time (without synchronization): " << render_time;
}
void BlenderSession::render_frame_finish()
diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp
index 1028c940772..63e9e1e0e68 100644
--- a/intern/cycles/blender/sync.cpp
+++ b/intern/cycles/blender/sync.cpp
@@ -285,7 +285,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
free_data_after_sync(b_depsgraph);
- VLOG(1) << "Total time spent synchronizing data: " << timer.get_time();
+ VLOG_INFO << "Total time spent synchronizing data: " << timer.get_time();
has_updates_ = false;
}
@@ -390,7 +390,7 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
}
if (scrambling_distance != 1.0f) {
- VLOG(3) << "Using scrambling distance: " << scrambling_distance;
+ VLOG_INFO << "Using scrambling distance: " << scrambling_distance;
}
integrator->set_scrambling_distance(scrambling_distance);
diff --git a/intern/cycles/bvh/build.cpp b/intern/cycles/bvh/build.cpp
index 1df3517673e..cf03f05de60 100644
--- a/intern/cycles/bvh/build.cpp
+++ b/intern/cycles/bvh/build.cpp
@@ -529,7 +529,7 @@ BVHNode *BVHBuild::run()
if (progress.get_cancel()) {
rootnode->deleteSubtree();
rootnode = NULL;
- VLOG(1) << "BVH build cancelled.";
+ VLOG_WORK << "BVH build cancelled.";
}
else {
/*rotate(rootnode, 4, 5);*/
@@ -537,26 +537,26 @@ BVHNode *BVHBuild::run()
rootnode->update_time();
}
if (rootnode != NULL) {
- VLOG(1) << "BVH build statistics:\n"
- << " Build time: " << time_dt() - build_start_time << "\n"
- << " Total number of nodes: "
- << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_NODE_COUNT))
- << "\n"
- << " Number of inner nodes: "
- << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_INNER_COUNT))
- << "\n"
- << " Number of leaf nodes: "
- << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_LEAF_COUNT))
- << "\n"
- << " Number of unaligned nodes: "
- << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_UNALIGNED_COUNT))
- << "\n"
- << " Allocation slop factor: "
- << ((prim_type.capacity() != 0) ? (float)prim_type.size() / prim_type.capacity() :
- 1.0f)
- << "\n"
- << " Maximum depth: "
- << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_DEPTH)) << "\n";
+ VLOG_WORK << "BVH build statistics:\n"
+ << " Build time: " << time_dt() - build_start_time << "\n"
+ << " Total number of nodes: "
+ << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_NODE_COUNT))
+ << "\n"
+ << " Number of inner nodes: "
+ << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_INNER_COUNT))
+ << "\n"
+ << " Number of leaf nodes: "
+ << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_LEAF_COUNT))
+ << "\n"
+ << " Number of unaligned nodes: "
+ << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_UNALIGNED_COUNT))
+ << "\n"
+ << " Allocation slop factor: "
+ << ((prim_type.capacity() != 0) ? (float)prim_type.size() / prim_type.capacity() :
+ 1.0f)
+ << "\n"
+ << " Maximum depth: "
+ << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_DEPTH)) << "\n";
}
}
diff --git a/intern/cycles/bvh/embree.cpp b/intern/cycles/bvh/embree.cpp
index 0fc71f49ce3..eed7ae19965 100644
--- a/intern/cycles/bvh/embree.cpp
+++ b/intern/cycles/bvh/embree.cpp
@@ -250,7 +250,7 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
*isect = current_isect;
/* Only primitives from volume object. */
uint tri_object = isect->object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ int object_flag = kernel_data_fetch(object_flag, tri_object);
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
--ctx->num_hits;
}
@@ -332,7 +332,7 @@ static bool rtc_memory_monitor_func(void *userPtr, const ssize_t bytes, const bo
static void rtc_error_func(void *, enum RTCError, const char *str)
{
- VLOG(1) << str;
+ VLOG_WARNING << str;
}
static double progress_start_time = 0.0;
@@ -521,8 +521,8 @@ void BVHEmbree::add_triangles(const Object *ob, const Mesh *mesh, int i)
geom_id, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, sizeof(int) * 3, num_triangles);
assert(rtc_indices);
if (!rtc_indices) {
- VLOG(1) << "Embree could not create new geometry buffer for mesh " << mesh->name.c_str()
- << ".\n";
+ VLOG_WARNING << "Embree could not create new geometry buffer for mesh " << mesh->name.c_str()
+ << ".\n";
return;
}
for (size_t j = 0; j < num_triangles; ++j) {
diff --git a/intern/cycles/device/cpu/device_impl.cpp b/intern/cycles/device/cpu/device_impl.cpp
index 612c391f7d5..d4f0532aa5e 100644
--- a/intern/cycles/device/cpu/device_impl.cpp
+++ b/intern/cycles/device/cpu/device_impl.cpp
@@ -51,12 +51,12 @@
CCL_NAMESPACE_BEGIN
CPUDevice::CPUDevice(const DeviceInfo &info_, Stats &stats_, Profiler &profiler_)
- : Device(info_, stats_, profiler_), texture_info(this, "__texture_info", MEM_GLOBAL)
+ : Device(info_, stats_, profiler_), texture_info(this, "texture_info", MEM_GLOBAL)
{
/* Pick any kernel, all of them are supposed to have same level of microarchitecture
* optimization. */
- VLOG(1) << "Using " << get_cpu_kernels().integrator_init_from_camera.get_uarch_name()
- << " CPU kernels.";
+ VLOG_INFO << "Using " << get_cpu_kernels().integrator_init_from_camera.get_uarch_name()
+ << " CPU kernels.";
if (info.cpu_threads == 0) {
info.cpu_threads = TaskScheduler::max_concurrency();
@@ -111,9 +111,9 @@ void CPUDevice::mem_alloc(device_memory &mem)
}
else {
if (mem.name) {
- VLOG(1) << "Buffer allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")";
+ VLOG_WORK << "Buffer allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")";
}
if (mem.type == MEM_DEVICE_ONLY || !mem.host_pointer) {
@@ -192,7 +192,7 @@ device_ptr CPUDevice::mem_alloc_sub_ptr(device_memory &mem, size_t offset, size_
void CPUDevice::const_copy_to(const char *name, void *host, size_t size)
{
#ifdef WITH_EMBREE
- if (strcmp(name, "__data") == 0) {
+ if (strcmp(name, "data") == 0) {
assert(size <= sizeof(KernelData));
// Update scene handle (since it is different for each device on multi devices)
@@ -205,9 +205,9 @@ void CPUDevice::const_copy_to(const char *name, void *host, size_t size)
void CPUDevice::global_alloc(device_memory &mem)
{
- VLOG(1) << "Global memory allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")";
+ VLOG_WORK << "Global memory allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")";
kernel_global_memory_copy(&kernel_globals, mem.name, mem.host_pointer, mem.data_size);
@@ -227,9 +227,9 @@ void CPUDevice::global_free(device_memory &mem)
void CPUDevice::tex_alloc(device_texture &mem)
{
- VLOG(1) << "Texture allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")";
+ VLOG_WORK << "Texture allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")";
mem.device_pointer = (device_ptr)mem.host_pointer;
mem.device_size = mem.memory_size();
diff --git a/intern/cycles/device/cuda/device.cpp b/intern/cycles/device/cuda/device.cpp
index 400490336d6..5a213c45b71 100644
--- a/intern/cycles/device/cuda/device.cpp
+++ b/intern/cycles/device/cuda/device.cpp
@@ -29,24 +29,25 @@ bool device_cuda_init()
initialized = true;
int cuew_result = cuewInit(CUEW_INIT_CUDA);
if (cuew_result == CUEW_SUCCESS) {
- VLOG(1) << "CUEW initialization succeeded";
+ VLOG_INFO << "CUEW initialization succeeded";
if (CUDADevice::have_precompiled_kernels()) {
- VLOG(1) << "Found precompiled kernels";
+ VLOG_INFO << "Found precompiled kernels";
result = true;
}
else if (cuewCompilerPath() != NULL) {
- VLOG(1) << "Found CUDA compiler " << cuewCompilerPath();
+ VLOG_INFO << "Found CUDA compiler " << cuewCompilerPath();
result = true;
}
else {
- VLOG(1) << "Neither precompiled kernels nor CUDA compiler was found,"
- << " unable to use CUDA";
+ VLOG_INFO << "Neither precompiled kernels nor CUDA compiler was found,"
+ << " unable to use CUDA";
}
}
else {
- VLOG(1) << "CUEW initialization failed: "
- << ((cuew_result == CUEW_ERROR_ATEXIT_FAILED) ? "Error setting up atexit() handler" :
- "Error opening the library");
+ VLOG_WARNING << "CUEW initialization failed: "
+ << ((cuew_result == CUEW_ERROR_ATEXIT_FAILED) ?
+ "Error setting up atexit() handler" :
+ "Error opening the library");
}
return result;
@@ -121,7 +122,8 @@ void device_cuda_info(vector<DeviceInfo> &devices)
int major;
cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, num);
if (major < 3) {
- VLOG(1) << "Ignoring device \"" << name << "\", this graphics card is no longer supported.";
+ VLOG_INFO << "Ignoring device \"" << name
+ << "\", this graphics card is no longer supported.";
continue;
}
@@ -166,21 +168,21 @@ void device_cuda_info(vector<DeviceInfo> &devices)
* Windows 10 even when it is, due to an issue in application profiles.
* Detect case where we expect it to be available and override. */
if (preempt_attr == 0 && (major >= 6) && system_windows_version_at_least(10, 17134)) {
- VLOG(1) << "Assuming device has compute preemption on Windows 10.";
+ VLOG_INFO << "Assuming device has compute preemption on Windows 10.";
preempt_attr = 1;
}
if (timeout_attr && !preempt_attr) {
- VLOG(1) << "Device is recognized as display.";
+ VLOG_INFO << "Device is recognized as display.";
info.description += " (Display)";
info.display_device = true;
display_devices.push_back(info);
}
else {
- VLOG(1) << "Device has compute preemption or is not used for display.";
+ VLOG_INFO << "Device has compute preemption or is not used for display.";
devices.push_back(info);
}
- VLOG(1) << "Added device \"" << name << "\" with id \"" << info.id << "\".";
+ VLOG_INFO << "Added device \"" << name << "\" with id \"" << info.id << "\".";
}
if (!display_devices.empty())
diff --git a/intern/cycles/device/cuda/device_impl.cpp b/intern/cycles/device/cuda/device_impl.cpp
index cb7e909a2d5..00851a8e91c 100644
--- a/intern/cycles/device/cuda/device_impl.cpp
+++ b/intern/cycles/device/cuda/device_impl.cpp
@@ -23,6 +23,8 @@
# include "util/types.h"
# include "util/windows.h"
+# include "kernel/device/cuda/globals.h"
+
CCL_NAMESPACE_BEGIN
class CUDADevice;
@@ -51,7 +53,7 @@ void CUDADevice::set_error(const string &error)
}
CUDADevice::CUDADevice(const DeviceInfo &info, Stats &stats, Profiler &profiler)
- : Device(info, stats, profiler), texture_info(this, "__texture_info", MEM_GLOBAL)
+ : Device(info, stats, profiler), texture_info(this, "texture_info", MEM_GLOBAL)
{
first_error = true;
@@ -244,9 +246,9 @@ string CUDADevice::compile_kernel(const uint kernel_features,
if (!use_adaptive_compilation()) {
if (!force_ptx) {
const string cubin = path_get(string_printf("lib/%s_sm_%d%d.cubin", name, major, minor));
- VLOG(1) << "Testing for pre-compiled kernel " << cubin << ".";
+ VLOG_INFO << "Testing for pre-compiled kernel " << cubin << ".";
if (path_exists(cubin)) {
- VLOG(1) << "Using precompiled kernel.";
+ VLOG_INFO << "Using precompiled kernel.";
return cubin;
}
}
@@ -256,9 +258,9 @@ string CUDADevice::compile_kernel(const uint kernel_features,
while (ptx_major >= 3) {
const string ptx = path_get(
string_printf("lib/%s_compute_%d%d.ptx", name, ptx_major, ptx_minor));
- VLOG(1) << "Testing for pre-compiled kernel " << ptx << ".";
+ VLOG_INFO << "Testing for pre-compiled kernel " << ptx << ".";
if (path_exists(ptx)) {
- VLOG(1) << "Using precompiled kernel.";
+ VLOG_INFO << "Using precompiled kernel.";
return ptx;
}
@@ -287,9 +289,9 @@ string CUDADevice::compile_kernel(const uint kernel_features,
const string cubin_file = string_printf(
"cycles_%s_%s_%d%d_%s.%s", name, kernel_arch, major, minor, kernel_md5.c_str(), kernel_ext);
const string cubin = path_cache_get(path_join("kernels", cubin_file));
- VLOG(1) << "Testing for locally compiled kernel " << cubin << ".";
+ VLOG_INFO << "Testing for locally compiled kernel " << cubin << ".";
if (path_exists(cubin)) {
- VLOG(1) << "Using locally compiled kernel.";
+ VLOG_INFO << "Using locally compiled kernel.";
return cubin;
}
@@ -323,7 +325,7 @@ string CUDADevice::compile_kernel(const uint kernel_features,
}
const int nvcc_cuda_version = cuewCompilerVersion();
- VLOG(1) << "Found nvcc " << nvcc << ", CUDA version " << nvcc_cuda_version << ".";
+ VLOG_INFO << "Found nvcc " << nvcc << ", CUDA version " << nvcc_cuda_version << ".";
if (nvcc_cuda_version < 101) {
printf(
"Unsupported CUDA version %d.%d detected, "
@@ -399,7 +401,8 @@ bool CUDADevice::load_kernels(const uint kernel_features)
*/
if (cuModule) {
if (use_adaptive_compilation()) {
- VLOG(1) << "Skipping CUDA kernel reload for adaptive compilation, not currently supported.";
+ VLOG_INFO
+ << "Skipping CUDA kernel reload for adaptive compilation, not currently supported.";
}
return true;
}
@@ -481,8 +484,8 @@ void CUDADevice::reserve_local_memory(const uint kernel_features)
cuMemGetInfo(&free_after, &total);
}
- VLOG(1) << "Local memory reserved " << string_human_readable_number(free_before - free_after)
- << " bytes. (" << string_human_readable_size(free_before - free_after) << ")";
+ VLOG_INFO << "Local memory reserved " << string_human_readable_number(free_before - free_after)
+ << " bytes. (" << string_human_readable_size(free_before - free_after) << ")";
# if 0
/* For testing mapped host memory, fill up device memory. */
@@ -513,7 +516,7 @@ void CUDADevice::init_host_memory()
}
}
else {
- VLOG(1) << "Mapped host memory disabled, failed to get system RAM";
+ VLOG_WARNING << "Mapped host memory disabled, failed to get system RAM";
map_host_limit = 0;
}
@@ -524,8 +527,8 @@ void CUDADevice::init_host_memory()
device_working_headroom = 32 * 1024 * 1024LL; // 32MB
device_texture_headroom = 128 * 1024 * 1024LL; // 128MB
- VLOG(1) << "Mapped host memory limit set to " << string_human_readable_number(map_host_limit)
- << " bytes. (" << string_human_readable_size(map_host_limit) << ")";
+ VLOG_INFO << "Mapped host memory limit set to " << string_human_readable_number(map_host_limit)
+ << " bytes. (" << string_human_readable_size(map_host_limit) << ")";
}
void CUDADevice::load_texture_info()
@@ -593,7 +596,7 @@ void CUDADevice::move_textures_to_host(size_t size, bool for_texture)
* multiple CUDA devices could be moving the memory. The
* first one will do it, and the rest will adopt the pointer. */
if (max_mem) {
- VLOG(1) << "Move memory from device to host: " << max_mem->name;
+ VLOG_WORK << "Move memory from device to host: " << max_mem->name;
static thread_mutex move_mutex;
thread_scoped_lock lock(move_mutex);
@@ -701,9 +704,9 @@ CUDADevice::CUDAMem *CUDADevice::generic_alloc(device_memory &mem, size_t pitch_
}
if (mem.name) {
- VLOG(1) << "Buffer allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")" << status;
+ VLOG_WORK << "Buffer allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")" << status;
}
mem.device_pointer = (device_ptr)device_pointer;
@@ -899,9 +902,19 @@ void CUDADevice::const_copy_to(const char *name, void *host, size_t size)
CUdeviceptr mem;
size_t bytes;
- cuda_assert(cuModuleGetGlobal(&mem, &bytes, cuModule, name));
- // assert(bytes == size);
- cuda_assert(cuMemcpyHtoD(mem, host, size));
+ cuda_assert(cuModuleGetGlobal(&mem, &bytes, cuModule, "kernel_params"));
+ assert(bytes == sizeof(KernelParamsCUDA));
+
+ /* Update data storage pointers in launch parameters. */
+# define KERNEL_DATA_ARRAY(data_type, data_name) \
+ if (strcmp(name, #data_name) == 0) { \
+ cuda_assert(cuMemcpyHtoD(mem + offsetof(KernelParamsCUDA, data_name), host, size)); \
+ return; \
+ }
+ KERNEL_DATA_ARRAY(KernelData, data)
+ KERNEL_DATA_ARRAY(IntegratorStateGPU, integrator_state)
+# include "kernel/data_arrays.h"
+# undef KERNEL_DATA_ARRAY
}
void CUDADevice::global_alloc(device_memory &mem)
@@ -925,7 +938,6 @@ void CUDADevice::tex_alloc(device_texture &mem)
{
CUDAContextScope scope(this);
- string bind_name = mem.name;
size_t dsize = datatype_size(mem.data_type);
size_t size = mem.memory_size();
@@ -1008,9 +1020,9 @@ void CUDADevice::tex_alloc(device_texture &mem)
desc.NumChannels = mem.data_elements;
desc.Flags = 0;
- VLOG(1) << "Array 3D allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")";
+ VLOG_WORK << "Array 3D allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")";
cuda_assert(cuArray3DCreate(&array_3d, &desc));
diff --git a/intern/cycles/device/cuda/queue.cpp b/intern/cycles/device/cuda/queue.cpp
index 38c71866ad0..5912e68a92b 100644
--- a/intern/cycles/device/cuda/queue.cpp
+++ b/intern/cycles/device/cuda/queue.cpp
@@ -39,12 +39,12 @@ int CUDADeviceQueue::num_concurrent_states(const size_t state_size) const
num_states = max((int)(num_states * factor), 1024);
}
else {
- VLOG(3) << "CYCLES_CONCURRENT_STATES_FACTOR evaluated to 0";
+ VLOG_DEVICE_STATS << "CYCLES_CONCURRENT_STATES_FACTOR evaluated to 0";
}
}
- VLOG(3) << "GPU queue concurrent states: " << num_states << ", using up to "
- << string_human_readable_size(num_states * state_size);
+ VLOG_DEVICE_STATS << "GPU queue concurrent states: " << num_states << ", using up to "
+ << string_human_readable_size(num_states * state_size);
return num_states;
}
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index ea5b3c6dc8c..82c7881da5f 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -325,8 +325,8 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
int orig_cpu_threads = (threads) ? threads : TaskScheduler::max_concurrency();
int cpu_threads = max(orig_cpu_threads - (subdevices.size() - 1), size_t(0));
- VLOG(1) << "CPU render threads reduced from " << orig_cpu_threads << " to " << cpu_threads
- << ", to dedicate to GPU.";
+ VLOG_INFO << "CPU render threads reduced from " << orig_cpu_threads << " to "
+ << cpu_threads << ", to dedicate to GPU.";
if (cpu_threads >= 1) {
DeviceInfo cpu_device = device;
@@ -338,7 +338,7 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
}
}
else {
- VLOG(1) << "CPU render threads disabled for interactive render.";
+ VLOG_INFO << "CPU render threads disabled for interactive render.";
continue;
}
}
diff --git a/intern/cycles/device/hip/device.cpp b/intern/cycles/device/hip/device.cpp
index d6a5ed9c419..3c9c73e7db0 100644
--- a/intern/cycles/device/hip/device.cpp
+++ b/intern/cycles/device/hip/device.cpp
@@ -29,30 +29,31 @@ bool device_hip_init()
initialized = true;
int hipew_result = hipewInit(HIPEW_INIT_HIP);
if (hipew_result == HIPEW_SUCCESS) {
- VLOG(1) << "HIPEW initialization succeeded";
+ VLOG_INFO << "HIPEW initialization succeeded";
if (HIPDevice::have_precompiled_kernels()) {
- VLOG(1) << "Found precompiled kernels";
+ VLOG_INFO << "Found precompiled kernels";
result = true;
}
else if (hipewCompilerPath() != NULL) {
- VLOG(1) << "Found HIPCC " << hipewCompilerPath();
+ VLOG_INFO << "Found HIPCC " << hipewCompilerPath();
result = true;
}
else {
- VLOG(1) << "Neither precompiled kernels nor HIPCC was found,"
- << " unable to use HIP";
+ VLOG_INFO << "Neither precompiled kernels nor HIPCC was found,"
+ << " unable to use HIP";
}
}
else {
if (hipew_result == HIPEW_ERROR_ATEXIT_FAILED) {
- VLOG(1) << "HIPEW initialization failed: Error setting up atexit() handler";
+ VLOG_WARNING << "HIPEW initialization failed: Error setting up atexit() handler";
}
else if (hipew_result == HIPEW_ERROR_OLD_DRIVER) {
- VLOG(1) << "HIPEW initialization failed: Driver version too old, requires AMD Radeon Pro "
- "21.Q4 driver or newer";
+ VLOG_WARNING
+ << "HIPEW initialization failed: Driver version too old, requires AMD Radeon Pro "
+ "21.Q4 driver or newer";
}
else {
- VLOG(1) << "HIPEW initialization failed: Error opening HIP dynamic library";
+ VLOG_WARNING << "HIPEW initialization failed: Error opening HIP dynamic library";
}
}
@@ -165,16 +166,16 @@ void device_hip_info(vector<DeviceInfo> &devices)
hipDeviceGetAttribute(&timeout_attr, hipDeviceAttributeKernelExecTimeout, num);
if (timeout_attr && !preempt_attr) {
- VLOG(1) << "Device is recognized as display.";
+ VLOG_INFO << "Device is recognized as display.";
info.description += " (Display)";
info.display_device = true;
display_devices.push_back(info);
}
else {
- VLOG(1) << "Device has compute preemption or is not used for display.";
+ VLOG_INFO << "Device has compute preemption or is not used for display.";
devices.push_back(info);
}
- VLOG(1) << "Added device \"" << name << "\" with id \"" << info.id << "\".";
+ VLOG_INFO << "Added device \"" << name << "\" with id \"" << info.id << "\".";
}
if (!display_devices.empty())
diff --git a/intern/cycles/device/hip/device_impl.cpp b/intern/cycles/device/hip/device_impl.cpp
index ea68c821166..82db55ea715 100644
--- a/intern/cycles/device/hip/device_impl.cpp
+++ b/intern/cycles/device/hip/device_impl.cpp
@@ -24,6 +24,8 @@
# include "util/types.h"
# include "util/windows.h"
+# include "kernel/device/hip/globals.h"
+
CCL_NAMESPACE_BEGIN
class HIPDevice;
@@ -52,7 +54,7 @@ void HIPDevice::set_error(const string &error)
}
HIPDevice::HIPDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler)
- : Device(info, stats, profiler), texture_info(this, "__texture_info", MEM_GLOBAL)
+ : Device(info, stats, profiler), texture_info(this, "texture_info", MEM_GLOBAL)
{
first_error = true;
@@ -233,9 +235,9 @@ string HIPDevice::compile_kernel(const uint kernel_features, const char *name, c
/* Attempt to use kernel provided with Blender. */
if (!use_adaptive_compilation()) {
const string fatbin = path_get(string_printf("lib/%s_%s.fatbin", name, arch));
- VLOG(1) << "Testing for pre-compiled kernel " << fatbin << ".";
+ VLOG_INFO << "Testing for pre-compiled kernel " << fatbin << ".";
if (path_exists(fatbin)) {
- VLOG(1) << "Using precompiled kernel.";
+ VLOG_INFO << "Using precompiled kernel.";
return fatbin;
}
}
@@ -265,9 +267,9 @@ string HIPDevice::compile_kernel(const uint kernel_features, const char *name, c
const string include_path = source_path;
const string fatbin_file = string_printf("cycles_%s_%s_%s", name, arch, kernel_md5.c_str());
const string fatbin = path_cache_get(path_join("kernels", fatbin_file));
- VLOG(1) << "Testing for locally compiled kernel " << fatbin << ".";
+ VLOG_INFO << "Testing for locally compiled kernel " << fatbin << ".";
if (path_exists(fatbin)) {
- VLOG(1) << "Using locally compiled kernel.";
+ VLOG_INFO << "Using locally compiled kernel.";
return fatbin;
}
@@ -301,7 +303,7 @@ string HIPDevice::compile_kernel(const uint kernel_features, const char *name, c
}
const int hipcc_hip_version = hipewCompilerVersion();
- VLOG(1) << "Found hipcc " << hipcc << ", HIP version " << hipcc_hip_version << ".";
+ VLOG_INFO << "Found hipcc " << hipcc << ", HIP version " << hipcc_hip_version << ".";
if (hipcc_hip_version < 40) {
printf(
"Unsupported HIP version %d.%d detected, "
@@ -361,7 +363,7 @@ bool HIPDevice::load_kernels(const uint kernel_features)
*/
if (hipModule) {
if (use_adaptive_compilation()) {
- VLOG(1) << "Skipping HIP kernel reload for adaptive compilation, not currently supported.";
+ VLOG_INFO << "Skipping HIP kernel reload for adaptive compilation, not currently supported.";
}
return true;
}
@@ -444,8 +446,8 @@ void HIPDevice::reserve_local_memory(const uint kernel_features)
hipMemGetInfo(&free_after, &total);
}
- VLOG(1) << "Local memory reserved " << string_human_readable_number(free_before - free_after)
- << " bytes. (" << string_human_readable_size(free_before - free_after) << ")";
+ VLOG_INFO << "Local memory reserved " << string_human_readable_number(free_before - free_after)
+ << " bytes. (" << string_human_readable_size(free_before - free_after) << ")";
# if 0
/* For testing mapped host memory, fill up device memory. */
@@ -476,7 +478,7 @@ void HIPDevice::init_host_memory()
}
}
else {
- VLOG(1) << "Mapped host memory disabled, failed to get system RAM";
+ VLOG_WARNING << "Mapped host memory disabled, failed to get system RAM";
map_host_limit = 0;
}
@@ -487,8 +489,8 @@ void HIPDevice::init_host_memory()
device_working_headroom = 32 * 1024 * 1024LL; // 32MB
device_texture_headroom = 128 * 1024 * 1024LL; // 128MB
- VLOG(1) << "Mapped host memory limit set to " << string_human_readable_number(map_host_limit)
- << " bytes. (" << string_human_readable_size(map_host_limit) << ")";
+ VLOG_INFO << "Mapped host memory limit set to " << string_human_readable_number(map_host_limit)
+ << " bytes. (" << string_human_readable_size(map_host_limit) << ")";
}
void HIPDevice::load_texture_info()
@@ -556,7 +558,7 @@ void HIPDevice::move_textures_to_host(size_t size, bool for_texture)
* multiple HIP devices could be moving the memory. The
* first one will do it, and the rest will adopt the pointer. */
if (max_mem) {
- VLOG(1) << "Move memory from device to host: " << max_mem->name;
+ VLOG_WORK << "Move memory from device to host: " << max_mem->name;
static thread_mutex move_mutex;
thread_scoped_lock lock(move_mutex);
@@ -658,9 +660,9 @@ HIPDevice::HIPMem *HIPDevice::generic_alloc(device_memory &mem, size_t pitch_pad
}
if (mem.name) {
- VLOG(1) << "Buffer allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")" << status;
+ VLOG_WORK << "Buffer allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")" << status;
}
mem.device_pointer = (device_ptr)device_pointer;
@@ -856,8 +858,19 @@ void HIPDevice::const_copy_to(const char *name, void *host, size_t size)
hipDeviceptr_t mem;
size_t bytes;
- hip_assert(hipModuleGetGlobal(&mem, &bytes, hipModule, name));
- hip_assert(hipMemcpyHtoD(mem, host, size));
+ hip_assert(hipModuleGetGlobal(&mem, &bytes, hipModule, "kernel_params"));
+ assert(bytes == sizeof(KernelParamsHIP));
+
+ /* Update data storage pointers in launch parameters. */
+# define KERNEL_DATA_ARRAY(data_type, data_name) \
+ if (strcmp(name, #data_name) == 0) { \
+ hip_assert(hipMemcpyHtoD(mem + offsetof(KernelParamsHIP, data_name), host, size)); \
+ return; \
+ }
+ KERNEL_DATA_ARRAY(KernelData, data)
+ KERNEL_DATA_ARRAY(IntegratorStateGPU, integrator_state)
+# include "kernel/data_arrays.h"
+# undef KERNEL_DATA_ARRAY
}
void HIPDevice::global_alloc(device_memory &mem)
@@ -881,7 +894,6 @@ void HIPDevice::tex_alloc(device_texture &mem)
{
HIPContextScope scope(this);
- string bind_name = mem.name;
size_t dsize = datatype_size(mem.data_type);
size_t size = mem.memory_size();
@@ -966,9 +978,9 @@ void HIPDevice::tex_alloc(device_texture &mem)
desc.NumChannels = mem.data_elements;
desc.Flags = 0;
- VLOG(1) << "Array 3D allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")";
+ VLOG_WORK << "Array 3D allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")";
hip_assert(hipArray3DCreate((hArray *)&array_3d, &desc));
diff --git a/intern/cycles/device/hip/queue.cpp b/intern/cycles/device/hip/queue.cpp
index 6c2c2c29624..8b3d963a32f 100644
--- a/intern/cycles/device/hip/queue.cpp
+++ b/intern/cycles/device/hip/queue.cpp
@@ -39,12 +39,12 @@ int HIPDeviceQueue::num_concurrent_states(const size_t state_size) const
num_states = max((int)(num_states * factor), 1024);
}
else {
- VLOG(3) << "CYCLES_CONCURRENT_STATES_FACTOR evaluated to 0";
+ VLOG_DEVICE_STATS << "CYCLES_CONCURRENT_STATES_FACTOR evaluated to 0";
}
}
- VLOG(3) << "GPU queue concurrent states: " << num_states << ", using up to "
- << string_human_readable_size(num_states * state_size);
+ VLOG_DEVICE_STATS << "GPU queue concurrent states: " << num_states << ", using up to "
+ << string_human_readable_size(num_states * state_size);
return num_states;
}
diff --git a/intern/cycles/device/memory.h b/intern/cycles/device/memory.h
index 55d6d39cef8..5f44475077e 100644
--- a/intern/cycles/device/memory.h
+++ b/intern/cycles/device/memory.h
@@ -350,7 +350,7 @@ template<typename T> class device_only_memory : public device_memory {
*
* When using memory type MEM_GLOBAL, a pointer to this memory will be
* automatically attached to kernel globals, using the provided name
- * matching an entry in kernel_textures.h. */
+ * matching an entry in kernel/data_arrays.h. */
template<typename T> class device_vector : public device_memory {
public:
diff --git a/intern/cycles/device/metal/device_impl.mm b/intern/cycles/device/metal/device_impl.mm
index 086bf0af979..0a89055af34 100644
--- a/intern/cycles/device/metal/device_impl.mm
+++ b/intern/cycles/device/metal/device_impl.mm
@@ -35,7 +35,7 @@ void MetalDevice::set_error(const string &error)
}
MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler)
- : Device(info, stats, profiler), texture_info(this, "__texture_info", MEM_GLOBAL)
+ : Device(info, stats, profiler), texture_info(this, "texture_info", MEM_GLOBAL)
{
mtlDevId = info.num;
@@ -411,9 +411,9 @@ MetalDevice::MetalMem *MetalDevice::generic_alloc(device_memory &mem)
}
if (mem.name) {
- VLOG(2) << "Buffer allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")";
+ VLOG_WORK << "Buffer allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")";
}
mem.device_size = metal_buffer.allocatedSize;
@@ -625,7 +625,7 @@ device_ptr MetalDevice::mem_alloc_sub_ptr(device_memory &mem, size_t offset, siz
void MetalDevice::const_copy_to(const char *name, void *host, size_t size)
{
- if (strcmp(name, "__data") == 0) {
+ if (strcmp(name, "data") == 0) {
assert(size == sizeof(KernelData));
memcpy((uint8_t *)&launch_params + offsetof(KernelParamsMetal, data), host, size);
return;
@@ -646,19 +646,19 @@ void MetalDevice::const_copy_to(const char *name, void *host, size_t size)
};
/* Update data storage pointers in launch parameters. */
- if (strcmp(name, "__integrator_state") == 0) {
+ if (strcmp(name, "integrator_state") == 0) {
/* IntegratorStateGPU is contiguous pointers */
const size_t pointer_block_size = sizeof(IntegratorStateGPU);
update_launch_pointers(
- offsetof(KernelParamsMetal, __integrator_state), host, size, pointer_block_size);
+ offsetof(KernelParamsMetal, integrator_state), host, size, pointer_block_size);
}
-# define KERNEL_TEX(data_type, tex_name) \
+# define KERNEL_DATA_ARRAY(data_type, tex_name) \
else if (strcmp(name, #tex_name) == 0) \
{ \
update_launch_pointers(offsetof(KernelParamsMetal, tex_name), host, size, size); \
}
-# include "kernel/textures.h"
-# undef KERNEL_TEX
+# include "kernel/data_arrays.h"
+# undef KERNEL_DATA_ARRAY
}
void MetalDevice::global_alloc(device_memory &mem)
@@ -800,9 +800,9 @@ void MetalDevice::tex_alloc(device_texture &mem)
desc.textureType = MTLTextureType3D;
desc.depth = mem.data_depth;
- VLOG(2) << "Texture 3D allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")";
+ VLOG_WORK << "Texture 3D allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")";
mtlTexture = [mtlDevice newTextureWithDescriptor:desc];
assert(mtlTexture);
@@ -834,9 +834,9 @@ void MetalDevice::tex_alloc(device_texture &mem)
desc.storageMode = storage_mode;
desc.usage = MTLTextureUsageShaderRead;
- VLOG(2) << "Texture 2D allocate: " << mem.name << ", "
- << string_human_readable_number(mem.memory_size()) << " bytes. ("
- << string_human_readable_size(mem.memory_size()) << ")";
+ VLOG_WORK << "Texture 2D allocate: " << mem.name << ", "
+ << string_human_readable_number(mem.memory_size()) << " bytes. ("
+ << string_human_readable_size(mem.memory_size()) << ")";
mtlTexture = [mtlDevice newTextureWithDescriptor:desc];
assert(mtlTexture);
diff --git a/intern/cycles/device/metal/queue.mm b/intern/cycles/device/metal/queue.mm
index 0e260886abb..da5408373bb 100644
--- a/intern/cycles/device/metal/queue.mm
+++ b/intern/cycles/device/metal/queue.mm
@@ -311,8 +311,8 @@ bool MetalDeviceQueue::enqueue(DeviceKernel kernel,
return false;
}
- VLOG(3) << "Metal queue launch " << device_kernel_as_string(kernel) << ", work_size "
- << work_size;
+ VLOG_DEVICE_STATS << "Metal queue launch " << device_kernel_as_string(kernel) << ", work_size "
+ << work_size;
id<MTLComputeCommandEncoder> mtlComputeCommandEncoder = get_compute_encoder(kernel);
@@ -358,7 +358,7 @@ bool MetalDeviceQueue::enqueue(DeviceKernel kernel,
/* Prepare any non-pointer (i.e. plain-old-data) KernelParamsMetal data */
/* The plain-old-data is contiguous, continuing to the end of KernelParamsMetal */
- size_t plain_old_launch_data_offset = offsetof(KernelParamsMetal, __integrator_state) +
+ size_t plain_old_launch_data_offset = offsetof(KernelParamsMetal, integrator_state) +
sizeof(IntegratorStateGPU);
size_t plain_old_launch_data_size = sizeof(KernelParamsMetal) - plain_old_launch_data_offset;
memcpy(init_arg_buffer + globals_offsets + plain_old_launch_data_offset,
@@ -415,7 +415,7 @@ bool MetalDeviceQueue::enqueue(DeviceKernel kernel,
}
/* this relies on IntegratorStateGPU layout being contiguous device_ptrs */
- const size_t pointer_block_end = offsetof(KernelParamsMetal, __integrator_state) +
+ const size_t pointer_block_end = offsetof(KernelParamsMetal, integrator_state) +
sizeof(IntegratorStateGPU);
for (size_t offset = 0; offset < pointer_block_end; offset += sizeof(device_ptr)) {
int pointer_index = int(offset / sizeof(device_ptr));
diff --git a/intern/cycles/device/optix/device.cpp b/intern/cycles/device/optix/device.cpp
index 70810bae10d..68ca21374fd 100644
--- a/intern/cycles/device/optix/device.cpp
+++ b/intern/cycles/device/optix/device.cpp
@@ -31,12 +31,12 @@ bool device_optix_init()
const OptixResult result = optixInit();
if (result == OPTIX_ERROR_UNSUPPORTED_ABI_VERSION) {
- VLOG(1) << "OptiX initialization failed because the installed NVIDIA driver is too old. "
- "Please update to the latest driver first!";
+ VLOG_WARNING << "OptiX initialization failed because the installed NVIDIA driver is too old. "
+ "Please update to the latest driver first!";
return false;
}
else if (result != OPTIX_SUCCESS) {
- VLOG(1) << "OptiX initialization failed with error code " << (unsigned int)result;
+ VLOG_WARNING << "OptiX initialization failed with error code " << (unsigned int)result;
return false;
}
diff --git a/intern/cycles/device/optix/device_impl.cpp b/intern/cycles/device/optix/device_impl.cpp
index 9ab9bbb59c5..e7dcc29a2da 100644
--- a/intern/cycles/device/optix/device_impl.cpp
+++ b/intern/cycles/device/optix/device_impl.cpp
@@ -246,7 +246,7 @@ OptiXDevice::Denoiser::Denoiser(OptiXDevice *device)
OptiXDevice::OptiXDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler)
: CUDADevice(info, stats, profiler),
sbt_data(this, "__sbt", MEM_READ_ONLY),
- launch_params(this, "__params", false),
+ launch_params(this, "kernel_params", false),
denoiser_(this)
{
/* Make the CUDA context current. */
@@ -278,7 +278,7 @@ OptiXDevice::OptiXDevice(const DeviceInfo &info, Stats &stats, Profiler &profile
};
# endif
if (DebugFlags().optix.use_debug) {
- VLOG(1) << "Using OptiX debug mode.";
+ VLOG_INFO << "Using OptiX debug mode.";
options.validationMode = OPTIX_DEVICE_CONTEXT_VALIDATION_MODE_ALL;
}
optix_assert(optixDeviceContextCreate(cuContext, &options, &context));
@@ -421,7 +421,7 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
pipeline_options.numPayloadValues = 8;
pipeline_options.numAttributeValues = 2; /* u, v */
pipeline_options.exceptionFlags = OPTIX_EXCEPTION_FLAG_NONE;
- pipeline_options.pipelineLaunchParamsVariableName = "__params"; /* See globals.h */
+ pipeline_options.pipelineLaunchParamsVariableName = "kernel_params"; /* See globals.h */
pipeline_options.usesPrimitiveTypeFlags = OPTIX_PRIMITIVE_TYPE_FLAGS_TRIANGLE;
if (kernel_features & KERNEL_FEATURE_HAIR) {
@@ -1392,11 +1392,11 @@ bool OptiXDevice::build_optix_bvh(BVHOptiX *bvh,
/* The build flags have to match the ones used to query the built-in curve intersection
program (see optixBuiltinISModuleGet above) */
build_input.type == OPTIX_BUILD_INPUT_TYPE_CURVES) {
- VLOG(2) << "Using fast to trace OptiX BVH";
+ VLOG_INFO << "Using fast to trace OptiX BVH";
options.buildFlags = OPTIX_BUILD_FLAG_PREFER_FAST_TRACE | OPTIX_BUILD_FLAG_ALLOW_COMPACTION;
}
else {
- VLOG(2) << "Using fast to update OptiX BVH";
+ VLOG_INFO << "Using fast to update OptiX BVH";
options.buildFlags = OPTIX_BUILD_FLAG_PREFER_FAST_BUILD | OPTIX_BUILD_FLAG_ALLOW_UPDATE;
}
@@ -2042,7 +2042,7 @@ void OptiXDevice::const_copy_to(const char *name, void *host, size_t size)
/* Set constant memory for CUDA module. */
CUDADevice::const_copy_to(name, host, size);
- if (strcmp(name, "__data") == 0) {
+ if (strcmp(name, "data") == 0) {
assert(size <= sizeof(KernelData));
/* Update traversable handle (since it is different for each device on multi devices). */
@@ -2054,14 +2054,14 @@ void OptiXDevice::const_copy_to(const char *name, void *host, size_t size)
}
/* Update data storage pointers in launch parameters. */
-# define KERNEL_TEX(data_type, tex_name) \
- if (strcmp(name, #tex_name) == 0) { \
- update_launch_params(offsetof(KernelParamsOptiX, tex_name), host, size); \
+# define KERNEL_DATA_ARRAY(data_type, data_name) \
+ if (strcmp(name, #data_name) == 0) { \
+ update_launch_params(offsetof(KernelParamsOptiX, data_name), host, size); \
return; \
}
- KERNEL_TEX(IntegratorStateGPU, __integrator_state)
-# include "kernel/textures.h"
-# undef KERNEL_TEX
+ KERNEL_DATA_ARRAY(IntegratorStateGPU, integrator_state)
+# include "kernel/data_arrays.h"
+# undef KERNEL_DATA_ARRAY
}
void OptiXDevice::update_launch_params(size_t offset, void *data, size_t data_size)
diff --git a/intern/cycles/device/queue.cpp b/intern/cycles/device/queue.cpp
index de65047ed6a..cc0cf0ccf84 100644
--- a/intern/cycles/device/queue.cpp
+++ b/intern/cycles/device/queue.cpp
@@ -19,7 +19,7 @@ DeviceQueue::DeviceQueue(Device *device)
DeviceQueue::~DeviceQueue()
{
- if (VLOG_IS_ON(3)) {
+ if (VLOG_DEVICE_STATS_IS_ON) {
/* Print kernel execution times sorted by time. */
vector<pair<DeviceKernelMask, double>> stats_sorted;
for (const auto &stat : stats_kernel_time_) {
@@ -32,17 +32,18 @@ DeviceQueue::~DeviceQueue()
return a.second > b.second;
});
- VLOG(3) << "GPU queue stats:";
+ VLOG_DEVICE_STATS << "GPU queue stats:";
for (const auto &[mask, time] : stats_sorted) {
- VLOG(3) << " " << std::setfill(' ') << std::setw(10) << std::fixed << std::setprecision(5)
- << std::right << time << "s: " << device_kernel_mask_as_string(mask);
+ VLOG_DEVICE_STATS << " " << std::setfill(' ') << std::setw(10) << std::fixed
+ << std::setprecision(5) << std::right << time
+ << "s: " << device_kernel_mask_as_string(mask);
}
}
}
void DeviceQueue::debug_init_execution()
{
- if (VLOG_IS_ON(3)) {
+ if (VLOG_DEVICE_STATS_IS_ON) {
last_sync_time_ = time_dt();
}
@@ -51,9 +52,9 @@ void DeviceQueue::debug_init_execution()
void DeviceQueue::debug_enqueue(DeviceKernel kernel, const int work_size)
{
- if (VLOG_IS_ON(3)) {
- VLOG(4) << "GPU queue launch " << device_kernel_as_string(kernel) << ", work_size "
- << work_size;
+ if (VLOG_DEVICE_STATS_IS_ON) {
+ VLOG_DEVICE_STATS << "GPU queue launch " << device_kernel_as_string(kernel) << ", work_size "
+ << work_size;
}
last_kernels_enqueued_ |= (uint64_t(1) << (uint64_t)kernel);
@@ -61,10 +62,10 @@ void DeviceQueue::debug_enqueue(DeviceKernel kernel, const int work_size)
void DeviceQueue::debug_synchronize()
{
- if (VLOG_IS_ON(3)) {
+ if (VLOG_DEVICE_STATS_IS_ON) {
const double new_time = time_dt();
const double elapsed_time = new_time - last_sync_time_;
- VLOG(4) << "GPU queue synchronize, elapsed " << std::setw(10) << elapsed_time << "s";
+ VLOG_DEVICE_STATS << "GPU queue synchronize, elapsed " << std::setw(10) << elapsed_time << "s";
stats_kernel_time_[last_kernels_enqueued_] += elapsed_time;
diff --git a/intern/cycles/integrator/denoiser.cpp b/intern/cycles/integrator/denoiser.cpp
index 23ab825a4d2..94991d63e4c 100644
--- a/intern/cycles/integrator/denoiser.cpp
+++ b/intern/cycles/integrator/denoiser.cpp
@@ -58,8 +58,8 @@ bool Denoiser::load_kernels(Progress *progress)
return false;
}
- VLOG(3) << "Will denoise on " << denoiser_device->info.description << " ("
- << denoiser_device->info.id << ")";
+ VLOG_WORK << "Will denoise on " << denoiser_device->info.description << " ("
+ << denoiser_device->info.id << ")";
return true;
}
diff --git a/intern/cycles/integrator/denoiser_device.cpp b/intern/cycles/integrator/denoiser_device.cpp
index 595397312b3..5414f9dfb1a 100644
--- a/intern/cycles/integrator/denoiser_device.cpp
+++ b/intern/cycles/integrator/denoiser_device.cpp
@@ -48,7 +48,7 @@ bool DeviceDenoiser::denoise_buffer(const BufferParams &buffer_params,
task.render_buffers = render_buffers;
}
else {
- VLOG(3) << "Creating temporary buffer on denoiser device.";
+ VLOG_WORK << "Creating temporary buffer on denoiser device.";
DeviceQueue *queue = denoiser_device->get_denoise_queue();
diff --git a/intern/cycles/integrator/denoiser_oidn.cpp b/intern/cycles/integrator/denoiser_oidn.cpp
index b074408e229..04e659a15e2 100644
--- a/intern/cycles/integrator/denoiser_oidn.cpp
+++ b/intern/cycles/integrator/denoiser_oidn.cpp
@@ -284,8 +284,8 @@ class OIDNDenoiseContext {
/* Read pass pixels using PassAccessor into a temporary buffer which is owned by the pass.. */
void read_pass_pixels_into_buffer(OIDNPass &oidn_pass)
{
- VLOG(3) << "Allocating temporary buffer for pass " << oidn_pass.name << " ("
- << pass_type_as_string(oidn_pass.type) << ")";
+ VLOG_WORK << "Allocating temporary buffer for pass " << oidn_pass.name << " ("
+ << pass_type_as_string(oidn_pass.type) << ")";
const int64_t width = buffer_params_.width;
const int64_t height = buffer_params_.height;
diff --git a/intern/cycles/integrator/path_trace.cpp b/intern/cycles/integrator/path_trace.cpp
index 36a0326e405..9ad1c465725 100644
--- a/intern/cycles/integrator/path_trace.cpp
+++ b/intern/cycles/integrator/path_trace.cpp
@@ -348,8 +348,8 @@ void PathTrace::path_trace(RenderWork &render_work)
return;
}
- VLOG(3) << "Will path trace " << render_work.path_trace.num_samples
- << " samples at the resolution divider " << render_work.resolution_divider;
+ VLOG_WORK << "Will path trace " << render_work.path_trace.num_samples
+ << " samples at the resolution divider " << render_work.resolution_divider;
const double start_time = time_dt();
@@ -373,9 +373,9 @@ void PathTrace::path_trace(RenderWork &render_work)
work_balance_infos_[i].time_spent += work_time;
work_balance_infos_[i].occupancy = statistics.occupancy;
- VLOG(3) << "Rendered " << num_samples << " samples in " << work_time << " seconds ("
- << work_time / num_samples
- << " seconds per sample), occupancy: " << statistics.occupancy;
+ VLOG_WORK << "Rendered " << num_samples << " samples in " << work_time << " seconds ("
+ << work_time / num_samples
+ << " seconds per sample), occupancy: " << statistics.occupancy;
});
float occupancy_accum = 0.0f;
@@ -398,10 +398,10 @@ void PathTrace::adaptive_sample(RenderWork &render_work)
bool did_reschedule_on_idle = false;
while (true) {
- VLOG(3) << "Will filter adaptive stopping buffer, threshold "
- << render_work.adaptive_sampling.threshold;
+ VLOG_WORK << "Will filter adaptive stopping buffer, threshold "
+ << render_work.adaptive_sampling.threshold;
if (render_work.adaptive_sampling.reset) {
- VLOG(3) << "Will re-calculate convergency flag for currently converged pixels.";
+ VLOG_WORK << "Will re-calculate convergency flag for currently converged pixels.";
}
const double start_time = time_dt();
@@ -420,11 +420,11 @@ void PathTrace::adaptive_sample(RenderWork &render_work)
render_work, time_dt() - start_time, is_cancel_requested());
if (num_active_pixels == 0) {
- VLOG(3) << "All pixels converged.";
+ VLOG_WORK << "All pixels converged.";
if (!render_scheduler_.render_work_reschedule_on_converge(render_work)) {
break;
}
- VLOG(3) << "Continuing with lower threshold.";
+ VLOG_WORK << "Continuing with lower threshold.";
}
else if (did_reschedule_on_idle) {
break;
@@ -436,10 +436,10 @@ void PathTrace::adaptive_sample(RenderWork &render_work)
* A better heuristic is possible here: for example, use maximum of 128^2 and percentage of
* the final resolution. */
if (!render_scheduler_.render_work_reschedule_on_idle(render_work)) {
- VLOG(3) << "Rescheduling is not possible: final threshold is reached.";
+ VLOG_WORK << "Rescheduling is not possible: final threshold is reached.";
break;
}
- VLOG(3) << "Rescheduling lower threshold.";
+ VLOG_WORK << "Rescheduling lower threshold.";
did_reschedule_on_idle = true;
}
else {
@@ -483,7 +483,7 @@ void PathTrace::cryptomatte_postprocess(const RenderWork &render_work)
if (!render_work.cryptomatte.postprocess) {
return;
}
- VLOG(3) << "Perform cryptomatte work.";
+ VLOG_WORK << "Perform cryptomatte work.";
parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
path_trace_work->cryptomatte_postproces();
@@ -501,7 +501,7 @@ void PathTrace::denoise(const RenderWork &render_work)
return;
}
- VLOG(3) << "Perform denoising work.";
+ VLOG_WORK << "Perform denoising work.";
const double start_time = time_dt();
@@ -599,26 +599,26 @@ void PathTrace::update_display(const RenderWork &render_work)
}
if (!display_ && !output_driver_) {
- VLOG(3) << "Ignore display update.";
+ VLOG_WORK << "Ignore display update.";
return;
}
if (full_params_.width == 0 || full_params_.height == 0) {
- VLOG(3) << "Skipping PathTraceDisplay update due to 0 size of the render buffer.";
+ VLOG_WORK << "Skipping PathTraceDisplay update due to 0 size of the render buffer.";
return;
}
const double start_time = time_dt();
if (output_driver_) {
- VLOG(3) << "Invoke buffer update callback.";
+ VLOG_WORK << "Invoke buffer update callback.";
PathTraceTile tile(*this);
output_driver_->update_render_tile(tile);
}
if (display_) {
- VLOG(3) << "Perform copy to GPUDisplay work.";
+ VLOG_WORK << "Perform copy to GPUDisplay work.";
const int texture_width = render_state_.effective_big_tile_params.window_width;
const int texture_height = render_state_.effective_big_tile_params.window_height;
@@ -654,33 +654,33 @@ void PathTrace::rebalance(const RenderWork &render_work)
const int num_works = path_trace_works_.size();
if (num_works == 1) {
- VLOG(3) << "Ignoring rebalance work due to single device render.";
+ VLOG_WORK << "Ignoring rebalance work due to single device render.";
return;
}
const double start_time = time_dt();
if (VLOG_IS_ON(3)) {
- VLOG(3) << "Perform rebalance work.";
- VLOG(3) << "Per-device path tracing time (seconds):";
+ VLOG_WORK << "Perform rebalance work.";
+ VLOG_WORK << "Per-device path tracing time (seconds):";
for (int i = 0; i < num_works; ++i) {
- VLOG(3) << path_trace_works_[i]->get_device()->info.description << ": "
- << work_balance_infos_[i].time_spent;
+ VLOG_WORK << path_trace_works_[i]->get_device()->info.description << ": "
+ << work_balance_infos_[i].time_spent;
}
}
const bool did_rebalance = work_balance_do_rebalance(work_balance_infos_);
if (VLOG_IS_ON(3)) {
- VLOG(3) << "Calculated per-device weights for works:";
+ VLOG_WORK << "Calculated per-device weights for works:";
for (int i = 0; i < num_works; ++i) {
- VLOG(3) << path_trace_works_[i]->get_device()->info.description << ": "
- << work_balance_infos_[i].weight;
+ VLOG_WORK << path_trace_works_[i]->get_device()->info.description << ": "
+ << work_balance_infos_[i].weight;
}
}
if (!did_rebalance) {
- VLOG(3) << "Balance in path trace works did not change.";
+ VLOG_WORK << "Balance in path trace works did not change.";
render_scheduler_.report_rebalance_time(render_work, time_dt() - start_time, false);
return;
}
@@ -704,7 +704,7 @@ void PathTrace::write_tile_buffer(const RenderWork &render_work)
return;
}
- VLOG(3) << "Write tile result.";
+ VLOG_WORK << "Write tile result.";
render_state_.tile_written = true;
@@ -718,14 +718,14 @@ void PathTrace::write_tile_buffer(const RenderWork &render_work)
*
* Important thing is: tile should be written to the software via callback only once. */
if (!has_multiple_tiles) {
- VLOG(3) << "Write tile result via buffer write callback.";
+ VLOG_WORK << "Write tile result via buffer write callback.";
tile_buffer_write();
}
/* Write tile to disk, so that the render work's render buffer can be re-used for the next tile.
*/
if (has_multiple_tiles) {
- VLOG(3) << "Write tile result into .";
+ VLOG_WORK << "Write tile result into .";
tile_buffer_write_to_disk();
}
}
@@ -736,10 +736,10 @@ void PathTrace::finalize_full_buffer_on_disk(const RenderWork &render_work)
return;
}
- VLOG(3) << "Handle full-frame render buffer work.";
+ VLOG_WORK << "Handle full-frame render buffer work.";
if (!tile_manager_.has_written_tiles()) {
- VLOG(3) << "No tiles on disk.";
+ VLOG_WORK << "No tiles on disk.";
return;
}
@@ -935,7 +935,7 @@ static string get_layer_view_name(const RenderBuffers &buffers)
void PathTrace::process_full_buffer_from_disk(string_view filename)
{
- VLOG(3) << "Processing full frame buffer file " << filename;
+ VLOG_WORK << "Processing full frame buffer file " << filename;
progress_set_status("Reading full buffer from disk");
diff --git a/intern/cycles/integrator/path_trace_work_gpu.cpp b/intern/cycles/integrator/path_trace_work_gpu.cpp
index ede81705ae8..e262c252ce3 100644
--- a/intern/cycles/integrator/path_trace_work_gpu.cpp
+++ b/intern/cycles/integrator/path_trace_work_gpu.cpp
@@ -152,7 +152,7 @@ void PathTraceWorkGPU::alloc_integrator_soa()
total_soa_size += soa_memory->memory_size();
}
- VLOG(3) << "GPU SoA state size: " << string_human_readable_size(total_soa_size);
+ VLOG_DEVICE_STATS << "GPU SoA state size: " << string_human_readable_size(total_soa_size);
}
}
@@ -239,7 +239,7 @@ void PathTraceWorkGPU::init_execution()
/* Copy to device side struct in constant memory. */
device_->const_copy_to(
- "__integrator_state", &integrator_state_gpu_, sizeof(integrator_state_gpu_));
+ "integrator_state", &integrator_state_gpu_, sizeof(integrator_state_gpu_));
}
void PathTraceWorkGPU::render_samples(RenderStatistics &statistics,
@@ -820,10 +820,10 @@ bool PathTraceWorkGPU::should_use_graphics_interop()
interop_use_ = device->should_use_graphics_interop();
if (interop_use_) {
- VLOG(2) << "Using graphics interop GPU display update.";
+ VLOG_INFO << "Using graphics interop GPU display update.";
}
else {
- VLOG(2) << "Using naive GPU display update.";
+ VLOG_INFO << "Using naive GPU display update.";
}
interop_use_checked_ = true;
diff --git a/intern/cycles/integrator/render_scheduler.cpp b/intern/cycles/integrator/render_scheduler.cpp
index ebc3170393f..e4676bd059c 100644
--- a/intern/cycles/integrator/render_scheduler.cpp
+++ b/intern/cycles/integrator/render_scheduler.cpp
@@ -225,7 +225,7 @@ bool RenderScheduler::render_work_reschedule_on_idle(RenderWork &render_work)
void RenderScheduler::render_work_reschedule_on_cancel(RenderWork &render_work)
{
- VLOG(3) << "Schedule work for cancel.";
+ VLOG_WORK << "Schedule work for cancel.";
/* Un-schedule samples: they will not be rendered and should not be counted. */
state_.num_rendered_samples -= render_work.path_trace.num_samples;
@@ -475,14 +475,14 @@ void RenderScheduler::report_path_trace_time(const RenderWork &render_work,
path_trace_time_.add_average(final_time_approx, render_work.path_trace.num_samples);
- VLOG(4) << "Average path tracing time: " << path_trace_time_.get_average() << " seconds.";
+ VLOG_WORK << "Average path tracing time: " << path_trace_time_.get_average() << " seconds.";
}
void RenderScheduler::report_path_trace_occupancy(const RenderWork &render_work, float occupancy)
{
state_.occupancy_num_samples = render_work.path_trace.num_samples;
state_.occupancy = occupancy;
- VLOG(4) << "Measured path tracing occupancy: " << occupancy;
+ VLOG_WORK << "Measured path tracing occupancy: " << occupancy;
}
void RenderScheduler::report_adaptive_filter_time(const RenderWork &render_work,
@@ -503,8 +503,8 @@ void RenderScheduler::report_adaptive_filter_time(const RenderWork &render_work,
adaptive_filter_time_.add_average(final_time_approx, render_work.path_trace.num_samples);
- VLOG(4) << "Average adaptive sampling filter time: " << adaptive_filter_time_.get_average()
- << " seconds.";
+ VLOG_WORK << "Average adaptive sampling filter time: " << adaptive_filter_time_.get_average()
+ << " seconds.";
}
void RenderScheduler::report_denoise_time(const RenderWork &render_work, double time)
@@ -523,7 +523,7 @@ void RenderScheduler::report_denoise_time(const RenderWork &render_work, double
denoise_time_.add_average(final_time_approx);
- VLOG(4) << "Average denoising time: " << denoise_time_.get_average() << " seconds.";
+ VLOG_WORK << "Average denoising time: " << denoise_time_.get_average() << " seconds.";
}
void RenderScheduler::report_display_update_time(const RenderWork &render_work, double time)
@@ -542,7 +542,8 @@ void RenderScheduler::report_display_update_time(const RenderWork &render_work,
display_update_time_.add_average(final_time_approx);
- VLOG(4) << "Average display update time: " << display_update_time_.get_average() << " seconds.";
+ VLOG_WORK << "Average display update time: " << display_update_time_.get_average()
+ << " seconds.";
/* Move the display update moment further in time, so that logic which checks when last update
* did happen have more reliable point in time (without path tracing and denoising parts of the
@@ -568,7 +569,7 @@ void RenderScheduler::report_rebalance_time(const RenderWork &render_work,
state_.last_rebalance_changed = balance_changed;
- VLOG(4) << "Average rebalance time: " << rebalance_time_.get_average() << " seconds.";
+ VLOG_WORK << "Average rebalance time: " << rebalance_time_.get_average() << " seconds.";
}
string RenderScheduler::full_report() const
@@ -1063,7 +1064,7 @@ void RenderScheduler::update_start_resolution_divider()
/* Resolution divider has never been calculated before: use default resolution, so that we have
* somewhat good initial behavior, giving a chance to collect real numbers. */
start_resolution_divider_ = default_start_resolution_divider_;
- VLOG(3) << "Initial resolution divider is " << start_resolution_divider_;
+ VLOG_WORK << "Initial resolution divider is " << start_resolution_divider_;
return;
}
@@ -1092,7 +1093,7 @@ void RenderScheduler::update_start_resolution_divider()
* simple and compute device is fast). */
start_resolution_divider_ = max(resolution_divider_for_update, pixel_size_);
- VLOG(3) << "Calculated resolution divider is " << start_resolution_divider_;
+ VLOG_WORK << "Calculated resolution divider is " << start_resolution_divider_;
}
double RenderScheduler::guess_viewport_navigation_update_interval_in_seconds() const
diff --git a/intern/cycles/integrator/shader_eval.cpp b/intern/cycles/integrator/shader_eval.cpp
index 92b9d1c662d..b1450732f5c 100644
--- a/intern/cycles/integrator/shader_eval.cpp
+++ b/intern/cycles/integrator/shader_eval.cpp
@@ -31,8 +31,8 @@ bool ShaderEval::eval(const ShaderEvalType type,
device_->foreach_device([&](Device *device) {
if (!first_device) {
- LOG(ERROR) << "Multi-devices are not yet fully implemented, will evaluate shader on a "
- "single device.";
+ VLOG_WORK << "Multi-devices are not yet fully implemented, will evaluate shader on a "
+ "single device.";
return;
}
first_device = false;
diff --git a/intern/cycles/integrator/work_tile_scheduler.cpp b/intern/cycles/integrator/work_tile_scheduler.cpp
index 6dc511064c9..4bc8c0c4396 100644
--- a/intern/cycles/integrator/work_tile_scheduler.cpp
+++ b/intern/cycles/integrator/work_tile_scheduler.cpp
@@ -55,7 +55,7 @@ void WorkTileScheduler::reset_scheduler_state()
tile_size_ = tile_calculate_best_size(
accelerated_rt_, image_size_px_, samples_num_, max_num_path_states_, scrambling_distance_);
- VLOG(3) << "Will schedule tiles of size " << tile_size_;
+ VLOG_WORK << "Will schedule tiles of size " << tile_size_;
if (VLOG_IS_ON(3)) {
/* The logging is based on multiple tiles scheduled, ignoring overhead of multi-tile scheduling
@@ -63,8 +63,8 @@ void WorkTileScheduler::reset_scheduler_state()
const int num_path_states_in_tile = tile_size_.width * tile_size_.height *
tile_size_.num_samples;
const int num_tiles = max_num_path_states_ / num_path_states_in_tile;
- VLOG(3) << "Number of unused path states: "
- << max_num_path_states_ - num_tiles * num_path_states_in_tile;
+ VLOG_WORK << "Number of unused path states: "
+ << max_num_path_states_ - num_tiles * num_path_states_in_tile;
}
num_tiles_x_ = divide_up(image_size_px_.x, tile_size_.width);
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 473bdb67920..a07d7852211 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -267,8 +267,8 @@ set(SRC_KERNEL_UTIL_HEADERS
)
set(SRC_KERNEL_TYPES_HEADERS
+ data_arrays.h
tables.h
- textures.h
types.h
)
diff --git a/intern/cycles/kernel/bvh/bvh.h b/intern/cycles/kernel/bvh/bvh.h
index 04ccb7ceff5..a1d0e307170 100644
--- a/intern/cycles/kernel/bvh/bvh.h
+++ b/intern/cycles/kernel/bvh/bvh.h
@@ -452,7 +452,7 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals kg,
# ifdef __EMBREE__
if (kernel_data.bvh.scene) {
- const bool has_bvh = !(kernel_tex_fetch(__object_flag, local_object) &
+ const bool has_bvh = !(kernel_data_fetch(object_flag, local_object) &
SD_OBJECT_TRANSFORM_APPLIED);
CCLIntersectContext ctx(
kg, has_bvh ? CCLIntersectContext::RAY_SSS : CCLIntersectContext::RAY_LOCAL);
diff --git a/intern/cycles/kernel/bvh/embree.h b/intern/cycles/kernel/bvh/embree.h
index 4f7e6435daf..1c6b9bc1e62 100644
--- a/intern/cycles/kernel/bvh/embree.h
+++ b/intern/cycles/kernel/bvh/embree.h
@@ -146,14 +146,14 @@ ccl_device_inline void kernel_embree_convert_hit(KernelGlobals kg,
const bool is_hair = hit->geomID & 1;
if (is_hair) {
- const KernelCurveSegment segment = kernel_tex_fetch(__curve_segments, isect->prim);
+ const KernelCurveSegment segment = kernel_data_fetch(curve_segments, isect->prim);
isect->type = segment.type;
isect->prim = segment.prim;
isect->u = hit->u;
isect->v = hit->v;
}
else {
- isect->type = kernel_tex_fetch(__objects, isect->object).primitive_type;
+ isect->type = kernel_data_fetch(objects, isect->object).primitive_type;
isect->u = 1.0f - hit->v - hit->u;
isect->v = hit->u;
}
@@ -170,7 +170,7 @@ ccl_device_inline void kernel_embree_convert_sss_hit(
isect->prim = hit->primID +
(intptr_t)rtcGetGeometryUserData(rtcGetGeometry(inst_scene, hit->geomID));
isect->object = object;
- isect->type = kernel_tex_fetch(__objects, object).primitive_type;
+ isect->type = kernel_data_fetch(objects, object).primitive_type;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/bvh/local.h b/intern/cycles/kernel/bvh/local.h
index 0d05e09d75f..3b6b30ea93d 100644
--- a/intern/cycles/kernel/bvh/local.h
+++ b/intern/cycles/kernel/bvh/local.h
@@ -41,7 +41,7 @@ ccl_device_inline
/* traversal variables in registers */
int stack_ptr = 0;
- int node_addr = kernel_tex_fetch(__object_node, local_object);
+ int node_addr = kernel_data_fetch(object_node, local_object);
/* ray parameters in registers */
float3 P = ray->P;
@@ -55,7 +55,7 @@ ccl_device_inline
}
kernel_assert((local_isect == NULL) == (max_hits == 0));
- const int object_flag = kernel_tex_fetch(__object_flag, local_object);
+ const int object_flag = kernel_data_fetch(object_flag, local_object);
if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
#if BVH_FEATURE(BVH_MOTION)
Transform ob_itfm;
@@ -73,7 +73,7 @@ ccl_device_inline
while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
int node_addr_child1, traverse_mask;
float dist[2];
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ float4 cnodes = kernel_data_fetch(bvh_nodes, node_addr + 0);
traverse_mask = NODE_INTERSECT(kg,
P,
@@ -117,7 +117,7 @@ ccl_device_inline
/* if node is leaf, fetch triangle list */
if (node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
+ float4 leaf = kernel_data_fetch(bvh_leaf_nodes, (-node_addr - 1));
int prim_addr = __float_as_int(leaf.x);
const int prim_addr2 = __float_as_int(leaf.y);
@@ -132,18 +132,18 @@ ccl_device_inline
case PRIMITIVE_TRIANGLE: {
/* intersect ray against primitive */
for (; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ kernel_assert(kernel_data_fetch(prim_type, prim_addr) == type);
/* Only intersect with matching object, for instanced objects we
* already know we are only intersecting the right object. */
if (object == OBJECT_NONE) {
- if (kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
+ if (kernel_data_fetch(prim_object, prim_addr) != local_object) {
continue;
}
}
/* Skip self intersection. */
- const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+ const int prim = kernel_data_fetch(prim_index, prim_addr);
if (intersection_skip_self_local(ray->self, prim)) {
continue;
}
@@ -167,18 +167,18 @@ ccl_device_inline
case PRIMITIVE_MOTION_TRIANGLE: {
/* intersect ray against primitive */
for (; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ kernel_assert(kernel_data_fetch(prim_type, prim_addr) == type);
/* Only intersect with matching object, for instanced objects we
* already know we are only intersecting the right object. */
if (object == OBJECT_NONE) {
- if (kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
+ if (kernel_data_fetch(prim_object, prim_addr) != local_object) {
continue;
}
}
/* Skip self intersection. */
- const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+ const int prim = kernel_data_fetch(prim_index, prim_addr);
if (intersection_skip_self_local(ray->self, prim)) {
continue;
}
diff --git a/intern/cycles/kernel/bvh/nodes.h b/intern/cycles/kernel/bvh/nodes.h
index fd475dcd5e9..c19dea9223b 100644
--- a/intern/cycles/kernel/bvh/nodes.h
+++ b/intern/cycles/kernel/bvh/nodes.h
@@ -9,9 +9,9 @@ ccl_device_forceinline Transform bvh_unaligned_node_fetch_space(KernelGlobals kg
{
Transform space;
const int child_addr = node_addr + child * 3;
- space.x = kernel_tex_fetch(__bvh_nodes, child_addr + 1);
- space.y = kernel_tex_fetch(__bvh_nodes, child_addr + 2);
- space.z = kernel_tex_fetch(__bvh_nodes, child_addr + 3);
+ space.x = kernel_data_fetch(bvh_nodes, child_addr + 1);
+ space.y = kernel_data_fetch(bvh_nodes, child_addr + 2);
+ space.z = kernel_data_fetch(bvh_nodes, child_addr + 3);
return space;
}
@@ -26,11 +26,11 @@ ccl_device_forceinline int bvh_aligned_node_intersect(KernelGlobals kg,
/* fetch node data */
#ifdef __VISIBILITY_FLAG__
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ float4 cnodes = kernel_data_fetch(bvh_nodes, node_addr + 0);
#endif
- float4 node0 = kernel_tex_fetch(__bvh_nodes, node_addr + 1);
- float4 node1 = kernel_tex_fetch(__bvh_nodes, node_addr + 2);
- float4 node2 = kernel_tex_fetch(__bvh_nodes, node_addr + 3);
+ float4 node0 = kernel_data_fetch(bvh_nodes, node_addr + 1);
+ float4 node1 = kernel_data_fetch(bvh_nodes, node_addr + 2);
+ float4 node2 = kernel_data_fetch(bvh_nodes, node_addr + 3);
/* intersect ray against child nodes */
float c0lox = (node0.x - P.x) * idir.x;
@@ -100,7 +100,7 @@ ccl_device_forceinline int bvh_unaligned_node_intersect(KernelGlobals kg,
{
int mask = 0;
#ifdef __VISIBILITY_FLAG__
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ float4 cnodes = kernel_data_fetch(bvh_nodes, node_addr + 0);
#endif
if (bvh_unaligned_node_intersect_child(kg, P, dir, t, node_addr, 0, &dist[0])) {
#ifdef __VISIBILITY_FLAG__
@@ -130,7 +130,7 @@ ccl_device_forceinline int bvh_node_intersect(KernelGlobals kg,
const uint visibility,
float dist[2])
{
- float4 node = kernel_tex_fetch(__bvh_nodes, node_addr);
+ float4 node = kernel_data_fetch(bvh_nodes, node_addr);
if (__float_as_uint(node.x) & PATH_RAY_NODE_UNALIGNED) {
return bvh_unaligned_node_intersect(kg, P, dir, idir, t, node_addr, visibility, dist);
}
diff --git a/intern/cycles/kernel/bvh/shadow_all.h b/intern/cycles/kernel/bvh/shadow_all.h
index 2f58929c1e5..e86fe867eac 100644
--- a/intern/cycles/kernel/bvh/shadow_all.h
+++ b/intern/cycles/kernel/bvh/shadow_all.h
@@ -80,7 +80,7 @@ ccl_device_inline
while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
int node_addr_child1, traverse_mask;
float dist[2];
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ float4 cnodes = kernel_data_fetch(bvh_nodes, node_addr + 0);
traverse_mask = NODE_INTERSECT(kg,
P,
@@ -124,7 +124,7 @@ ccl_device_inline
/* if node is leaf, fetch triangle list */
if (node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
+ float4 leaf = kernel_data_fetch(bvh_leaf_nodes, (-node_addr - 1));
int prim_addr = __float_as_int(leaf.x);
if (prim_addr >= 0) {
@@ -137,7 +137,7 @@ ccl_device_inline
/* primitive intersection */
for (; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) ==
+ kernel_assert((kernel_data_fetch(prim_type, prim_addr) & PRIMITIVE_ALL) ==
(type & PRIMITIVE_ALL));
bool hit;
@@ -147,9 +147,9 @@ ccl_device_inline
Intersection isect ccl_optional_struct_init;
const int prim_object = (object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, prim_addr) :
+ kernel_data_fetch(prim_object, prim_addr) :
object;
- const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+ const int prim = kernel_data_fetch(prim_index, prim_addr);
if (intersection_skip_self_shadow(ray->self, prim_object, prim)) {
continue;
}
@@ -181,14 +181,14 @@ ccl_device_inline
case PRIMITIVE_CURVE_RIBBON:
case PRIMITIVE_MOTION_CURVE_RIBBON: {
if ((type & PRIMITIVE_MOTION) && kernel_data.bvh.use_bvh_steps) {
- const float2 prim_time = kernel_tex_fetch(__prim_time, prim_addr);
+ const float2 prim_time = kernel_data_fetch(prim_time, prim_addr);
if (ray->time < prim_time.x || ray->time > prim_time.y) {
hit = false;
break;
}
}
- const int curve_type = kernel_tex_fetch(__prim_type, prim_addr);
+ const int curve_type = kernel_data_fetch(prim_type, prim_addr);
hit = curve_intersect(
kg, &isect, P, dir, t_max_current, prim_object, prim, ray->time, curve_type);
@@ -199,14 +199,14 @@ ccl_device_inline
case PRIMITIVE_POINT:
case PRIMITIVE_MOTION_POINT: {
if ((type & PRIMITIVE_MOTION) && kernel_data.bvh.use_bvh_steps) {
- const float2 prim_time = kernel_tex_fetch(__prim_time, prim_addr);
+ const float2 prim_time = kernel_data_fetch(prim_time, prim_addr);
if (ray->time < prim_time.x || ray->time > prim_time.y) {
hit = false;
break;
}
}
- const int point_type = kernel_tex_fetch(__prim_type, prim_addr);
+ const int point_type = kernel_data_fetch(prim_type, prim_addr);
hit = point_intersect(
kg, &isect, P, dir, t_max_current, prim_object, prim, ray->time, point_type);
break;
@@ -291,7 +291,7 @@ ccl_device_inline
}
else {
/* instance push */
- object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
+ object = kernel_data_fetch(prim_object, -prim_addr - 1);
#if BVH_FEATURE(BVH_MOTION)
t_world_to_instance = bvh_instance_motion_push(
@@ -307,7 +307,7 @@ ccl_device_inline
kernel_assert(stack_ptr < BVH_STACK_SIZE);
traversal_stack[stack_ptr] = ENTRYPOINT_SENTINEL;
- node_addr = kernel_tex_fetch(__object_node, object);
+ node_addr = kernel_data_fetch(object_node, object);
}
}
} while (node_addr != ENTRYPOINT_SENTINEL);
diff --git a/intern/cycles/kernel/bvh/traversal.h b/intern/cycles/kernel/bvh/traversal.h
index 1181d4bfdee..784fbf4fd11 100644
--- a/intern/cycles/kernel/bvh/traversal.h
+++ b/intern/cycles/kernel/bvh/traversal.h
@@ -62,7 +62,7 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
int node_addr_child1, traverse_mask;
float dist[2];
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ float4 cnodes = kernel_data_fetch(bvh_nodes, node_addr + 0);
{
traverse_mask = NODE_INTERSECT(kg,
@@ -108,7 +108,7 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
/* if node is leaf, fetch triangle list */
if (node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
+ float4 leaf = kernel_data_fetch(bvh_leaf_nodes, (-node_addr - 1));
int prim_addr = __float_as_int(leaf.x);
if (prim_addr >= 0) {
@@ -121,12 +121,12 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
/* primitive intersection */
for (; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ kernel_assert(kernel_data_fetch(prim_type, prim_addr) == type);
const int prim_object = (object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, prim_addr) :
+ kernel_data_fetch(prim_object, prim_addr) :
object;
- const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+ const int prim = kernel_data_fetch(prim_index, prim_addr);
if (intersection_skip_self_shadow(ray->self, prim_object, prim)) {
continue;
}
@@ -166,13 +166,13 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
case PRIMITIVE_CURVE_RIBBON:
case PRIMITIVE_MOTION_CURVE_RIBBON: {
if ((type & PRIMITIVE_MOTION) && kernel_data.bvh.use_bvh_steps) {
- const float2 prim_time = kernel_tex_fetch(__prim_time, prim_addr);
+ const float2 prim_time = kernel_data_fetch(prim_time, prim_addr);
if (ray->time < prim_time.x || ray->time > prim_time.y) {
break;
}
}
- const int curve_type = kernel_tex_fetch(__prim_type, prim_addr);
+ const int curve_type = kernel_data_fetch(prim_type, prim_addr);
const bool hit = curve_intersect(
kg, isect, P, dir, isect->t, prim_object, prim, ray->time, curve_type);
if (hit) {
@@ -187,13 +187,13 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
case PRIMITIVE_POINT:
case PRIMITIVE_MOTION_POINT: {
if ((type & PRIMITIVE_MOTION) && kernel_data.bvh.use_bvh_steps) {
- const float2 prim_time = kernel_tex_fetch(__prim_time, prim_addr);
+ const float2 prim_time = kernel_data_fetch(prim_time, prim_addr);
if (ray->time < prim_time.x || ray->time > prim_time.y) {
break;
}
}
- const int point_type = kernel_tex_fetch(__prim_type, prim_addr);
+ const int point_type = kernel_data_fetch(prim_type, prim_addr);
const bool hit = point_intersect(
kg, isect, P, dir, isect->t, prim_object, prim, ray->time, point_type);
if (hit) {
@@ -209,7 +209,7 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
}
else {
/* instance push */
- object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
+ object = kernel_data_fetch(prim_object, -prim_addr - 1);
#if BVH_FEATURE(BVH_MOTION)
isect->t *= bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &ob_itfm);
@@ -221,7 +221,7 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
kernel_assert(stack_ptr < BVH_STACK_SIZE);
traversal_stack[stack_ptr] = ENTRYPOINT_SENTINEL;
- node_addr = kernel_tex_fetch(__object_node, object);
+ node_addr = kernel_data_fetch(object_node, object);
}
}
} while (node_addr != ENTRYPOINT_SENTINEL);
diff --git a/intern/cycles/kernel/bvh/util.h b/intern/cycles/kernel/bvh/util.h
index 71045157372..572e023db25 100644
--- a/intern/cycles/kernel/bvh/util.h
+++ b/intern/cycles/kernel/bvh/util.h
@@ -53,20 +53,20 @@ ccl_device_forceinline int intersection_get_shader_flags(KernelGlobals kg,
int shader = 0;
if (type & PRIMITIVE_TRIANGLE) {
- shader = kernel_tex_fetch(__tri_shader, prim);
+ shader = kernel_data_fetch(tri_shader, prim);
}
#ifdef __POINTCLOUD__
else if (type & PRIMITIVE_POINT) {
- shader = kernel_tex_fetch(__points_shader, prim);
+ shader = kernel_data_fetch(points_shader, prim);
}
#endif
#ifdef __HAIR__
else if (type & PRIMITIVE_CURVE) {
- shader = kernel_tex_fetch(__curves, prim).shader_id;
+ shader = kernel_data_fetch(curves, prim).shader_id;
}
#endif
- return kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
+ return kernel_data_fetch(shaders, (shader & SHADER_MASK)).flags;
}
ccl_device_forceinline int intersection_get_shader_from_isect_prim(KernelGlobals kg,
@@ -76,16 +76,16 @@ ccl_device_forceinline int intersection_get_shader_from_isect_prim(KernelGlobals
int shader = 0;
if (isect_type & PRIMITIVE_TRIANGLE) {
- shader = kernel_tex_fetch(__tri_shader, prim);
+ shader = kernel_data_fetch(tri_shader, prim);
}
#ifdef __POINTCLOUD__
else if (isect_type & PRIMITIVE_POINT) {
- shader = kernel_tex_fetch(__points_shader, prim);
+ shader = kernel_data_fetch(points_shader, prim);
}
#endif
#ifdef __HAIR__
else if (isect_type & PRIMITIVE_CURVE) {
- shader = kernel_tex_fetch(__curves, prim).shader_id;
+ shader = kernel_data_fetch(curves, prim).shader_id;
}
#endif
@@ -101,7 +101,7 @@ ccl_device_forceinline int intersection_get_shader(
ccl_device_forceinline int intersection_get_object_flags(
KernelGlobals kg, ccl_private const Intersection *ccl_restrict isect)
{
- return kernel_tex_fetch(__object_flag, isect->object);
+ return kernel_data_fetch(object_flag, isect->object);
}
/* TODO: find a better (faster) solution for this. Maybe store offset per object for
@@ -110,27 +110,27 @@ ccl_device_inline int intersection_find_attribute(KernelGlobals kg,
const int object,
const uint id)
{
- uint attr_offset = kernel_tex_fetch(__objects, object).attribute_map_offset;
- uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ uint attr_offset = kernel_data_fetch(objects, object).attribute_map_offset;
+ AttributeMap attr_map = kernel_data_fetch(attributes_map, attr_offset);
- while (attr_map.x != id) {
- if (UNLIKELY(attr_map.x == ATTR_STD_NONE)) {
- if (UNLIKELY(attr_map.y == 0)) {
+ while (attr_map.id != id) {
+ if (UNLIKELY(attr_map.id == ATTR_STD_NONE)) {
+ if (UNLIKELY(attr_map.element == 0)) {
return (int)ATTR_STD_NOT_FOUND;
}
else {
/* Chain jump to a different part of the table. */
- attr_offset = attr_map.z;
+ attr_offset = attr_map.offset;
}
}
else {
attr_offset += ATTR_PRIM_TYPES;
}
- attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ attr_map = kernel_data_fetch(attributes_map, attr_offset);
}
/* return result */
- return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
+ return (attr_map.element == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.offset;
}
/* Transparent Shadows */
@@ -151,12 +151,12 @@ ccl_device_inline float intersection_curve_shadow_transparency(KernelGlobals kg,
}
/* Interpolate transparency between curve keys. */
- const KernelCurve kcurve = kernel_tex_fetch(__curves, prim);
+ const KernelCurve kcurve = kernel_data_fetch(curves, prim);
const int k0 = kcurve.first_key + PRIMITIVE_UNPACK_SEGMENT(kcurve.type);
const int k1 = k0 + 1;
- const float f0 = kernel_tex_fetch(__attributes_float, offset + k0);
- const float f1 = kernel_tex_fetch(__attributes_float, offset + k1);
+ const float f0 = kernel_data_fetch(attributes_float, offset + k0);
+ const float f1 = kernel_data_fetch(attributes_float, offset + k1);
return (1.0f - u) * f0 + u * f1;
}
diff --git a/intern/cycles/kernel/bvh/volume.h b/intern/cycles/kernel/bvh/volume.h
index d711b3abbf4..9715712a8f2 100644
--- a/intern/cycles/kernel/bvh/volume.h
+++ b/intern/cycles/kernel/bvh/volume.h
@@ -65,7 +65,7 @@ ccl_device_inline
while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
int node_addr_child1, traverse_mask;
float dist[2];
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ float4 cnodes = kernel_data_fetch(bvh_nodes, node_addr + 0);
traverse_mask = NODE_INTERSECT(kg,
P,
@@ -109,7 +109,7 @@ ccl_device_inline
/* if node is leaf, fetch triangle list */
if (node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
+ float4 leaf = kernel_data_fetch(bvh_leaf_nodes, (-node_addr - 1));
int prim_addr = __float_as_int(leaf.x);
if (prim_addr >= 0) {
@@ -125,17 +125,17 @@ ccl_device_inline
case PRIMITIVE_TRIANGLE: {
/* intersect ray against primitive */
for (; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ kernel_assert(kernel_data_fetch(prim_type, prim_addr) == type);
/* only primitives from volume object */
const int prim_object = (object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, prim_addr) :
+ kernel_data_fetch(prim_object, prim_addr) :
object;
- const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+ const int prim = kernel_data_fetch(prim_index, prim_addr);
if (intersection_skip_self(ray->self, prim_object, prim)) {
continue;
}
- int object_flag = kernel_tex_fetch(__object_flag, prim_object);
+ int object_flag = kernel_data_fetch(object_flag, prim_object);
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
continue;
}
@@ -148,16 +148,16 @@ ccl_device_inline
case PRIMITIVE_MOTION_TRIANGLE: {
/* intersect ray against primitive */
for (; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ kernel_assert(kernel_data_fetch(prim_type, prim_addr) == type);
/* only primitives from volume object */
const int prim_object = (object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, prim_addr) :
+ kernel_data_fetch(prim_object, prim_addr) :
object;
- const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+ const int prim = kernel_data_fetch(prim_index, prim_addr);
if (intersection_skip_self(ray->self, prim_object, prim)) {
continue;
}
- int object_flag = kernel_tex_fetch(__object_flag, prim_object);
+ int object_flag = kernel_data_fetch(object_flag, prim_object);
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
continue;
}
@@ -182,8 +182,8 @@ ccl_device_inline
}
else {
/* instance push */
- object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
- int object_flag = kernel_tex_fetch(__object_flag, object);
+ object = kernel_data_fetch(prim_object, -prim_addr - 1);
+ int object_flag = kernel_data_fetch(object_flag, object);
if (object_flag & SD_OBJECT_HAS_VOLUME) {
#if BVH_FEATURE(BVH_MOTION)
isect->t *= bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &ob_itfm);
@@ -195,7 +195,7 @@ ccl_device_inline
kernel_assert(stack_ptr < BVH_STACK_SIZE);
traversal_stack[stack_ptr] = ENTRYPOINT_SENTINEL;
- node_addr = kernel_tex_fetch(__object_node, object);
+ node_addr = kernel_data_fetch(object_node, object);
}
else {
/* pop */
diff --git a/intern/cycles/kernel/bvh/volume_all.h b/intern/cycles/kernel/bvh/volume_all.h
index a969bae14a1..d06ea8fe557 100644
--- a/intern/cycles/kernel/bvh/volume_all.h
+++ b/intern/cycles/kernel/bvh/volume_all.h
@@ -67,7 +67,7 @@ ccl_device_inline
while (node_addr >= 0 && node_addr != ENTRYPOINT_SENTINEL) {
int node_addr_child1, traverse_mask;
float dist[2];
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, node_addr + 0);
+ float4 cnodes = kernel_data_fetch(bvh_nodes, node_addr + 0);
traverse_mask = NODE_INTERSECT(kg,
P,
@@ -111,7 +111,7 @@ ccl_device_inline
/* if node is leaf, fetch triangle list */
if (node_addr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr - 1));
+ float4 leaf = kernel_data_fetch(bvh_leaf_nodes, (-node_addr - 1));
int prim_addr = __float_as_int(leaf.x);
if (prim_addr >= 0) {
@@ -128,16 +128,16 @@ ccl_device_inline
case PRIMITIVE_TRIANGLE: {
/* intersect ray against primitive */
for (; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ kernel_assert(kernel_data_fetch(prim_type, prim_addr) == type);
/* only primitives from volume object */
const int prim_object = (object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, prim_addr) :
+ kernel_data_fetch(prim_object, prim_addr) :
object;
- const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+ const int prim = kernel_data_fetch(prim_index, prim_addr);
if (intersection_skip_self(ray->self, prim_object, prim)) {
continue;
}
- int object_flag = kernel_tex_fetch(__object_flag, prim_object);
+ int object_flag = kernel_data_fetch(object_flag, prim_object);
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
continue;
}
@@ -172,16 +172,16 @@ ccl_device_inline
case PRIMITIVE_MOTION_TRIANGLE: {
/* intersect ray against primitive */
for (; prim_addr < prim_addr2; prim_addr++) {
- kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
+ kernel_assert(kernel_data_fetch(prim_type, prim_addr) == type);
/* only primitives from volume object */
const int prim_object = (object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, prim_addr) :
+ kernel_data_fetch(prim_object, prim_addr) :
object;
- const int prim = kernel_tex_fetch(__prim_index, prim_addr);
+ const int prim = kernel_data_fetch(prim_index, prim_addr);
if (intersection_skip_self(ray->self, prim_object, prim)) {
continue;
}
- int object_flag = kernel_tex_fetch(__object_flag, prim_object);
+ int object_flag = kernel_data_fetch(object_flag, prim_object);
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
continue;
}
@@ -228,8 +228,8 @@ ccl_device_inline
}
else {
/* instance push */
- object = kernel_tex_fetch(__prim_object, -prim_addr - 1);
- int object_flag = kernel_tex_fetch(__object_flag, object);
+ object = kernel_data_fetch(prim_object, -prim_addr - 1);
+ int object_flag = kernel_data_fetch(object_flag, object);
if (object_flag & SD_OBJECT_HAS_VOLUME) {
#if BVH_FEATURE(BVH_MOTION)
isect_t *= bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &ob_itfm);
@@ -244,7 +244,7 @@ ccl_device_inline
kernel_assert(stack_ptr < BVH_STACK_SIZE);
traversal_stack[stack_ptr] = ENTRYPOINT_SENTINEL;
- node_addr = kernel_tex_fetch(__object_node, object);
+ node_addr = kernel_data_fetch(object_node, object);
}
else {
/* pop */
diff --git a/intern/cycles/kernel/camera/camera.h b/intern/cycles/kernel/camera/camera.h
index aad68e527ac..25960a94ddb 100644
--- a/intern/cycles/kernel/camera/camera.h
+++ b/intern/cycles/kernel/camera/camera.h
@@ -90,7 +90,7 @@ ccl_device void camera_sample_perspective(KernelGlobals kg,
#ifdef __CAMERA_MOTION__
if (kernel_data.cam.num_motion_steps) {
transform_motion_array_interpolate(&cameratoworld,
- kernel_tex_array(__camera_motion),
+ kernel_data_array(camera_motion),
kernel_data.cam.num_motion_steps,
ray->time);
}
@@ -210,7 +210,7 @@ ccl_device void camera_sample_orthographic(KernelGlobals kg,
#ifdef __CAMERA_MOTION__
if (kernel_data.cam.num_motion_steps) {
transform_motion_array_interpolate(&cameratoworld,
- kernel_tex_array(__camera_motion),
+ kernel_data_array(camera_motion),
kernel_data.cam.num_motion_steps,
ray->time);
}
@@ -421,7 +421,7 @@ ccl_device_inline void camera_sample(KernelGlobals kg,
}
else {
#ifdef __CAMERA_MOTION__
- ccl_global const DecomposedTransform *cam_motion = kernel_tex_array(__camera_motion);
+ ccl_global const DecomposedTransform *cam_motion = kernel_data_array(camera_motion);
camera_sample_panorama(&kernel_data.cam, cam_motion, raster_x, raster_y, lens_u, lens_v, ray);
#else
camera_sample_panorama(&kernel_data.cam, raster_x, raster_y, lens_u, lens_v, ray);
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index 011155cdf5f..6f3c2092c64 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -434,7 +434,7 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
else {
/* Shadow terminator offset. */
const float frequency_multiplier =
- kernel_tex_fetch(__objects, sd->object).shadow_terminator_shading_offset;
+ kernel_data_fetch(objects, sd->object).shadow_terminator_shading_offset;
if (frequency_multiplier > 1.0f) {
*eval *= shift_cos_in(dot(*omega_in, sc->N), frequency_multiplier);
}
@@ -556,7 +556,7 @@ ccl_device_inline
}
/* Shadow terminator offset. */
const float frequency_multiplier =
- kernel_tex_fetch(__objects, sd->object).shadow_terminator_shading_offset;
+ kernel_data_fetch(objects, sd->object).shadow_terminator_shading_offset;
if (frequency_multiplier > 1.0f) {
eval *= shift_cos_in(dot(omega_in, sc->N), frequency_multiplier);
}
diff --git a/intern/cycles/kernel/data_arrays.h b/intern/cycles/kernel/data_arrays.h
new file mode 100644
index 00000000000..7205f728088
--- /dev/null
+++ b/intern/cycles/kernel/data_arrays.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#ifndef KERNEL_DATA_ARRAY
+# define KERNEL_DATA_ARRAY(type, name)
+#endif
+
+/* BVH2, not used for OptiX or Embree. */
+KERNEL_DATA_ARRAY(float4, bvh_nodes)
+KERNEL_DATA_ARRAY(float4, bvh_leaf_nodes)
+KERNEL_DATA_ARRAY(uint, prim_type)
+KERNEL_DATA_ARRAY(uint, prim_visibility)
+KERNEL_DATA_ARRAY(uint, prim_index)
+KERNEL_DATA_ARRAY(uint, prim_object)
+KERNEL_DATA_ARRAY(uint, object_node)
+KERNEL_DATA_ARRAY(float2, prim_time)
+
+/* objects */
+KERNEL_DATA_ARRAY(KernelObject, objects)
+KERNEL_DATA_ARRAY(Transform, object_motion_pass)
+KERNEL_DATA_ARRAY(DecomposedTransform, object_motion)
+KERNEL_DATA_ARRAY(uint, object_flag)
+KERNEL_DATA_ARRAY(float, object_volume_step)
+KERNEL_DATA_ARRAY(uint, object_prim_offset)
+
+/* cameras */
+KERNEL_DATA_ARRAY(DecomposedTransform, camera_motion)
+
+/* triangles */
+KERNEL_DATA_ARRAY(uint, tri_shader)
+KERNEL_DATA_ARRAY(packed_float3, tri_vnormal)
+KERNEL_DATA_ARRAY(uint4, tri_vindex)
+KERNEL_DATA_ARRAY(uint, tri_patch)
+KERNEL_DATA_ARRAY(float2, tri_patch_uv)
+KERNEL_DATA_ARRAY(packed_float3, tri_verts)
+
+/* curves */
+KERNEL_DATA_ARRAY(KernelCurve, curves)
+KERNEL_DATA_ARRAY(float4, curve_keys)
+KERNEL_DATA_ARRAY(KernelCurveSegment, curve_segments)
+
+/* patches */
+KERNEL_DATA_ARRAY(uint, patches)
+
+/* pointclouds */
+KERNEL_DATA_ARRAY(float4, points)
+KERNEL_DATA_ARRAY(uint, points_shader)
+
+/* attributes */
+KERNEL_DATA_ARRAY(AttributeMap, attributes_map)
+KERNEL_DATA_ARRAY(float, attributes_float)
+KERNEL_DATA_ARRAY(float2, attributes_float2)
+KERNEL_DATA_ARRAY(packed_float3, attributes_float3)
+KERNEL_DATA_ARRAY(float4, attributes_float4)
+KERNEL_DATA_ARRAY(uchar4, attributes_uchar4)
+
+/* lights */
+KERNEL_DATA_ARRAY(KernelLightDistribution, light_distribution)
+KERNEL_DATA_ARRAY(KernelLight, lights)
+KERNEL_DATA_ARRAY(float2, light_background_marginal_cdf)
+KERNEL_DATA_ARRAY(float2, light_background_conditional_cdf)
+
+/* particles */
+KERNEL_DATA_ARRAY(KernelParticle, particles)
+
+/* shaders */
+KERNEL_DATA_ARRAY(uint4, svm_nodes)
+KERNEL_DATA_ARRAY(KernelShader, shaders)
+
+/* lookup tables */
+KERNEL_DATA_ARRAY(float, lookup_table)
+
+/* sobol */
+KERNEL_DATA_ARRAY(float, sample_pattern_lut)
+
+/* image textures */
+KERNEL_DATA_ARRAY(TextureInfo, texture_info)
+
+/* ies lights */
+KERNEL_DATA_ARRAY(float, ies)
+
+#undef KERNEL_DATA_ARRAY
diff --git a/intern/cycles/kernel/device/cpu/compat.h b/intern/cycles/kernel/device/cpu/compat.h
index e1c20169582..3bfc37e98ee 100644
--- a/intern/cycles/kernel/device/cpu/compat.h
+++ b/intern/cycles/kernel/device/cpu/compat.h
@@ -35,20 +35,6 @@ CCL_NAMESPACE_BEGIN
#define kernel_assert(cond) assert(cond)
-/* Texture types to be compatible with CUDA textures. These are really just
- * simple arrays and after inlining fetch hopefully revert to being a simple
- * pointer lookup. */
-template<typename T> struct texture {
- ccl_always_inline const T &fetch(int index) const
- {
- kernel_assert(index >= 0 && index < width);
- return data[index];
- }
-
- T *data;
- int width;
-};
-
/* Macros to handle different memory storage on different devices */
#ifdef __KERNEL_SSE2__
diff --git a/intern/cycles/kernel/device/cpu/globals.h b/intern/cycles/kernel/device/cpu/globals.h
index 7e080d428ea..309afae412e 100644
--- a/intern/cycles/kernel/device/cpu/globals.h
+++ b/intern/cycles/kernel/device/cpu/globals.h
@@ -12,7 +12,7 @@
CCL_NAMESPACE_BEGIN
/* On the CPU, we pass along the struct KernelGlobals to nearly everywhere in
- * the kernel, to access constant data. These are all stored as "textures", but
+ * the kernel, to access constant data. These are all stored as flat arrays.
* these are really just standard arrays. We can't use actually globals because
* multiple renders may be running inside the same process. */
@@ -22,11 +22,23 @@ struct OSLThreadData;
struct OSLShadingSystem;
#endif
+/* Array for kernel data, with size to be able to assert on invalid data access. */
+template<typename T> struct kernel_array {
+ ccl_always_inline const T &fetch(int index) const
+ {
+ kernel_assert(index >= 0 && index < width);
+ return data[index];
+ }
+
+ T *data;
+ int width;
+};
+
typedef struct KernelGlobalsCPU {
-#define KERNEL_TEX(type, name) texture<type> name;
-#include "kernel/textures.h"
+#define KERNEL_DATA_ARRAY(type, name) kernel_array<type> name;
+#include "kernel/data_arrays.h"
- KernelData __data;
+ KernelData data;
#ifdef __OSL__
/* On the CPU, we also have the OSL globals here. Most data structures are shared
@@ -44,8 +56,8 @@ typedef struct KernelGlobalsCPU {
typedef const KernelGlobalsCPU *ccl_restrict KernelGlobals;
/* Abstraction macros */
-#define kernel_tex_fetch(tex, index) (kg->tex.fetch(index))
-#define kernel_tex_array(tex) (kg->tex.data)
-#define kernel_data (kg->__data)
+#define kernel_data_fetch(name, index) (kg->name.fetch(index))
+#define kernel_data_array(name) (kg->name.data)
+#define kernel_data (kg->data)
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/device/cpu/image.h b/intern/cycles/kernel/device/cpu/image.h
index 7809ec5f4a7..320e6309128 100644
--- a/intern/cycles/kernel/device/cpu/image.h
+++ b/intern/cycles/kernel/device/cpu/image.h
@@ -733,7 +733,7 @@ template<typename TexT, typename OutT = float4> struct NanoVDBInterpolator {
ccl_device float4 kernel_tex_image_interp(KernelGlobals kg, int id, float x, float y)
{
- const TextureInfo &info = kernel_tex_fetch(__texture_info, id);
+ const TextureInfo &info = kernel_data_fetch(texture_info, id);
if (UNLIKELY(!info.data)) {
return zero_float4();
@@ -776,7 +776,7 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals kg,
float3 P,
InterpolationType interp)
{
- const TextureInfo &info = kernel_tex_fetch(__texture_info, id);
+ const TextureInfo &info = kernel_data_fetch(texture_info, id);
if (UNLIKELY(!info.data)) {
return zero_float4();
diff --git a/intern/cycles/kernel/device/cpu/kernel.cpp b/intern/cycles/kernel/device/cpu/kernel.cpp
index b12e3089378..01087c96dd6 100644
--- a/intern/cycles/kernel/device/cpu/kernel.cpp
+++ b/intern/cycles/kernel/device/cpu/kernel.cpp
@@ -53,8 +53,8 @@ CCL_NAMESPACE_BEGIN
void kernel_const_copy(KernelGlobalsCPU *kg, const char *name, void *host, size_t)
{
- if (strcmp(name, "__data") == 0) {
- kg->__data = *(KernelData *)host;
+ if (strcmp(name, "data") == 0) {
+ kg->data = *(KernelData *)host;
}
else {
assert(0);
@@ -66,13 +66,13 @@ void kernel_global_memory_copy(KernelGlobalsCPU *kg, const char *name, void *mem
if (0) {
}
-#define KERNEL_TEX(type, tname) \
+#define KERNEL_DATA_ARRAY(type, tname) \
else if (strcmp(name, #tname) == 0) \
{ \
kg->tname.data = (type *)mem; \
kg->tname.width = size; \
}
-#include "kernel/textures.h"
+#include "kernel/data_arrays.h"
else {
assert(0);
}
diff --git a/intern/cycles/kernel/device/cuda/globals.h b/intern/cycles/kernel/device/cuda/globals.h
index e77fcd2b424..f5f7bcf58ee 100644
--- a/intern/cycles/kernel/device/cuda/globals.h
+++ b/intern/cycles/kernel/device/cuda/globals.h
@@ -20,18 +20,24 @@ struct KernelGlobalsGPU {
};
typedef ccl_global const KernelGlobalsGPU *ccl_restrict KernelGlobals;
-/* Global scene data and textures */
-__constant__ KernelData __data;
-#define KERNEL_TEX(type, name) const __constant__ __device__ type *name;
-#include "kernel/textures.h"
+struct KernelParamsCUDA {
+ /* Global scene data and textures */
+ KernelData data;
+#define KERNEL_DATA_ARRAY(type, name) const type *name;
+#include "kernel/data_arrays.h"
+
+ /* Integrator state */
+ IntegratorStateGPU integrator_state;
+};
-/* Integrator state */
-__constant__ IntegratorStateGPU __integrator_state;
+#ifdef __KERNEL_GPU__
+__constant__ KernelParamsCUDA kernel_params;
+#endif
/* Abstraction macros */
-#define kernel_data __data
-#define kernel_tex_fetch(t, index) t[(index)]
-#define kernel_tex_array(t) (t)
-#define kernel_integrator_state __integrator_state
+#define kernel_data kernel_params.data
+#define kernel_data_fetch(name, index) kernel_params.name[(index)]
+#define kernel_data_array(name) (kernel_params.name)
+#define kernel_integrator_state kernel_params.integrator_state
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/device/gpu/image.h b/intern/cycles/kernel/device/gpu/image.h
index 29d851ae478..a8c72645569 100644
--- a/intern/cycles/kernel/device/gpu/image.h
+++ b/intern/cycles/kernel/device/gpu/image.h
@@ -181,7 +181,7 @@ ccl_device_noinline typename nanovdb::NanoGrid<T>::ValueType kernel_tex_image_in
ccl_device float4 kernel_tex_image_interp(KernelGlobals kg, int id, float x, float y)
{
- ccl_global const TextureInfo &info = kernel_tex_fetch(__texture_info, id);
+ ccl_global const TextureInfo &info = kernel_data_fetch(texture_info, id);
/* float4, byte4, ushort4 and half4 */
const int texture_type = info.data_type;
@@ -216,7 +216,7 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals kg,
float3 P,
InterpolationType interp)
{
- ccl_global const TextureInfo &info = kernel_tex_fetch(__texture_info, id);
+ ccl_global const TextureInfo &info = kernel_data_fetch(texture_info, id);
if (info.use_transform_3d) {
P = transform_point(&info.transform_3d, P);
diff --git a/intern/cycles/kernel/device/hip/globals.h b/intern/cycles/kernel/device/hip/globals.h
index 50f117038a2..3a334b21a9e 100644
--- a/intern/cycles/kernel/device/hip/globals.h
+++ b/intern/cycles/kernel/device/hip/globals.h
@@ -20,18 +20,24 @@ struct KernelGlobalsGPU {
};
typedef ccl_global const KernelGlobalsGPU *ccl_restrict KernelGlobals;
-/* Global scene data and textures */
-__constant__ KernelData __data;
-#define KERNEL_TEX(type, name) __attribute__((used)) const __constant__ __device__ type *name;
-#include "kernel/textures.h"
+struct KernelParamsHIP {
+ /* Global scene data and textures */
+ KernelData data;
+#define KERNEL_DATA_ARRAY(type, name) const type *name;
+#include "kernel/data_arrays.h"
+
+ /* Integrator state */
+ IntegratorStateGPU integrator_state;
+};
-/* Integrator state */
-__constant__ IntegratorStateGPU __integrator_state;
+#ifdef __KERNEL_GPU__
+__constant__ KernelParamsHIP kernel_params;
+#endif
/* Abstraction macros */
-#define kernel_data __data
-#define kernel_tex_fetch(t, index) t[(index)]
-#define kernel_tex_array(t) (t)
-#define kernel_integrator_state __integrator_state
+#define kernel_data kernel_params.data
+#define kernel_data_fetch(name, index) kernel_params.name[(index)]
+#define kernel_data_array(name) (kernel_params.name)
+#define kernel_integrator_state kernel_params.integrator_state
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/device/metal/context_end.h b/intern/cycles/kernel/device/metal/context_end.h
index b4c8661c401..44ac0478266 100644
--- a/intern/cycles/kernel/device/metal/context_end.h
+++ b/intern/cycles/kernel/device/metal/context_end.h
@@ -7,4 +7,4 @@
/* NOTE: These macros will need maintaining as entry-points change. */
#undef kernel_integrator_state
-#define kernel_integrator_state context.launch_params_metal.__integrator_state
+#define kernel_integrator_state context.launch_params_metal.integrator_state
diff --git a/intern/cycles/kernel/device/metal/globals.h b/intern/cycles/kernel/device/metal/globals.h
index 1c3e775dbae..a336c096440 100644
--- a/intern/cycles/kernel/device/metal/globals.h
+++ b/intern/cycles/kernel/device/metal/globals.h
@@ -12,11 +12,11 @@ CCL_NAMESPACE_BEGIN
typedef struct KernelParamsMetal {
-#define KERNEL_TEX(type, name) ccl_global const type *name;
-#include "kernel/textures.h"
-#undef KERNEL_TEX
+#define KERNEL_DATA_ARRAY(type, name) ccl_global const type *name;
+#include "kernel/data_arrays.h"
+#undef KERNEL_DATA_ARRAY
- const IntegratorStateGPU __integrator_state;
+ const IntegratorStateGPU integrator_state;
const KernelData data;
} KernelParamsMetal;
@@ -27,12 +27,10 @@ typedef struct KernelGlobalsGPU {
typedef ccl_global const KernelGlobalsGPU *ccl_restrict KernelGlobals;
+/* Abstraction macros */
#define kernel_data launch_params_metal.data
-#define kernel_integrator_state launch_params_metal.__integrator_state
-
-/* data lookup defines */
-
-#define kernel_tex_fetch(tex, index) launch_params_metal.tex[index]
-#define kernel_tex_array(tex) launch_params_metal.tex
+#define kernel_data_fetch(name, index) launch_params_metal.name[index]
+#define kernel_data_array(name) launch_params_metal.name
+#define kernel_integrator_state launch_params_metal.integrator_state
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/device/metal/kernel.metal b/intern/cycles/kernel/device/metal/kernel.metal
index a7252570e64..3c31dc3354c 100644
--- a/intern/cycles/kernel/device/metal/kernel.metal
+++ b/intern/cycles/kernel/device/metal/kernel.metal
@@ -59,7 +59,7 @@ TReturn metalrt_local_hit(constant KernelParamsMetal &launch_params_metal,
TReturn result;
#ifdef __BVH_LOCAL__
- uint prim = primitive_id + kernel_tex_fetch(__object_prim_offset, object);
+ uint prim = primitive_id + kernel_data_fetch(object_prim_offset, object);
if ((object != payload.local_object) || intersection_skip_self_local(payload.self, prim)) {
/* Only intersect with matching object and skip self-intersecton. */
@@ -113,16 +113,16 @@ TReturn metalrt_local_hit(constant KernelParamsMetal &launch_params_metal,
isect->t = ray_tmax;
isect->prim = prim;
isect->object = object;
- isect->type = kernel_tex_fetch(__objects, object).primitive_type;
+ isect->type = kernel_data_fetch(objects, object).primitive_type;
isect->u = 1.0f - barycentrics.y - barycentrics.x;
isect->v = barycentrics.x;
/* Record geometric normal */
- const uint tri_vindex = kernel_tex_fetch(__tri_vindex, isect->prim).w;
- const float3 tri_a = float3(kernel_tex_fetch(__tri_verts, tri_vindex + 0));
- const float3 tri_b = float3(kernel_tex_fetch(__tri_verts, tri_vindex + 1));
- const float3 tri_c = float3(kernel_tex_fetch(__tri_verts, tri_vindex + 2));
+ const uint tri_vindex = kernel_data_fetch(tri_vindex, isect->prim).w;
+ const float3 tri_a = float3(kernel_data_fetch(tri_verts, tri_vindex + 0));
+ const float3 tri_b = float3(kernel_data_fetch(tri_verts, tri_vindex + 1));
+ const float3 tri_c = float3(kernel_data_fetch(tri_verts, tri_vindex + 2));
payload.local_isect.Ng[hit] = normalize(cross(tri_b - tri_a, tri_c - tri_a));
/* Continue tracing (without this the trace call would return after the first hit) */
@@ -168,7 +168,7 @@ bool metalrt_shadow_all_hit(constant KernelParamsMetal &launch_params_metal,
#ifdef __SHADOW_RECORD_ALL__
# ifdef __VISIBILITY_FLAG__
const uint visibility = payload.visibility;
- if ((kernel_tex_fetch(__objects, object).visibility & visibility) == 0) {
+ if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
/* continue search */
return true;
}
@@ -184,14 +184,14 @@ bool metalrt_shadow_all_hit(constant KernelParamsMetal &launch_params_metal,
if (intersection_type == METALRT_HIT_TRIANGLE) {
u = 1.0f - barycentrics.y - barycentrics.x;
v = barycentrics.x;
- type = kernel_tex_fetch(__objects, object).primitive_type;
+ type = kernel_data_fetch(objects, object).primitive_type;
}
# ifdef __HAIR__
else {
u = barycentrics.x;
v = barycentrics.y;
- const KernelCurveSegment segment = kernel_tex_fetch(__curve_segments, prim);
+ const KernelCurveSegment segment = kernel_data_fetch(curve_segments, prim);
type = segment.type;
prim = segment.prim;
@@ -294,7 +294,7 @@ __anyhit__cycles_metalrt_shadow_all_hit_tri(constant KernelParamsMetal &launch_p
float2 barycentrics [[barycentric_coord]],
float ray_tmax [[distance]])
{
- uint prim = primitive_id + kernel_tex_fetch(__object_prim_offset, object);
+ uint prim = primitive_id + kernel_data_fetch(object_prim_offset, object);
TriangleIntersectionResult result;
result.continue_search = metalrt_shadow_all_hit<METALRT_HIT_TRIANGLE>(
@@ -337,7 +337,7 @@ inline TReturnType metalrt_visibility_test(constant KernelParamsMetal &launch_pa
uint visibility = payload.visibility;
# ifdef __VISIBILITY_FLAG__
- if ((kernel_tex_fetch(__objects, object).visibility & visibility) == 0) {
+ if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
result.accept = false;
result.continue_search = true;
return result;
@@ -377,12 +377,12 @@ __anyhit__cycles_metalrt_visibility_test_tri(constant KernelParamsMetal &launch_
unsigned int object [[user_instance_id]],
unsigned int primitive_id [[primitive_id]])
{
- uint prim = primitive_id + kernel_tex_fetch(__object_prim_offset, object);
+ uint prim = primitive_id + kernel_data_fetch(object_prim_offset, object);
TriangleIntersectionResult result = metalrt_visibility_test<TriangleIntersectionResult, METALRT_HIT_TRIANGLE>(
launch_params_metal, payload, object, prim, 0.0f);
if (result.accept) {
payload.prim = prim;
- payload.type = kernel_tex_fetch(__objects, object).primitive_type;
+ payload.type = kernel_data_fetch(objects, object).primitive_type;
}
return result;
}
@@ -414,7 +414,7 @@ void metalrt_intersection_curve(constant KernelParamsMetal &launch_params_metal,
{
# ifdef __VISIBILITY_FLAG__
const uint visibility = payload.visibility;
- if ((kernel_tex_fetch(__objects, object).visibility & visibility) == 0) {
+ if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
return;
}
# endif
@@ -495,8 +495,8 @@ __intersection__curve_ribbon(constant KernelParamsMetal &launch_params_metal [[b
const float3 ray_direction [[direction]],
const float ray_tmax [[max_distance]])
{
- uint prim = primitive_id + kernel_tex_fetch(__object_prim_offset, object);
- const KernelCurveSegment segment = kernel_tex_fetch(__curve_segments, prim);
+ uint prim = primitive_id + kernel_data_fetch(object_prim_offset, object);
+ const KernelCurveSegment segment = kernel_data_fetch(curve_segments, prim);
BoundingBoxIntersectionResult result;
result.accept = false;
@@ -526,8 +526,8 @@ __intersection__curve_ribbon_shadow(constant KernelParamsMetal &launch_params_me
const float3 ray_direction [[direction]],
const float ray_tmax [[max_distance]])
{
- uint prim = primitive_id + kernel_tex_fetch(__object_prim_offset, object);
- const KernelCurveSegment segment = kernel_tex_fetch(__curve_segments, prim);
+ uint prim = primitive_id + kernel_data_fetch(object_prim_offset, object);
+ const KernelCurveSegment segment = kernel_data_fetch(curve_segments, prim);
BoundingBoxIntersectionResult result;
result.accept = false;
@@ -557,8 +557,8 @@ __intersection__curve_all(constant KernelParamsMetal &launch_params_metal [[buff
const float3 ray_direction [[direction]],
const float ray_tmax [[max_distance]])
{
- uint prim = primitive_id + kernel_tex_fetch(__object_prim_offset, object);
- const KernelCurveSegment segment = kernel_tex_fetch(__curve_segments, prim);
+ uint prim = primitive_id + kernel_data_fetch(object_prim_offset, object);
+ const KernelCurveSegment segment = kernel_data_fetch(curve_segments, prim);
BoundingBoxIntersectionResult result;
result.accept = false;
@@ -585,8 +585,8 @@ __intersection__curve_all_shadow(constant KernelParamsMetal &launch_params_metal
const float3 ray_direction [[direction]],
const float ray_tmax [[max_distance]])
{
- uint prim = primitive_id + kernel_tex_fetch(__object_prim_offset, object);
- const KernelCurveSegment segment = kernel_tex_fetch(__curve_segments, prim);
+ uint prim = primitive_id + kernel_data_fetch(object_prim_offset, object);
+ const KernelCurveSegment segment = kernel_data_fetch(curve_segments, prim);
BoundingBoxIntersectionResult result;
result.accept = false;
@@ -620,7 +620,7 @@ void metalrt_intersection_point(constant KernelParamsMetal &launch_params_metal,
{
# ifdef __VISIBILITY_FLAG__
const uint visibility = payload.visibility;
- if ((kernel_tex_fetch(__objects, object).visibility & visibility) == 0) {
+ if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
return;
}
# endif
@@ -701,8 +701,8 @@ __intersection__point(constant KernelParamsMetal &launch_params_metal [[buffer(1
const float3 ray_direction [[direction]],
const float ray_tmax [[max_distance]])
{
- const uint prim = primitive_id + kernel_tex_fetch(__object_prim_offset, object);
- const int type = kernel_tex_fetch(__objects, object).primitive_type;
+ const uint prim = primitive_id + kernel_data_fetch(object_prim_offset, object);
+ const int type = kernel_data_fetch(objects, object).primitive_type;
BoundingBoxIntersectionResult result;
result.accept = false;
@@ -730,8 +730,8 @@ __intersection__point_shadow(constant KernelParamsMetal &launch_params_metal [[b
const float3 ray_direction [[direction]],
const float ray_tmax [[max_distance]])
{
- const uint prim = primitive_id + kernel_tex_fetch(__object_prim_offset, object);
- const int type = kernel_tex_fetch(__objects, object).primitive_type;
+ const uint prim = primitive_id + kernel_data_fetch(object_prim_offset, object);
+ const int type = kernel_data_fetch(objects, object).primitive_type;
BoundingBoxIntersectionResult result;
result.accept = false;
diff --git a/intern/cycles/kernel/device/optix/globals.h b/intern/cycles/kernel/device/optix/globals.h
index bb752c531f0..7af2e421378 100644
--- a/intern/cycles/kernel/device/optix/globals.h
+++ b/intern/cycles/kernel/device/optix/globals.h
@@ -28,21 +28,21 @@ struct KernelParamsOptiX {
/* Global scene data and textures */
KernelData data;
-#define KERNEL_TEX(type, name) const type *name;
-#include "kernel/textures.h"
+#define KERNEL_DATA_ARRAY(type, name) const type *name;
+#include "kernel/data_arrays.h"
/* Integrator state */
- IntegratorStateGPU __integrator_state;
+ IntegratorStateGPU integrator_state;
};
#ifdef __NVCC__
-extern "C" static __constant__ KernelParamsOptiX __params;
+extern "C" static __constant__ KernelParamsOptiX kernel_params;
#endif
/* Abstraction macros */
-#define kernel_data __params.data
-#define kernel_tex_array(t) __params.t
-#define kernel_tex_fetch(t, index) __params.t[(index)]
-#define kernel_integrator_state __params.__integrator_state
+#define kernel_data kernel_params.data
+#define kernel_data_array(name) kernel_params.name
+#define kernel_data_fetch(name, index) kernel_params.name[(index)]
+#define kernel_integrator_state kernel_params.integrator_state
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/device/optix/kernel.cu b/intern/cycles/kernel/device/optix/kernel.cu
index 9843b2e99be..949bf41d171 100644
--- a/intern/cycles/kernel/device/optix/kernel.cu
+++ b/intern/cycles/kernel/device/optix/kernel.cu
@@ -51,15 +51,15 @@ ccl_device_forceinline int get_object_id()
extern "C" __global__ void __raygen__kernel_optix_integrator_intersect_closest()
{
const int global_index = optixGetLaunchIndex().x;
- const int path_index = (__params.path_index_array) ? __params.path_index_array[global_index] :
+ const int path_index = (kernel_params.path_index_array) ? kernel_params.path_index_array[global_index] :
global_index;
- integrator_intersect_closest(nullptr, path_index, __params.render_buffer);
+ integrator_intersect_closest(nullptr, path_index, kernel_params.render_buffer);
}
extern "C" __global__ void __raygen__kernel_optix_integrator_intersect_shadow()
{
const int global_index = optixGetLaunchIndex().x;
- const int path_index = (__params.path_index_array) ? __params.path_index_array[global_index] :
+ const int path_index = (kernel_params.path_index_array) ? kernel_params.path_index_array[global_index] :
global_index;
integrator_intersect_shadow(nullptr, path_index);
}
@@ -67,7 +67,7 @@ extern "C" __global__ void __raygen__kernel_optix_integrator_intersect_shadow()
extern "C" __global__ void __raygen__kernel_optix_integrator_intersect_subsurface()
{
const int global_index = optixGetLaunchIndex().x;
- const int path_index = (__params.path_index_array) ? __params.path_index_array[global_index] :
+ const int path_index = (kernel_params.path_index_array) ? kernel_params.path_index_array[global_index] :
global_index;
integrator_intersect_subsurface(nullptr, path_index);
}
@@ -75,7 +75,7 @@ extern "C" __global__ void __raygen__kernel_optix_integrator_intersect_subsurfac
extern "C" __global__ void __raygen__kernel_optix_integrator_intersect_volume_stack()
{
const int global_index = optixGetLaunchIndex().x;
- const int path_index = (__params.path_index_array) ? __params.path_index_array[global_index] :
+ const int path_index = (kernel_params.path_index_array) ? kernel_params.path_index_array[global_index] :
global_index;
integrator_intersect_volume_stack(nullptr, path_index);
}
@@ -151,17 +151,17 @@ extern "C" __global__ void __anyhit__kernel_optix_local_hit()
isect->t = optixGetRayTmax();
isect->prim = prim;
isect->object = get_object_id();
- isect->type = kernel_tex_fetch(__objects, isect->object).primitive_type;
+ isect->type = kernel_data_fetch(objects, isect->object).primitive_type;
const float2 barycentrics = optixGetTriangleBarycentrics();
isect->u = 1.0f - barycentrics.y - barycentrics.x;
isect->v = barycentrics.x;
/* Record geometric normal. */
- const uint tri_vindex = kernel_tex_fetch(__tri_vindex, prim).w;
- const float3 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0);
- const float3 tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1);
- const float3 tri_c = kernel_tex_fetch(__tri_verts, tri_vindex + 2);
+ const uint tri_vindex = kernel_data_fetch(tri_vindex, prim).w;
+ const float3 tri_a = kernel_data_fetch(tri_verts, tri_vindex + 0);
+ const float3 tri_b = kernel_data_fetch(tri_verts, tri_vindex + 1);
+ const float3 tri_c = kernel_data_fetch(tri_verts, tri_vindex + 2);
local_isect->Ng[hit] = normalize(cross(tri_b - tri_a, tri_c - tri_a));
/* Continue tracing (without this the trace call would return after the first hit). */
@@ -176,7 +176,7 @@ extern "C" __global__ void __anyhit__kernel_optix_shadow_all_hit()
const uint object = get_object_id();
# ifdef __VISIBILITY_FLAG__
const uint visibility = optixGetPayload_4();
- if ((kernel_tex_fetch(__objects, object).visibility & visibility) == 0) {
+ if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
return optixIgnoreIntersection();
}
# endif
@@ -192,14 +192,14 @@ extern "C" __global__ void __anyhit__kernel_optix_shadow_all_hit()
const float2 barycentrics = optixGetTriangleBarycentrics();
u = 1.0f - barycentrics.y - barycentrics.x;
v = barycentrics.x;
- type = kernel_tex_fetch(__objects, object).primitive_type;
+ type = kernel_data_fetch(objects, object).primitive_type;
}
# ifdef __HAIR__
else if ((optixGetHitKind() & (~PRIMITIVE_MOTION)) != PRIMITIVE_POINT) {
u = __uint_as_float(optixGetAttribute_0());
v = __uint_as_float(optixGetAttribute_1());
- const KernelCurveSegment segment = kernel_tex_fetch(__curve_segments, prim);
+ const KernelCurveSegment segment = kernel_data_fetch(curve_segments, prim);
type = segment.type;
prim = segment.prim;
@@ -212,7 +212,7 @@ extern "C" __global__ void __anyhit__kernel_optix_shadow_all_hit()
}
# endif
else {
- type = kernel_tex_fetch(__objects, object).primitive_type;
+ type = kernel_data_fetch(objects, object).primitive_type;
u = 0.0f;
v = 0.0f;
}
@@ -307,12 +307,12 @@ extern "C" __global__ void __anyhit__kernel_optix_volume_test()
const uint object = get_object_id();
#ifdef __VISIBILITY_FLAG__
const uint visibility = optixGetPayload_4();
- if ((kernel_tex_fetch(__objects, object).visibility & visibility) == 0) {
+ if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
return optixIgnoreIntersection();
}
#endif
- if ((kernel_tex_fetch(__object_flag, object) & SD_OBJECT_HAS_VOLUME) == 0) {
+ if ((kernel_data_fetch(object_flag, object) & SD_OBJECT_HAS_VOLUME) == 0) {
return optixIgnoreIntersection();
}
@@ -340,7 +340,7 @@ extern "C" __global__ void __anyhit__kernel_optix_visibility_test()
const uint object = get_object_id();
const uint visibility = optixGetPayload_4();
#ifdef __VISIBILITY_FLAG__
- if ((kernel_tex_fetch(__objects, object).visibility & visibility) == 0) {
+ if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
return optixIgnoreIntersection();
}
#endif
@@ -377,10 +377,10 @@ extern "C" __global__ void __closesthit__kernel_optix_hit()
optixSetPayload_1(__float_as_uint(1.0f - barycentrics.y - barycentrics.x));
optixSetPayload_2(__float_as_uint(barycentrics.x));
optixSetPayload_3(prim);
- optixSetPayload_5(kernel_tex_fetch(__objects, object).primitive_type);
+ optixSetPayload_5(kernel_data_fetch(objects, object).primitive_type);
}
else if ((optixGetHitKind() & (~PRIMITIVE_MOTION)) != PRIMITIVE_POINT) {
- const KernelCurveSegment segment = kernel_tex_fetch(__curve_segments, prim);
+ const KernelCurveSegment segment = kernel_data_fetch(curve_segments, prim);
optixSetPayload_1(optixGetAttribute_0()); /* Same as 'optixGetCurveParameter()' */
optixSetPayload_2(optixGetAttribute_1());
optixSetPayload_3(segment.prim);
@@ -390,7 +390,7 @@ extern "C" __global__ void __closesthit__kernel_optix_hit()
optixSetPayload_1(0);
optixSetPayload_2(0);
optixSetPayload_3(prim);
- optixSetPayload_5(kernel_tex_fetch(__objects, object).primitive_type);
+ optixSetPayload_5(kernel_data_fetch(objects, object).primitive_type);
}
}
@@ -401,7 +401,7 @@ ccl_device_inline void optix_intersection_curve(const int prim, const int type)
# ifdef __VISIBILITY_FLAG__
const uint visibility = optixGetPayload_4();
- if ((kernel_tex_fetch(__objects, object).visibility & visibility) == 0) {
+ if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
return;
}
# endif
@@ -436,7 +436,7 @@ ccl_device_inline void optix_intersection_curve(const int prim, const int type)
extern "C" __global__ void __intersection__curve_ribbon()
{
- const KernelCurveSegment segment = kernel_tex_fetch(__curve_segments, optixGetPrimitiveIndex());
+ const KernelCurveSegment segment = kernel_data_fetch(curve_segments, optixGetPrimitiveIndex());
const int prim = segment.prim;
const int type = segment.type;
if (type & PRIMITIVE_CURVE_RIBBON) {
@@ -451,11 +451,11 @@ extern "C" __global__ void __intersection__point()
{
const int prim = optixGetPrimitiveIndex();
const int object = get_object_id();
- const int type = kernel_tex_fetch(__objects, object).primitive_type;
+ const int type = kernel_data_fetch(objects, object).primitive_type;
# ifdef __VISIBILITY_FLAG__
const uint visibility = optixGetPayload_4();
- if ((kernel_tex_fetch(__objects, object).visibility & visibility) == 0) {
+ if ((kernel_data_fetch(objects, object).visibility & visibility) == 0) {
return;
}
# endif
diff --git a/intern/cycles/kernel/device/optix/kernel_shader_raytrace.cu b/intern/cycles/kernel/device/optix/kernel_shader_raytrace.cu
index 3bd57bc0f1a..41e6224f6da 100644
--- a/intern/cycles/kernel/device/optix/kernel_shader_raytrace.cu
+++ b/intern/cycles/kernel/device/optix/kernel_shader_raytrace.cu
@@ -11,15 +11,15 @@
extern "C" __global__ void __raygen__kernel_optix_integrator_shade_surface_raytrace()
{
const int global_index = optixGetLaunchIndex().x;
- const int path_index = (__params.path_index_array) ? __params.path_index_array[global_index] :
+ const int path_index = (kernel_params.path_index_array) ? kernel_params.path_index_array[global_index] :
global_index;
- integrator_shade_surface_raytrace(nullptr, path_index, __params.render_buffer);
+ integrator_shade_surface_raytrace(nullptr, path_index, kernel_params.render_buffer);
}
extern "C" __global__ void __raygen__kernel_optix_integrator_shade_surface_mnee()
{
const int global_index = optixGetLaunchIndex().x;
- const int path_index = (__params.path_index_array) ? __params.path_index_array[global_index] :
+ const int path_index = (kernel_params.path_index_array) ? kernel_params.path_index_array[global_index] :
global_index;
- integrator_shade_surface_mnee(nullptr, path_index, __params.render_buffer);
+ integrator_shade_surface_mnee(nullptr, path_index, kernel_params.render_buffer);
}
diff --git a/intern/cycles/kernel/geom/attribute.h b/intern/cycles/kernel/geom/attribute.h
index da620f69e2d..31a9e39d528 100644
--- a/intern/cycles/kernel/geom/attribute.h
+++ b/intern/cycles/kernel/geom/attribute.h
@@ -18,7 +18,7 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline uint subd_triangle_patch(KernelGlobals kg, ccl_private const ShaderData *sd)
{
- return (sd->prim != PRIM_NONE) ? kernel_tex_fetch(__tri_patch, sd->prim) : ~0;
+ return (sd->prim != PRIM_NONE) ? kernel_data_fetch(tri_patch, sd->prim) : ~0;
}
ccl_device_inline uint attribute_primitive_type(KernelGlobals kg, ccl_private const ShaderData *sd)
@@ -42,7 +42,7 @@ ccl_device_inline AttributeDescriptor attribute_not_found()
ccl_device_inline uint object_attribute_map_offset(KernelGlobals kg, int object)
{
- return kernel_tex_fetch(__objects, object).attribute_map_offset;
+ return kernel_data_fetch(objects, object).attribute_map_offset;
}
ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
@@ -56,26 +56,26 @@ ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
/* for SVM, find attribute by unique id */
uint attr_offset = object_attribute_map_offset(kg, sd->object);
attr_offset += attribute_primitive_type(kg, sd);
- uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ AttributeMap attr_map = kernel_data_fetch(attributes_map, attr_offset);
- while (attr_map.x != id) {
- if (UNLIKELY(attr_map.x == ATTR_STD_NONE)) {
- if (UNLIKELY(attr_map.y == 0)) {
+ while (attr_map.id != id) {
+ if (UNLIKELY(attr_map.id == ATTR_STD_NONE)) {
+ if (UNLIKELY(attr_map.element == 0)) {
return attribute_not_found();
}
else {
/* Chain jump to a different part of the table. */
- attr_offset = attr_map.z;
+ attr_offset = attr_map.offset;
}
}
else {
attr_offset += ATTR_PRIM_TYPES;
}
- attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+ attr_map = kernel_data_fetch(attributes_map, attr_offset);
}
AttributeDescriptor desc;
- desc.element = (AttributeElement)attr_map.y;
+ desc.element = (AttributeElement)attr_map.element;
if (sd->prim == PRIM_NONE && desc.element != ATTR_ELEMENT_MESH &&
desc.element != ATTR_ELEMENT_VOXEL && desc.element != ATTR_ELEMENT_OBJECT) {
@@ -83,9 +83,10 @@ ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
}
/* return result */
- desc.offset = (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
- desc.type = (NodeAttributeType)(attr_map.w & 0xff);
- desc.flags = (AttributeFlag)(attr_map.w >> 8);
+ desc.offset = (attr_map.element == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND :
+ (int)attr_map.offset;
+ desc.type = (NodeAttributeType)attr_map.type;
+ desc.flags = (AttributeFlag)attr_map.flags;
return desc;
}
@@ -98,9 +99,9 @@ ccl_device Transform primitive_attribute_matrix(KernelGlobals kg,
{
Transform tfm;
- tfm.x = kernel_tex_fetch(__attributes_float4, desc.offset + 0);
- tfm.y = kernel_tex_fetch(__attributes_float4, desc.offset + 1);
- tfm.z = kernel_tex_fetch(__attributes_float4, desc.offset + 2);
+ tfm.x = kernel_data_fetch(attributes_float4, desc.offset + 0);
+ tfm.y = kernel_data_fetch(attributes_float4, desc.offset + 1);
+ tfm.z = kernel_data_fetch(attributes_float4, desc.offset + 2);
return tfm;
}
diff --git a/intern/cycles/kernel/geom/curve.h b/intern/cycles/kernel/geom/curve.h
index 4dbc6d4f6db..e243adfde21 100644
--- a/intern/cycles/kernel/geom/curve.h
+++ b/intern/cycles/kernel/geom/curve.h
@@ -23,12 +23,12 @@ ccl_device float curve_attribute_float(KernelGlobals kg,
ccl_private float *dy)
{
if (desc.element & (ATTR_ELEMENT_CURVE_KEY | ATTR_ELEMENT_CURVE_KEY_MOTION)) {
- KernelCurve curve = kernel_tex_fetch(__curves, sd->prim);
+ KernelCurve curve = kernel_data_fetch(curves, sd->prim);
int k0 = curve.first_key + PRIMITIVE_UNPACK_SEGMENT(sd->type);
int k1 = k0 + 1;
- float f0 = kernel_tex_fetch(__attributes_float, desc.offset + k0);
- float f1 = kernel_tex_fetch(__attributes_float, desc.offset + k1);
+ float f0 = kernel_data_fetch(attributes_float, desc.offset + k0);
+ float f1 = kernel_data_fetch(attributes_float, desc.offset + k1);
# ifdef __RAY_DIFFERENTIALS__
if (dx)
@@ -50,7 +50,7 @@ ccl_device float curve_attribute_float(KernelGlobals kg,
if (desc.element & (ATTR_ELEMENT_CURVE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) {
const int offset = (desc.element == ATTR_ELEMENT_CURVE) ? desc.offset + sd->prim :
desc.offset;
- return kernel_tex_fetch(__attributes_float, offset);
+ return kernel_data_fetch(attributes_float, offset);
}
else {
return 0.0f;
@@ -65,12 +65,12 @@ ccl_device float2 curve_attribute_float2(KernelGlobals kg,
ccl_private float2 *dy)
{
if (desc.element & (ATTR_ELEMENT_CURVE_KEY | ATTR_ELEMENT_CURVE_KEY_MOTION)) {
- KernelCurve curve = kernel_tex_fetch(__curves, sd->prim);
+ KernelCurve curve = kernel_data_fetch(curves, sd->prim);
int k0 = curve.first_key + PRIMITIVE_UNPACK_SEGMENT(sd->type);
int k1 = k0 + 1;
- float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + k0);
- float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + k1);
+ float2 f0 = kernel_data_fetch(attributes_float2, desc.offset + k0);
+ float2 f1 = kernel_data_fetch(attributes_float2, desc.offset + k1);
# ifdef __RAY_DIFFERENTIALS__
if (dx)
@@ -96,7 +96,7 @@ ccl_device float2 curve_attribute_float2(KernelGlobals kg,
if (desc.element & (ATTR_ELEMENT_CURVE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) {
const int offset = (desc.element == ATTR_ELEMENT_CURVE) ? desc.offset + sd->prim :
desc.offset;
- return kernel_tex_fetch(__attributes_float2, offset);
+ return kernel_data_fetch(attributes_float2, offset);
}
else {
return make_float2(0.0f, 0.0f);
@@ -111,12 +111,12 @@ ccl_device float3 curve_attribute_float3(KernelGlobals kg,
ccl_private float3 *dy)
{
if (desc.element & (ATTR_ELEMENT_CURVE_KEY | ATTR_ELEMENT_CURVE_KEY_MOTION)) {
- KernelCurve curve = kernel_tex_fetch(__curves, sd->prim);
+ KernelCurve curve = kernel_data_fetch(curves, sd->prim);
int k0 = curve.first_key + PRIMITIVE_UNPACK_SEGMENT(sd->type);
int k1 = k0 + 1;
- float3 f0 = kernel_tex_fetch(__attributes_float3, desc.offset + k0);
- float3 f1 = kernel_tex_fetch(__attributes_float3, desc.offset + k1);
+ float3 f0 = kernel_data_fetch(attributes_float3, desc.offset + k0);
+ float3 f1 = kernel_data_fetch(attributes_float3, desc.offset + k1);
# ifdef __RAY_DIFFERENTIALS__
if (dx)
@@ -138,7 +138,7 @@ ccl_device float3 curve_attribute_float3(KernelGlobals kg,
if (desc.element & (ATTR_ELEMENT_CURVE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) {
const int offset = (desc.element == ATTR_ELEMENT_CURVE) ? desc.offset + sd->prim :
desc.offset;
- return kernel_tex_fetch(__attributes_float3, offset);
+ return kernel_data_fetch(attributes_float3, offset);
}
else {
return make_float3(0.0f, 0.0f, 0.0f);
@@ -153,12 +153,12 @@ ccl_device float4 curve_attribute_float4(KernelGlobals kg,
ccl_private float4 *dy)
{
if (desc.element & (ATTR_ELEMENT_CURVE_KEY | ATTR_ELEMENT_CURVE_KEY_MOTION)) {
- KernelCurve curve = kernel_tex_fetch(__curves, sd->prim);
+ KernelCurve curve = kernel_data_fetch(curves, sd->prim);
int k0 = curve.first_key + PRIMITIVE_UNPACK_SEGMENT(sd->type);
int k1 = k0 + 1;
- float4 f0 = kernel_tex_fetch(__attributes_float4, desc.offset + k0);
- float4 f1 = kernel_tex_fetch(__attributes_float4, desc.offset + k1);
+ float4 f0 = kernel_data_fetch(attributes_float4, desc.offset + k0);
+ float4 f1 = kernel_data_fetch(attributes_float4, desc.offset + k1);
# ifdef __RAY_DIFFERENTIALS__
if (dx)
@@ -180,7 +180,7 @@ ccl_device float4 curve_attribute_float4(KernelGlobals kg,
if (desc.element & (ATTR_ELEMENT_CURVE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) {
const int offset = (desc.element == ATTR_ELEMENT_CURVE) ? desc.offset + sd->prim :
desc.offset;
- return kernel_tex_fetch(__attributes_float4, offset);
+ return kernel_data_fetch(attributes_float4, offset);
}
else {
return zero_float4();
@@ -195,15 +195,15 @@ ccl_device float curve_thickness(KernelGlobals kg, ccl_private const ShaderData
float r = 0.0f;
if (sd->type & PRIMITIVE_CURVE) {
- KernelCurve curve = kernel_tex_fetch(__curves, sd->prim);
+ KernelCurve curve = kernel_data_fetch(curves, sd->prim);
int k0 = curve.first_key + PRIMITIVE_UNPACK_SEGMENT(sd->type);
int k1 = k0 + 1;
float4 P_curve[2];
if (!(sd->type & PRIMITIVE_MOTION)) {
- P_curve[0] = kernel_tex_fetch(__curve_keys, k0);
- P_curve[1] = kernel_tex_fetch(__curve_keys, k1);
+ P_curve[0] = kernel_data_fetch(curve_keys, k0);
+ P_curve[1] = kernel_data_fetch(curve_keys, k1);
}
else {
motion_curve_keys_linear(kg, sd->object, sd->prim, sd->time, k0, k1, P_curve);
@@ -232,14 +232,14 @@ ccl_device float curve_random(KernelGlobals kg, ccl_private const ShaderData *sd
ccl_device float3 curve_motion_center_location(KernelGlobals kg, ccl_private const ShaderData *sd)
{
- KernelCurve curve = kernel_tex_fetch(__curves, sd->prim);
+ KernelCurve curve = kernel_data_fetch(curves, sd->prim);
int k0 = curve.first_key + PRIMITIVE_UNPACK_SEGMENT(sd->type);
int k1 = k0 + 1;
float4 P_curve[2];
- P_curve[0] = kernel_tex_fetch(__curve_keys, k0);
- P_curve[1] = kernel_tex_fetch(__curve_keys, k1);
+ P_curve[0] = kernel_data_fetch(curve_keys, k0);
+ P_curve[1] = kernel_data_fetch(curve_keys, k1);
return float4_to_float3(P_curve[1]) * sd->u + float4_to_float3(P_curve[0]) * (1.0f - sd->u);
}
diff --git a/intern/cycles/kernel/geom/curve_intersect.h b/intern/cycles/kernel/geom/curve_intersect.h
index e1a1f9c02c5..11ec42a0598 100644
--- a/intern/cycles/kernel/geom/curve_intersect.h
+++ b/intern/cycles/kernel/geom/curve_intersect.h
@@ -624,7 +624,7 @@ ccl_device_forceinline bool curve_intersect(KernelGlobals kg,
{
const bool is_motion = (type & PRIMITIVE_MOTION);
- KernelCurve kcurve = kernel_tex_fetch(__curves, prim);
+ KernelCurve kcurve = kernel_data_fetch(curves, prim);
int k0 = kcurve.first_key + PRIMITIVE_UNPACK_SEGMENT(type);
int k1 = k0 + 1;
@@ -633,10 +633,10 @@ ccl_device_forceinline bool curve_intersect(KernelGlobals kg,
float4 curve[4];
if (!is_motion) {
- curve[0] = kernel_tex_fetch(__curve_keys, ka);
- curve[1] = kernel_tex_fetch(__curve_keys, k0);
- curve[2] = kernel_tex_fetch(__curve_keys, k1);
- curve[3] = kernel_tex_fetch(__curve_keys, kb);
+ curve[0] = kernel_data_fetch(curve_keys, ka);
+ curve[1] = kernel_data_fetch(curve_keys, k0);
+ curve[2] = kernel_data_fetch(curve_keys, k1);
+ curve[3] = kernel_data_fetch(curve_keys, kb);
}
else {
motion_curve_keys(kg, object, prim, time, ka, k0, k1, kb, curve);
@@ -682,7 +682,7 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg,
D = safe_normalize_len(D, &t);
}
- KernelCurve kcurve = kernel_tex_fetch(__curves, isect_prim);
+ KernelCurve kcurve = kernel_data_fetch(curves, isect_prim);
int k0 = kcurve.first_key + PRIMITIVE_UNPACK_SEGMENT(sd->type);
int k1 = k0 + 1;
@@ -692,10 +692,10 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg,
float4 P_curve[4];
if (!(sd->type & PRIMITIVE_MOTION)) {
- P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
- P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
- P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
- P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
+ P_curve[0] = kernel_data_fetch(curve_keys, ka);
+ P_curve[1] = kernel_data_fetch(curve_keys, k0);
+ P_curve[2] = kernel_data_fetch(curve_keys, k1);
+ P_curve[3] = kernel_data_fetch(curve_keys, kb);
}
else {
motion_curve_keys(kg, sd->object, sd->prim, sd->time, ka, k0, k1, kb, P_curve);
@@ -750,7 +750,7 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg,
sd->P = P;
sd->Ng = (sd->type & PRIMITIVE_CURVE_RIBBON) ? sd->I : sd->N;
sd->dPdv = cross(sd->dPdu, sd->Ng);
- sd->shader = kernel_tex_fetch(__curves, sd->prim).shader_id;
+ sd->shader = kernel_data_fetch(curves, sd->prim).shader_id;
}
#endif
diff --git a/intern/cycles/kernel/geom/motion_curve.h b/intern/cycles/kernel/geom/motion_curve.h
index b5289b6dda1..448e4b95e0b 100644
--- a/intern/cycles/kernel/geom/motion_curve.h
+++ b/intern/cycles/kernel/geom/motion_curve.h
@@ -27,8 +27,8 @@ ccl_device_inline void motion_curve_keys_for_step_linear(KernelGlobals kg,
{
if (step == numsteps) {
/* center step: regular key location */
- keys[0] = kernel_tex_fetch(__curve_keys, k0);
- keys[1] = kernel_tex_fetch(__curve_keys, k1);
+ keys[0] = kernel_data_fetch(curve_keys, k0);
+ keys[1] = kernel_data_fetch(curve_keys, k1);
}
else {
/* center step is not stored in this array */
@@ -37,8 +37,8 @@ ccl_device_inline void motion_curve_keys_for_step_linear(KernelGlobals kg,
offset += step * numkeys;
- keys[0] = kernel_tex_fetch(__attributes_float4, offset + k0);
- keys[1] = kernel_tex_fetch(__attributes_float4, offset + k1);
+ keys[0] = kernel_data_fetch(attributes_float4, offset + k0);
+ keys[1] = kernel_data_fetch(attributes_float4, offset + k1);
}
}
@@ -83,10 +83,10 @@ ccl_device_inline void motion_curve_keys_for_step(KernelGlobals kg,
{
if (step == numsteps) {
/* center step: regular key location */
- keys[0] = kernel_tex_fetch(__curve_keys, k0);
- keys[1] = kernel_tex_fetch(__curve_keys, k1);
- keys[2] = kernel_tex_fetch(__curve_keys, k2);
- keys[3] = kernel_tex_fetch(__curve_keys, k3);
+ keys[0] = kernel_data_fetch(curve_keys, k0);
+ keys[1] = kernel_data_fetch(curve_keys, k1);
+ keys[2] = kernel_data_fetch(curve_keys, k2);
+ keys[3] = kernel_data_fetch(curve_keys, k3);
}
else {
/* center step is not stored in this array */
@@ -95,10 +95,10 @@ ccl_device_inline void motion_curve_keys_for_step(KernelGlobals kg,
offset += step * numkeys;
- keys[0] = kernel_tex_fetch(__attributes_float4, offset + k0);
- keys[1] = kernel_tex_fetch(__attributes_float4, offset + k1);
- keys[2] = kernel_tex_fetch(__attributes_float4, offset + k2);
- keys[3] = kernel_tex_fetch(__attributes_float4, offset + k3);
+ keys[0] = kernel_data_fetch(attributes_float4, offset + k0);
+ keys[1] = kernel_data_fetch(attributes_float4, offset + k1);
+ keys[2] = kernel_data_fetch(attributes_float4, offset + k2);
+ keys[3] = kernel_data_fetch(attributes_float4, offset + k3);
}
}
diff --git a/intern/cycles/kernel/geom/motion_point.h b/intern/cycles/kernel/geom/motion_point.h
index c1952ab090a..4916ae702ff 100644
--- a/intern/cycles/kernel/geom/motion_point.h
+++ b/intern/cycles/kernel/geom/motion_point.h
@@ -19,7 +19,7 @@ motion_point_for_step(KernelGlobals kg, int offset, int numkeys, int numsteps, i
{
if (step == numsteps) {
/* center step: regular key location */
- return kernel_tex_fetch(__points, prim);
+ return kernel_data_fetch(points, prim);
}
else {
/* center step is not stored in this array */
@@ -28,7 +28,7 @@ motion_point_for_step(KernelGlobals kg, int offset, int numkeys, int numsteps, i
offset += step * numkeys;
- return kernel_tex_fetch(__attributes_float4, offset + prim);
+ return kernel_data_fetch(attributes_float4, offset + prim);
}
}
diff --git a/intern/cycles/kernel/geom/motion_triangle.h b/intern/cycles/kernel/geom/motion_triangle.h
index a87eb11f4f4..06308071700 100644
--- a/intern/cycles/kernel/geom/motion_triangle.h
+++ b/intern/cycles/kernel/geom/motion_triangle.h
@@ -30,9 +30,9 @@ ccl_device_inline void motion_triangle_verts_for_step(KernelGlobals kg,
{
if (step == numsteps) {
/* center step: regular vertex location */
- verts[0] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0);
- verts[1] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1);
- verts[2] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2);
+ verts[0] = kernel_data_fetch(tri_verts, tri_vindex.w + 0);
+ verts[1] = kernel_data_fetch(tri_verts, tri_vindex.w + 1);
+ verts[2] = kernel_data_fetch(tri_verts, tri_vindex.w + 2);
}
else {
/* center step not store in this array */
@@ -41,9 +41,9 @@ ccl_device_inline void motion_triangle_verts_for_step(KernelGlobals kg,
offset += step * numverts;
- verts[0] = kernel_tex_fetch(__attributes_float3, offset + tri_vindex.x);
- verts[1] = kernel_tex_fetch(__attributes_float3, offset + tri_vindex.y);
- verts[2] = kernel_tex_fetch(__attributes_float3, offset + tri_vindex.z);
+ verts[0] = kernel_data_fetch(attributes_float3, offset + tri_vindex.x);
+ verts[1] = kernel_data_fetch(attributes_float3, offset + tri_vindex.y);
+ verts[2] = kernel_data_fetch(attributes_float3, offset + tri_vindex.z);
}
}
@@ -57,9 +57,9 @@ ccl_device_inline void motion_triangle_normals_for_step(KernelGlobals kg,
{
if (step == numsteps) {
/* center step: regular vertex location */
- normals[0] = kernel_tex_fetch(__tri_vnormal, tri_vindex.x);
- normals[1] = kernel_tex_fetch(__tri_vnormal, tri_vindex.y);
- normals[2] = kernel_tex_fetch(__tri_vnormal, tri_vindex.z);
+ normals[0] = kernel_data_fetch(tri_vnormal, tri_vindex.x);
+ normals[1] = kernel_data_fetch(tri_vnormal, tri_vindex.y);
+ normals[2] = kernel_data_fetch(tri_vnormal, tri_vindex.z);
}
else {
/* center step is not stored in this array */
@@ -68,9 +68,9 @@ ccl_device_inline void motion_triangle_normals_for_step(KernelGlobals kg,
offset += step * numverts;
- normals[0] = kernel_tex_fetch(__attributes_float3, offset + tri_vindex.x);
- normals[1] = kernel_tex_fetch(__attributes_float3, offset + tri_vindex.y);
- normals[2] = kernel_tex_fetch(__attributes_float3, offset + tri_vindex.z);
+ normals[0] = kernel_data_fetch(attributes_float3, offset + tri_vindex.x);
+ normals[1] = kernel_data_fetch(attributes_float3, offset + tri_vindex.y);
+ normals[2] = kernel_data_fetch(attributes_float3, offset + tri_vindex.z);
}
}
@@ -92,7 +92,7 @@ ccl_device_inline void motion_triangle_vertices(
/* fetch vertex coordinates */
float3 next_verts[3];
- uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
+ uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step + 1, next_verts);
@@ -121,7 +121,7 @@ ccl_device_inline void motion_triangle_vertices_and_normals(
/* Fetch vertex coordinates. */
float3 next_verts[3];
- uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
+ uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step + 1, next_verts);
@@ -167,7 +167,7 @@ ccl_device_inline float3 motion_triangle_smooth_normal(
/* fetch normals */
float3 normals[3], next_normals[3];
- uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
+ uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step, normals);
motion_triangle_normals_for_step(
diff --git a/intern/cycles/kernel/geom/motion_triangle_intersect.h b/intern/cycles/kernel/geom/motion_triangle_intersect.h
index fb951fa151d..6eea5096567 100644
--- a/intern/cycles/kernel/geom/motion_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/motion_triangle_intersect.h
@@ -63,7 +63,7 @@ ccl_device_inline bool motion_triangle_intersect(KernelGlobals kg,
/* Visibility flag test. we do it here under the assumption
* that most triangles are culled by node flags.
*/
- if (kernel_tex_fetch(__prim_visibility, prim_addr) & visibility)
+ if (kernel_data_fetch(prim_visibility, prim_addr) & visibility)
#endif
{
isect->t = t;
diff --git a/intern/cycles/kernel/geom/motion_triangle_shader.h b/intern/cycles/kernel/geom/motion_triangle_shader.h
index 2b2bb858816..236e737b785 100644
--- a/intern/cycles/kernel/geom/motion_triangle_shader.h
+++ b/intern/cycles/kernel/geom/motion_triangle_shader.h
@@ -31,7 +31,7 @@ ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals kg,
bool is_local)
{
/* Get shader. */
- sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
+ sd->shader = kernel_data_fetch(tri_shader, sd->prim);
/* Get motion info. */
/* TODO(sergey): This logic is really similar to motion_triangle_vertices(),
* can we de-duplicate something here?
@@ -47,7 +47,7 @@ ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals kg,
kernel_assert(offset != ATTR_STD_NOT_FOUND);
/* Fetch vertex coordinates. */
float3 verts[3], next_verts[3];
- uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
+ uint4 tri_vindex = kernel_data_fetch(tri_vindex, sd->prim);
motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts);
motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step + 1, next_verts);
/* Interpolate between steps. */
diff --git a/intern/cycles/kernel/geom/object.h b/intern/cycles/kernel/geom/object.h
index 3faab7fa905..b15f6b5dda5 100644
--- a/intern/cycles/kernel/geom/object.h
+++ b/intern/cycles/kernel/geom/object.h
@@ -31,10 +31,10 @@ ccl_device_inline Transform object_fetch_transform(KernelGlobals kg,
enum ObjectTransform type)
{
if (type == OBJECT_INVERSE_TRANSFORM) {
- return kernel_tex_fetch(__objects, object).itfm;
+ return kernel_data_fetch(objects, object).itfm;
}
else {
- return kernel_tex_fetch(__objects, object).tfm;
+ return kernel_data_fetch(objects, object).tfm;
}
}
@@ -43,10 +43,10 @@ ccl_device_inline Transform object_fetch_transform(KernelGlobals kg,
ccl_device_inline Transform lamp_fetch_transform(KernelGlobals kg, int lamp, bool inverse)
{
if (inverse) {
- return kernel_tex_fetch(__lights, lamp).itfm;
+ return kernel_data_fetch(lights, lamp).itfm;
}
else {
- return kernel_tex_fetch(__lights, lamp).tfm;
+ return kernel_data_fetch(lights, lamp).tfm;
}
}
@@ -57,7 +57,7 @@ ccl_device_inline Transform object_fetch_motion_pass_transform(KernelGlobals kg,
enum ObjectVectorTransform type)
{
int offset = object * OBJECT_MOTION_PASS_SIZE + (int)type;
- return kernel_tex_fetch(__object_motion_pass, offset);
+ return kernel_data_fetch(object_motion_pass, offset);
}
/* Motion blurred object transformations */
@@ -65,9 +65,9 @@ ccl_device_inline Transform object_fetch_motion_pass_transform(KernelGlobals kg,
#ifdef __OBJECT_MOTION__
ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals kg, int object, float time)
{
- const uint motion_offset = kernel_tex_fetch(__objects, object).motion_offset;
- ccl_global const DecomposedTransform *motion = &kernel_tex_fetch(__object_motion, motion_offset);
- const uint num_steps = kernel_tex_fetch(__objects, object).numsteps * 2 + 1;
+ const uint motion_offset = kernel_data_fetch(objects, object).motion_offset;
+ ccl_global const DecomposedTransform *motion = &kernel_data_fetch(object_motion, motion_offset);
+ const uint num_steps = kernel_data_fetch(objects, object).numsteps * 2 + 1;
Transform tfm;
transform_motion_array_interpolate(&tfm, motion, num_steps, time);
@@ -80,7 +80,7 @@ ccl_device_inline Transform object_fetch_transform_motion_test(KernelGlobals kg,
float time,
ccl_private Transform *itfm)
{
- int object_flag = kernel_tex_fetch(__object_flag, object);
+ int object_flag = kernel_data_fetch(object_flag, object);
if (object_flag & SD_OBJECT_MOTION) {
/* if we do motion blur */
Transform tfm = object_fetch_transform_motion(kg, object, time);
@@ -259,7 +259,7 @@ ccl_device_inline float3 object_color(KernelGlobals kg, int object)
if (object == OBJECT_NONE)
return make_float3(0.0f, 0.0f, 0.0f);
- ccl_global const KernelObject *kobject = &kernel_tex_fetch(__objects, object);
+ ccl_global const KernelObject *kobject = &kernel_data_fetch(objects, object);
return make_float3(kobject->color[0], kobject->color[1], kobject->color[2]);
}
@@ -270,7 +270,7 @@ ccl_device_inline float object_alpha(KernelGlobals kg, int object)
if (object == OBJECT_NONE)
return 0.0f;
- return kernel_tex_fetch(__objects, object).alpha;
+ return kernel_data_fetch(objects, object).alpha;
}
/* Pass ID number of object */
@@ -280,7 +280,7 @@ ccl_device_inline float object_pass_id(KernelGlobals kg, int object)
if (object == OBJECT_NONE)
return 0.0f;
- return kernel_tex_fetch(__objects, object).pass_id;
+ return kernel_data_fetch(objects, object).pass_id;
}
/* Lightgroup of lamp */
@@ -290,7 +290,7 @@ ccl_device_inline int lamp_lightgroup(KernelGlobals kg, int lamp)
if (lamp == LAMP_NONE)
return LIGHTGROUP_NONE;
- return kernel_tex_fetch(__lights, lamp).lightgroup;
+ return kernel_data_fetch(lights, lamp).lightgroup;
}
/* Lightgroup of object */
@@ -300,7 +300,7 @@ ccl_device_inline int object_lightgroup(KernelGlobals kg, int object)
if (object == OBJECT_NONE)
return LIGHTGROUP_NONE;
- return kernel_tex_fetch(__objects, object).lightgroup;
+ return kernel_data_fetch(objects, object).lightgroup;
}
/* Per lamp random number for shader variation */
@@ -310,7 +310,7 @@ ccl_device_inline float lamp_random_number(KernelGlobals kg, int lamp)
if (lamp == LAMP_NONE)
return 0.0f;
- return kernel_tex_fetch(__lights, lamp).random;
+ return kernel_data_fetch(lights, lamp).random;
}
/* Per object random number for shader variation */
@@ -320,7 +320,7 @@ ccl_device_inline float object_random_number(KernelGlobals kg, int object)
if (object == OBJECT_NONE)
return 0.0f;
- return kernel_tex_fetch(__objects, object).random_number;
+ return kernel_data_fetch(objects, object).random_number;
}
/* Particle ID from which this object was generated */
@@ -330,7 +330,7 @@ ccl_device_inline int object_particle_id(KernelGlobals kg, int object)
if (object == OBJECT_NONE)
return 0;
- return kernel_tex_fetch(__objects, object).particle_index;
+ return kernel_data_fetch(objects, object).particle_index;
}
/* Generated texture coordinate on surface from where object was instanced */
@@ -340,7 +340,7 @@ ccl_device_inline float3 object_dupli_generated(KernelGlobals kg, int object)
if (object == OBJECT_NONE)
return make_float3(0.0f, 0.0f, 0.0f);
- ccl_global const KernelObject *kobject = &kernel_tex_fetch(__objects, object);
+ ccl_global const KernelObject *kobject = &kernel_data_fetch(objects, object);
return make_float3(
kobject->dupli_generated[0], kobject->dupli_generated[1], kobject->dupli_generated[2]);
}
@@ -352,7 +352,7 @@ ccl_device_inline float3 object_dupli_uv(KernelGlobals kg, int object)
if (object == OBJECT_NONE)
return make_float3(0.0f, 0.0f, 0.0f);
- ccl_global const KernelObject *kobject = &kernel_tex_fetch(__objects, object);
+ ccl_global const KernelObject *kobject = &kernel_data_fetch(objects, object);
return make_float3(kobject->dupli_uv[0], kobject->dupli_uv[1], 0.0f);
}
@@ -365,13 +365,13 @@ ccl_device_inline void object_motion_info(KernelGlobals kg,
ccl_private int *numkeys)
{
if (numkeys) {
- *numkeys = kernel_tex_fetch(__objects, object).numkeys;
+ *numkeys = kernel_data_fetch(objects, object).numkeys;
}
if (numsteps)
- *numsteps = kernel_tex_fetch(__objects, object).numsteps;
+ *numsteps = kernel_data_fetch(objects, object).numsteps;
if (numverts)
- *numverts = kernel_tex_fetch(__objects, object).numverts;
+ *numverts = kernel_data_fetch(objects, object).numverts;
}
/* Offset to an objects patch map */
@@ -381,7 +381,7 @@ ccl_device_inline uint object_patch_map_offset(KernelGlobals kg, int object)
if (object == OBJECT_NONE)
return 0;
- return kernel_tex_fetch(__objects, object).patch_map_offset;
+ return kernel_data_fetch(objects, object).patch_map_offset;
}
/* Volume step size */
@@ -392,7 +392,7 @@ ccl_device_inline float object_volume_density(KernelGlobals kg, int object)
return 1.0f;
}
- return kernel_tex_fetch(__objects, object).volume_density;
+ return kernel_data_fetch(objects, object).volume_density;
}
ccl_device_inline float object_volume_step_size(KernelGlobals kg, int object)
@@ -401,14 +401,14 @@ ccl_device_inline float object_volume_step_size(KernelGlobals kg, int object)
return kernel_data.background.volume_step_size;
}
- return kernel_tex_fetch(__object_volume_step, object);
+ return kernel_data_fetch(object_volume_step, object);
}
/* Pass ID for shader */
ccl_device int shader_pass_id(KernelGlobals kg, ccl_private const ShaderData *sd)
{
- return kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).pass_id;
+ return kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).pass_id;
}
/* Cryptomatte ID */
@@ -418,7 +418,7 @@ ccl_device_inline float object_cryptomatte_id(KernelGlobals kg, int object)
if (object == OBJECT_NONE)
return 0.0f;
- return kernel_tex_fetch(__objects, object).cryptomatte_object;
+ return kernel_data_fetch(objects, object).cryptomatte_object;
}
ccl_device_inline float object_cryptomatte_asset_id(KernelGlobals kg, int object)
@@ -426,49 +426,49 @@ ccl_device_inline float object_cryptomatte_asset_id(KernelGlobals kg, int object
if (object == OBJECT_NONE)
return 0;
- return kernel_tex_fetch(__objects, object).cryptomatte_asset;
+ return kernel_data_fetch(objects, object).cryptomatte_asset;
}
/* Particle data from which object was instanced */
ccl_device_inline uint particle_index(KernelGlobals kg, int particle)
{
- return kernel_tex_fetch(__particles, particle).index;
+ return kernel_data_fetch(particles, particle).index;
}
ccl_device float particle_age(KernelGlobals kg, int particle)
{
- return kernel_tex_fetch(__particles, particle).age;
+ return kernel_data_fetch(particles, particle).age;
}
ccl_device float particle_lifetime(KernelGlobals kg, int particle)
{
- return kernel_tex_fetch(__particles, particle).lifetime;
+ return kernel_data_fetch(particles, particle).lifetime;
}
ccl_device float particle_size(KernelGlobals kg, int particle)
{
- return kernel_tex_fetch(__particles, particle).size;
+ return kernel_data_fetch(particles, particle).size;
}
ccl_device float4 particle_rotation(KernelGlobals kg, int particle)
{
- return kernel_tex_fetch(__particles, particle).rotation;
+ return kernel_data_fetch(particles, particle).rotation;
}
ccl_device float3 particle_location(KernelGlobals kg, int particle)
{
- return float4_to_float3(kernel_tex_fetch(__particles, particle).location);
+ return float4_to_float3(kernel_data_fetch(particles, particle).location);
}
ccl_device float3 particle_velocity(KernelGlobals kg, int particle)
{
- return float4_to_float3(kernel_tex_fetch(__particles, particle).velocity);
+ return float4_to_float3(kernel_data_fetch(particles, particle).velocity);
}
ccl_device float3 particle_angular_velocity(KernelGlobals kg, int particle)
{
- return float4_to_float3(kernel_tex_fetch(__particles, particle).angular_velocity);
+ return float4_to_float3(kernel_data_fetch(particles, particle).angular_velocity);
}
/* Object intersection in BVH */
diff --git a/intern/cycles/kernel/geom/patch.h b/intern/cycles/kernel/geom/patch.h
index 1c63a00e30d..ec98ddf51f0 100644
--- a/intern/cycles/kernel/geom/patch.h
+++ b/intern/cycles/kernel/geom/patch.h
@@ -62,7 +62,7 @@ patch_map_find_patch(KernelGlobals kg, int object, int patch, float u, float v)
int quadrant = patch_map_resolve_quadrant(median, &u, &v);
kernel_assert(quadrant >= 0);
- uint child = kernel_tex_fetch(__patches, node + quadrant);
+ uint child = kernel_data_fetch(patches, node + quadrant);
/* is the quadrant a hole? */
if (!(child & PATCH_MAP_NODE_IS_SET)) {
@@ -73,9 +73,9 @@ patch_map_find_patch(KernelGlobals kg, int object, int patch, float u, float v)
uint index = child & PATCH_MAP_NODE_INDEX_MASK;
if (child & PATCH_MAP_NODE_IS_LEAF) {
- handle.array_index = kernel_tex_fetch(__patches, index + 0);
- handle.patch_index = kernel_tex_fetch(__patches, index + 1);
- handle.vert_index = kernel_tex_fetch(__patches, index + 2);
+ handle.array_index = kernel_data_fetch(patches, index + 0);
+ handle.patch_index = kernel_data_fetch(patches, index + 1);
+ handle.vert_index = kernel_data_fetch(patches, index + 2);
return handle;
}
@@ -189,11 +189,11 @@ ccl_device_inline int patch_eval_indices(KernelGlobals kg,
int channel,
int indices[PATCH_MAX_CONTROL_VERTS])
{
- int index_base = kernel_tex_fetch(__patches, handle->array_index + 2) + handle->vert_index;
+ int index_base = kernel_data_fetch(patches, handle->array_index + 2) + handle->vert_index;
/* XXX: regular patches only */
for (int i = 0; i < 16; i++) {
- indices[i] = kernel_tex_fetch(__patches, index_base + i);
+ indices[i] = kernel_data_fetch(patches, index_base + i);
}
return 16;
@@ -209,7 +209,7 @@ ccl_device_inline void patch_eval_basis(KernelGlobals kg,
float weights_du[PATCH_MAX_CONTROL_VERTS],
float weights_dv[PATCH_MAX_CONTROL_VERTS])
{
- uint patch_bits = kernel_tex_fetch(__patches, handle->patch_index + 1); /* read patch param */
+ uint patch_bits = kernel_data_fetch(patches, handle->patch_index + 1); /* read patch param */
float d_scale = 1 << patch_eval_depth(patch_bits);
bool non_quad_root = (patch_bits >> 4) & 0x1;
@@ -287,7 +287,7 @@ ccl_device float patch_eval_float(KernelGlobals kg,
*dv = 0.0f;
for (int i = 0; i < num_control; i++) {
- float v = kernel_tex_fetch(__attributes_float, offset + indices[i]);
+ float v = kernel_data_fetch(attributes_float, offset + indices[i]);
val += v * weights[i];
if (du)
@@ -324,7 +324,7 @@ ccl_device float2 patch_eval_float2(KernelGlobals kg,
*dv = make_float2(0.0f, 0.0f);
for (int i = 0; i < num_control; i++) {
- float2 v = kernel_tex_fetch(__attributes_float2, offset + indices[i]);
+ float2 v = kernel_data_fetch(attributes_float2, offset + indices[i]);
val += v * weights[i];
if (du)
@@ -361,7 +361,7 @@ ccl_device float3 patch_eval_float3(KernelGlobals kg,
*dv = make_float3(0.0f, 0.0f, 0.0f);
for (int i = 0; i < num_control; i++) {
- float3 v = kernel_tex_fetch(__attributes_float3, offset + indices[i]);
+ float3 v = kernel_data_fetch(attributes_float3, offset + indices[i]);
val += v * weights[i];
if (du)
@@ -398,7 +398,7 @@ ccl_device float4 patch_eval_float4(KernelGlobals kg,
*dv = zero_float4();
for (int i = 0; i < num_control; i++) {
- float4 v = kernel_tex_fetch(__attributes_float4, offset + indices[i]);
+ float4 v = kernel_data_fetch(attributes_float4, offset + indices[i]);
val += v * weights[i];
if (du)
@@ -436,7 +436,7 @@ ccl_device float4 patch_eval_uchar4(KernelGlobals kg,
for (int i = 0; i < num_control; i++) {
float4 v = color_srgb_to_linear_v4(
- color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, offset + indices[i])));
+ color_uchar4_to_float4(kernel_data_fetch(attributes_uchar4, offset + indices[i])));
val += v * weights[i];
if (du)
diff --git a/intern/cycles/kernel/geom/point.h b/intern/cycles/kernel/geom/point.h
index ee7eca9e0c6..726d829c329 100644
--- a/intern/cycles/kernel/geom/point.h
+++ b/intern/cycles/kernel/geom/point.h
@@ -26,7 +26,7 @@ ccl_device float point_attribute_float(KernelGlobals kg,
# endif
if (desc.element == ATTR_ELEMENT_VERTEX) {
- return kernel_tex_fetch(__attributes_float, desc.offset + sd->prim);
+ return kernel_data_fetch(attributes_float, desc.offset + sd->prim);
}
else {
return 0.0f;
@@ -47,7 +47,7 @@ ccl_device float2 point_attribute_float2(KernelGlobals kg,
# endif
if (desc.element == ATTR_ELEMENT_VERTEX) {
- return kernel_tex_fetch(__attributes_float2, desc.offset + sd->prim);
+ return kernel_data_fetch(attributes_float2, desc.offset + sd->prim);
}
else {
return make_float2(0.0f, 0.0f);
@@ -68,7 +68,7 @@ ccl_device float3 point_attribute_float3(KernelGlobals kg,
# endif
if (desc.element == ATTR_ELEMENT_VERTEX) {
- return kernel_tex_fetch(__attributes_float3, desc.offset + sd->prim);
+ return kernel_data_fetch(attributes_float3, desc.offset + sd->prim);
}
else {
return make_float3(0.0f, 0.0f, 0.0f);
@@ -89,7 +89,7 @@ ccl_device float4 point_attribute_float4(KernelGlobals kg,
# endif
if (desc.element == ATTR_ELEMENT_VERTEX) {
- return kernel_tex_fetch(__attributes_float4, desc.offset + sd->prim);
+ return kernel_data_fetch(attributes_float4, desc.offset + sd->prim);
}
else {
return zero_float4();
@@ -104,7 +104,7 @@ ccl_device float3 point_position(KernelGlobals kg, ccl_private const ShaderData
/* World space center. */
float3 P = (sd->type & PRIMITIVE_MOTION) ?
float4_to_float3(motion_point(kg, sd->object, sd->prim, sd->time)) :
- float4_to_float3(kernel_tex_fetch(__points, sd->prim));
+ float4_to_float3(kernel_data_fetch(points, sd->prim));
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
object_position_transform(kg, sd, &P);
@@ -122,7 +122,7 @@ ccl_device float point_radius(KernelGlobals kg, ccl_private const ShaderData *sd
{
if (sd->type & PRIMITIVE_POINT) {
/* World space radius. */
- const float r = kernel_tex_fetch(__points, sd->prim).w;
+ const float r = kernel_data_fetch(points, sd->prim).w;
if (sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED) {
return r;
@@ -155,7 +155,7 @@ ccl_device float point_random(KernelGlobals kg, ccl_private const ShaderData *sd
ccl_device float3 point_motion_center_location(KernelGlobals kg, ccl_private const ShaderData *sd)
{
- return float4_to_float3(kernel_tex_fetch(__points, sd->prim));
+ return float4_to_float3(kernel_data_fetch(points, sd->prim));
}
#endif /* __POINTCLOUD__ */
diff --git a/intern/cycles/kernel/geom/point_intersect.h b/intern/cycles/kernel/geom/point_intersect.h
index c7ae72bb488..dfd9d9a015b 100644
--- a/intern/cycles/kernel/geom/point_intersect.h
+++ b/intern/cycles/kernel/geom/point_intersect.h
@@ -63,7 +63,7 @@ ccl_device_forceinline bool point_intersect(KernelGlobals kg,
const int type)
{
const float4 point = (type & PRIMITIVE_MOTION) ? motion_point(kg, object, prim, time) :
- kernel_tex_fetch(__points, prim);
+ kernel_data_fetch(points, prim);
if (!point_intersect_test(point, P, dir, tmax, &isect->t)) {
return false;
@@ -82,7 +82,7 @@ ccl_device_inline void point_shader_setup(KernelGlobals kg,
ccl_private const Intersection *isect,
ccl_private const Ray *ray)
{
- sd->shader = kernel_tex_fetch(__points_shader, isect->prim);
+ sd->shader = kernel_data_fetch(points_shader, isect->prim);
sd->P = ray->P + ray->D * isect->t;
/* Texture coordinates, zero for now. */
@@ -94,7 +94,7 @@ ccl_device_inline void point_shader_setup(KernelGlobals kg,
/* Compute point center for normal. */
float3 center = float4_to_float3((isect->type & PRIMITIVE_MOTION) ?
motion_point(kg, sd->object, sd->prim, sd->time) :
- kernel_tex_fetch(__points, sd->prim));
+ kernel_data_fetch(points, sd->prim));
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
object_position_transform_auto(kg, sd, &center);
}
diff --git a/intern/cycles/kernel/geom/shader_data.h b/intern/cycles/kernel/geom/shader_data.h
index 7a439da427a..e5dbeac5e66 100644
--- a/intern/cycles/kernel/geom/shader_data.h
+++ b/intern/cycles/kernel/geom/shader_data.h
@@ -40,7 +40,7 @@ ccl_device_inline void shader_setup_from_ray(KernelGlobals kg,
sd->ray_length = isect->t;
sd->type = isect->type;
sd->object = isect->object;
- sd->object_flag = kernel_tex_fetch(__object_flag, sd->object);
+ sd->object_flag = kernel_data_fetch(object_flag, sd->object);
sd->prim = isect->prim;
sd->lamp = LAMP_NONE;
sd->flag = 0;
@@ -73,7 +73,7 @@ ccl_device_inline void shader_setup_from_ray(KernelGlobals kg,
if (sd->type == PRIMITIVE_TRIANGLE) {
/* static triangle */
float3 Ng = triangle_normal(kg, sd);
- sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
+ sd->shader = kernel_data_fetch(tri_shader, sd->prim);
/* vectors */
sd->P = triangle_point_from_uv(kg, sd, isect->object, isect->prim, isect->u, isect->v);
@@ -106,7 +106,7 @@ ccl_device_inline void shader_setup_from_ray(KernelGlobals kg,
}
}
- sd->flag = kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+ sd->flag = kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).flags;
/* backfacing test */
bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
@@ -169,10 +169,10 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals kg,
sd->time = time;
sd->ray_length = t;
- sd->flag = kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+ sd->flag = kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).flags;
sd->object_flag = 0;
if (sd->object != OBJECT_NONE) {
- sd->object_flag |= kernel_tex_fetch(__object_flag, sd->object);
+ sd->object_flag |= kernel_data_fetch(object_flag, sd->object);
#ifdef __OBJECT_MOTION__
shader_setup_object_transforms(kg, sd, time);
@@ -264,21 +264,20 @@ ccl_device void shader_setup_from_displace(KernelGlobals kg,
/* force smooth shading for displacement */
shader |= SHADER_SMOOTH_NORMAL;
- shader_setup_from_sample(
- kg,
- sd,
- P,
- Ng,
- I,
- shader,
- object,
- prim,
- u,
- v,
- 0.0f,
- 0.5f,
- !(kernel_tex_fetch(__object_flag, object) & SD_OBJECT_TRANSFORM_APPLIED),
- LAMP_NONE);
+ shader_setup_from_sample(kg,
+ sd,
+ P,
+ Ng,
+ I,
+ shader,
+ object,
+ prim,
+ u,
+ v,
+ 0.0f,
+ 0.5f,
+ !(kernel_data_fetch(object_flag, object) & SD_OBJECT_TRANSFORM_APPLIED),
+ LAMP_NONE);
}
/* ShaderData setup for point on curve. */
@@ -300,18 +299,18 @@ ccl_device void shader_setup_from_curve(KernelGlobals kg,
sd->ray_length = 0.0f;
/* Shader */
- sd->shader = kernel_tex_fetch(__curves, prim).shader_id;
- sd->flag = kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+ sd->shader = kernel_data_fetch(curves, prim).shader_id;
+ sd->flag = kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).flags;
/* Object */
sd->object = object;
- sd->object_flag = kernel_tex_fetch(__object_flag, sd->object);
+ sd->object_flag = kernel_data_fetch(object_flag, sd->object);
#ifdef __OBJECT_MOTION__
shader_setup_object_transforms(kg, sd, sd->time);
#endif
/* Get control points. */
- KernelCurve kcurve = kernel_tex_fetch(__curves, prim);
+ KernelCurve kcurve = kernel_data_fetch(curves, prim);
int k0 = kcurve.first_key + PRIMITIVE_UNPACK_SEGMENT(sd->type);
int k1 = k0 + 1;
@@ -320,10 +319,10 @@ ccl_device void shader_setup_from_curve(KernelGlobals kg,
float4 P_curve[4];
- P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
- P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
- P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
- P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
+ P_curve[0] = kernel_data_fetch(curve_keys, ka);
+ P_curve[1] = kernel_data_fetch(curve_keys, k0);
+ P_curve[2] = kernel_data_fetch(curve_keys, k1);
+ P_curve[3] = kernel_data_fetch(curve_keys, kb);
/* Interpolate position and tangent. */
sd->P = float4_to_float3(catmull_rom_basis_derivative(P_curve, sd->u));
@@ -373,7 +372,7 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals kg,
sd->Ng = -ray_D;
sd->I = -ray_D;
sd->shader = kernel_data.background.surface_shader;
- sd->flag = kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+ sd->flag = kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).flags;
sd->object_flag = 0;
sd->time = ray_time;
sd->ray_length = 0.0f;
diff --git a/intern/cycles/kernel/geom/subd_triangle.h b/intern/cycles/kernel/geom/subd_triangle.h
index 24e1e454b8c..8b73b342e16 100644
--- a/intern/cycles/kernel/geom/subd_triangle.h
+++ b/intern/cycles/kernel/geom/subd_triangle.h
@@ -13,11 +13,11 @@ ccl_device_inline void subd_triangle_patch_uv(KernelGlobals kg,
ccl_private const ShaderData *sd,
float2 uv[3])
{
- uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
+ uint4 tri_vindex = kernel_data_fetch(tri_vindex, sd->prim);
- uv[0] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.x);
- uv[1] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.y);
- uv[2] = kernel_tex_fetch(__tri_patch_uv, tri_vindex.z);
+ uv[0] = kernel_data_fetch(tri_patch_uv, tri_vindex.x);
+ uv[1] = kernel_data_fetch(tri_patch_uv, tri_vindex.y);
+ uv[2] = kernel_data_fetch(tri_patch_uv, tri_vindex.z);
}
/* Vertex indices of patch */
@@ -26,10 +26,10 @@ ccl_device_inline uint4 subd_triangle_patch_indices(KernelGlobals kg, int patch)
{
uint4 indices;
- indices.x = kernel_tex_fetch(__patches, patch + 0);
- indices.y = kernel_tex_fetch(__patches, patch + 1);
- indices.z = kernel_tex_fetch(__patches, patch + 2);
- indices.w = kernel_tex_fetch(__patches, patch + 3);
+ indices.x = kernel_data_fetch(patches, patch + 0);
+ indices.y = kernel_data_fetch(patches, patch + 1);
+ indices.z = kernel_data_fetch(patches, patch + 2);
+ indices.w = kernel_data_fetch(patches, patch + 3);
return indices;
}
@@ -38,14 +38,14 @@ ccl_device_inline uint4 subd_triangle_patch_indices(KernelGlobals kg, int patch)
ccl_device_inline uint subd_triangle_patch_face(KernelGlobals kg, int patch)
{
- return kernel_tex_fetch(__patches, patch + 4);
+ return kernel_data_fetch(patches, patch + 4);
}
/* Number of corners on originating face */
ccl_device_inline uint subd_triangle_patch_num_corners(KernelGlobals kg, int patch)
{
- return kernel_tex_fetch(__patches, patch + 5) & 0xffff;
+ return kernel_data_fetch(patches, patch + 5) & 0xffff;
}
/* Indices of the four corners that are used by the patch */
@@ -54,10 +54,10 @@ ccl_device_inline void subd_triangle_patch_corners(KernelGlobals kg, int patch,
{
uint4 data;
- data.x = kernel_tex_fetch(__patches, patch + 4);
- data.y = kernel_tex_fetch(__patches, patch + 5);
- data.z = kernel_tex_fetch(__patches, patch + 6);
- data.w = kernel_tex_fetch(__patches, patch + 7);
+ data.x = kernel_data_fetch(patches, patch + 4);
+ data.y = kernel_data_fetch(patches, patch + 5);
+ data.z = kernel_data_fetch(patches, patch + 6);
+ data.w = kernel_data_fetch(patches, patch + 7);
int num_corners = data.y & 0xffff;
@@ -141,7 +141,7 @@ ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals kg,
if (dy)
*dy = 0.0f;
- return kernel_tex_fetch(__attributes_float, desc.offset + subd_triangle_patch_face(kg, patch));
+ return kernel_data_fetch(attributes_float, desc.offset + subd_triangle_patch_face(kg, patch));
}
else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
float2 uv[3];
@@ -149,10 +149,10 @@ ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals kg,
uint4 v = subd_triangle_patch_indices(kg, patch);
- float f0 = kernel_tex_fetch(__attributes_float, desc.offset + v.x);
- float f1 = kernel_tex_fetch(__attributes_float, desc.offset + v.y);
- float f2 = kernel_tex_fetch(__attributes_float, desc.offset + v.z);
- float f3 = kernel_tex_fetch(__attributes_float, desc.offset + v.w);
+ float f0 = kernel_data_fetch(attributes_float, desc.offset + v.x);
+ float f1 = kernel_data_fetch(attributes_float, desc.offset + v.y);
+ float f2 = kernel_data_fetch(attributes_float, desc.offset + v.z);
+ float f3 = kernel_data_fetch(attributes_float, desc.offset + v.w);
if (subd_triangle_patch_num_corners(kg, patch) != 4) {
f1 = (f1 + f0) * 0.5f;
@@ -179,10 +179,10 @@ ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals kg,
int corners[4];
subd_triangle_patch_corners(kg, patch, corners);
- float f0 = kernel_tex_fetch(__attributes_float, corners[0] + desc.offset);
- float f1 = kernel_tex_fetch(__attributes_float, corners[1] + desc.offset);
- float f2 = kernel_tex_fetch(__attributes_float, corners[2] + desc.offset);
- float f3 = kernel_tex_fetch(__attributes_float, corners[3] + desc.offset);
+ float f0 = kernel_data_fetch(attributes_float, corners[0] + desc.offset);
+ float f1 = kernel_data_fetch(attributes_float, corners[1] + desc.offset);
+ float f2 = kernel_data_fetch(attributes_float, corners[2] + desc.offset);
+ float f3 = kernel_data_fetch(attributes_float, corners[3] + desc.offset);
if (subd_triangle_patch_num_corners(kg, patch) != 4) {
f1 = (f1 + f0) * 0.5f;
@@ -208,7 +208,7 @@ ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals kg,
if (dy)
*dy = 0.0f;
- return kernel_tex_fetch(__attributes_float, desc.offset);
+ return kernel_data_fetch(attributes_float, desc.offset);
}
else {
if (dx)
@@ -281,8 +281,7 @@ ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals kg,
if (dy)
*dy = make_float2(0.0f, 0.0f);
- return kernel_tex_fetch(__attributes_float2,
- desc.offset + subd_triangle_patch_face(kg, patch));
+ return kernel_data_fetch(attributes_float2, desc.offset + subd_triangle_patch_face(kg, patch));
}
else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
float2 uv[3];
@@ -290,10 +289,10 @@ ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals kg,
uint4 v = subd_triangle_patch_indices(kg, patch);
- float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + v.x);
- float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + v.y);
- float2 f2 = kernel_tex_fetch(__attributes_float2, desc.offset + v.z);
- float2 f3 = kernel_tex_fetch(__attributes_float2, desc.offset + v.w);
+ float2 f0 = kernel_data_fetch(attributes_float2, desc.offset + v.x);
+ float2 f1 = kernel_data_fetch(attributes_float2, desc.offset + v.y);
+ float2 f2 = kernel_data_fetch(attributes_float2, desc.offset + v.z);
+ float2 f3 = kernel_data_fetch(attributes_float2, desc.offset + v.w);
if (subd_triangle_patch_num_corners(kg, patch) != 4) {
f1 = (f1 + f0) * 0.5f;
@@ -322,10 +321,10 @@ ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals kg,
float2 f0, f1, f2, f3;
- f0 = kernel_tex_fetch(__attributes_float2, corners[0] + desc.offset);
- f1 = kernel_tex_fetch(__attributes_float2, corners[1] + desc.offset);
- f2 = kernel_tex_fetch(__attributes_float2, corners[2] + desc.offset);
- f3 = kernel_tex_fetch(__attributes_float2, corners[3] + desc.offset);
+ f0 = kernel_data_fetch(attributes_float2, corners[0] + desc.offset);
+ f1 = kernel_data_fetch(attributes_float2, corners[1] + desc.offset);
+ f2 = kernel_data_fetch(attributes_float2, corners[2] + desc.offset);
+ f3 = kernel_data_fetch(attributes_float2, corners[3] + desc.offset);
if (subd_triangle_patch_num_corners(kg, patch) != 4) {
f1 = (f1 + f0) * 0.5f;
@@ -351,7 +350,7 @@ ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals kg,
if (dy)
*dy = make_float2(0.0f, 0.0f);
- return kernel_tex_fetch(__attributes_float2, desc.offset);
+ return kernel_data_fetch(attributes_float2, desc.offset);
}
else {
if (dx)
@@ -423,8 +422,7 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg,
if (dy)
*dy = make_float3(0.0f, 0.0f, 0.0f);
- return kernel_tex_fetch(__attributes_float3,
- desc.offset + subd_triangle_patch_face(kg, patch));
+ return kernel_data_fetch(attributes_float3, desc.offset + subd_triangle_patch_face(kg, patch));
}
else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
float2 uv[3];
@@ -432,10 +430,10 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg,
uint4 v = subd_triangle_patch_indices(kg, patch);
- float3 f0 = kernel_tex_fetch(__attributes_float3, desc.offset + v.x);
- float3 f1 = kernel_tex_fetch(__attributes_float3, desc.offset + v.y);
- float3 f2 = kernel_tex_fetch(__attributes_float3, desc.offset + v.z);
- float3 f3 = kernel_tex_fetch(__attributes_float3, desc.offset + v.w);
+ float3 f0 = kernel_data_fetch(attributes_float3, desc.offset + v.x);
+ float3 f1 = kernel_data_fetch(attributes_float3, desc.offset + v.y);
+ float3 f2 = kernel_data_fetch(attributes_float3, desc.offset + v.z);
+ float3 f3 = kernel_data_fetch(attributes_float3, desc.offset + v.w);
if (subd_triangle_patch_num_corners(kg, patch) != 4) {
f1 = (f1 + f0) * 0.5f;
@@ -464,10 +462,10 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg,
float3 f0, f1, f2, f3;
- f0 = kernel_tex_fetch(__attributes_float3, corners[0] + desc.offset);
- f1 = kernel_tex_fetch(__attributes_float3, corners[1] + desc.offset);
- f2 = kernel_tex_fetch(__attributes_float3, corners[2] + desc.offset);
- f3 = kernel_tex_fetch(__attributes_float3, corners[3] + desc.offset);
+ f0 = kernel_data_fetch(attributes_float3, corners[0] + desc.offset);
+ f1 = kernel_data_fetch(attributes_float3, corners[1] + desc.offset);
+ f2 = kernel_data_fetch(attributes_float3, corners[2] + desc.offset);
+ f3 = kernel_data_fetch(attributes_float3, corners[3] + desc.offset);
if (subd_triangle_patch_num_corners(kg, patch) != 4) {
f1 = (f1 + f0) * 0.5f;
@@ -493,7 +491,7 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg,
if (dy)
*dy = make_float3(0.0f, 0.0f, 0.0f);
- return kernel_tex_fetch(__attributes_float3, desc.offset);
+ return kernel_data_fetch(attributes_float3, desc.offset);
}
else {
if (dx)
@@ -570,8 +568,7 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg,
if (dy)
*dy = zero_float4();
- return kernel_tex_fetch(__attributes_float4,
- desc.offset + subd_triangle_patch_face(kg, patch));
+ return kernel_data_fetch(attributes_float4, desc.offset + subd_triangle_patch_face(kg, patch));
}
else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
float2 uv[3];
@@ -579,10 +576,10 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg,
uint4 v = subd_triangle_patch_indices(kg, patch);
- float4 f0 = kernel_tex_fetch(__attributes_float4, desc.offset + v.x);
- float4 f1 = kernel_tex_fetch(__attributes_float4, desc.offset + v.y);
- float4 f2 = kernel_tex_fetch(__attributes_float4, desc.offset + v.z);
- float4 f3 = kernel_tex_fetch(__attributes_float4, desc.offset + v.w);
+ float4 f0 = kernel_data_fetch(attributes_float4, desc.offset + v.x);
+ float4 f1 = kernel_data_fetch(attributes_float4, desc.offset + v.y);
+ float4 f2 = kernel_data_fetch(attributes_float4, desc.offset + v.z);
+ float4 f3 = kernel_data_fetch(attributes_float4, desc.offset + v.w);
if (subd_triangle_patch_num_corners(kg, patch) != 4) {
f1 = (f1 + f0) * 0.5f;
@@ -613,19 +610,19 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg,
if (desc.element == ATTR_ELEMENT_CORNER_BYTE) {
f0 = color_srgb_to_linear_v4(
- color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, corners[0] + desc.offset)));
+ color_uchar4_to_float4(kernel_data_fetch(attributes_uchar4, corners[0] + desc.offset)));
f1 = color_srgb_to_linear_v4(
- color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, corners[1] + desc.offset)));
+ color_uchar4_to_float4(kernel_data_fetch(attributes_uchar4, corners[1] + desc.offset)));
f2 = color_srgb_to_linear_v4(
- color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, corners[2] + desc.offset)));
+ color_uchar4_to_float4(kernel_data_fetch(attributes_uchar4, corners[2] + desc.offset)));
f3 = color_srgb_to_linear_v4(
- color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, corners[3] + desc.offset)));
+ color_uchar4_to_float4(kernel_data_fetch(attributes_uchar4, corners[3] + desc.offset)));
}
else {
- f0 = kernel_tex_fetch(__attributes_float4, corners[0] + desc.offset);
- f1 = kernel_tex_fetch(__attributes_float4, corners[1] + desc.offset);
- f2 = kernel_tex_fetch(__attributes_float4, corners[2] + desc.offset);
- f3 = kernel_tex_fetch(__attributes_float4, corners[3] + desc.offset);
+ f0 = kernel_data_fetch(attributes_float4, corners[0] + desc.offset);
+ f1 = kernel_data_fetch(attributes_float4, corners[1] + desc.offset);
+ f2 = kernel_data_fetch(attributes_float4, corners[2] + desc.offset);
+ f3 = kernel_data_fetch(attributes_float4, corners[3] + desc.offset);
}
if (subd_triangle_patch_num_corners(kg, patch) != 4) {
@@ -652,7 +649,7 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg,
if (dy)
*dy = zero_float4();
- return kernel_tex_fetch(__attributes_float4, desc.offset);
+ return kernel_data_fetch(attributes_float4, desc.offset);
}
else {
if (dx)
diff --git a/intern/cycles/kernel/geom/triangle.h b/intern/cycles/kernel/geom/triangle.h
index 8ac7e67ff05..788bfaca7cf 100644
--- a/intern/cycles/kernel/geom/triangle.h
+++ b/intern/cycles/kernel/geom/triangle.h
@@ -15,10 +15,10 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline float3 triangle_normal(KernelGlobals kg, ccl_private ShaderData *sd)
{
/* load triangle vertices */
- const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
- const float3 v0 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0);
- const float3 v1 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1);
- const float3 v2 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2);
+ const uint4 tri_vindex = kernel_data_fetch(tri_vindex, sd->prim);
+ const float3 v0 = kernel_data_fetch(tri_verts, tri_vindex.w + 0);
+ const float3 v1 = kernel_data_fetch(tri_verts, tri_vindex.w + 1);
+ const float3 v2 = kernel_data_fetch(tri_verts, tri_vindex.w + 2);
/* return normal */
if (sd->object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
@@ -40,15 +40,15 @@ ccl_device_inline void triangle_point_normal(KernelGlobals kg,
ccl_private int *shader)
{
/* load triangle vertices */
- const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
- float3 v0 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0);
- float3 v1 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1);
- float3 v2 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2);
+ const uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
+ float3 v0 = kernel_data_fetch(tri_verts, tri_vindex.w + 0);
+ float3 v1 = kernel_data_fetch(tri_verts, tri_vindex.w + 1);
+ float3 v2 = kernel_data_fetch(tri_verts, tri_vindex.w + 2);
/* compute point */
float t = 1.0f - u - v;
*P = (u * v0 + v * v1 + t * v2);
/* get object flags */
- int object_flag = kernel_tex_fetch(__object_flag, object);
+ int object_flag = kernel_data_fetch(object_flag, object);
/* compute normal */
if (object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
*Ng = normalize(cross(v2 - v0, v1 - v0));
@@ -57,17 +57,17 @@ ccl_device_inline void triangle_point_normal(KernelGlobals kg,
*Ng = normalize(cross(v1 - v0, v2 - v0));
}
/* shader`*/
- *shader = kernel_tex_fetch(__tri_shader, prim);
+ *shader = kernel_data_fetch(tri_shader, prim);
}
/* Triangle vertex locations */
ccl_device_inline void triangle_vertices(KernelGlobals kg, int prim, float3 P[3])
{
- const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
- P[0] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0);
- P[1] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1);
- P[2] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2);
+ const uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
+ P[0] = kernel_data_fetch(tri_verts, tri_vindex.w + 0);
+ P[1] = kernel_data_fetch(tri_verts, tri_vindex.w + 1);
+ P[2] = kernel_data_fetch(tri_verts, tri_vindex.w + 2);
}
/* Triangle vertex locations and vertex normals */
@@ -77,13 +77,13 @@ ccl_device_inline void triangle_vertices_and_normals(KernelGlobals kg,
float3 P[3],
float3 N[3])
{
- const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
- P[0] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0);
- P[1] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1);
- P[2] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2);
- N[0] = kernel_tex_fetch(__tri_vnormal, tri_vindex.x);
- N[1] = kernel_tex_fetch(__tri_vnormal, tri_vindex.y);
- N[2] = kernel_tex_fetch(__tri_vnormal, tri_vindex.z);
+ const uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
+ P[0] = kernel_data_fetch(tri_verts, tri_vindex.w + 0);
+ P[1] = kernel_data_fetch(tri_verts, tri_vindex.w + 1);
+ P[2] = kernel_data_fetch(tri_verts, tri_vindex.w + 2);
+ N[0] = kernel_data_fetch(tri_vnormal, tri_vindex.x);
+ N[1] = kernel_data_fetch(tri_vnormal, tri_vindex.y);
+ N[2] = kernel_data_fetch(tri_vnormal, tri_vindex.z);
}
/* Interpolate smooth vertex normal from vertices */
@@ -92,10 +92,10 @@ ccl_device_inline float3
triangle_smooth_normal(KernelGlobals kg, float3 Ng, int prim, float u, float v)
{
/* load triangle vertices */
- const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
- float3 n0 = kernel_tex_fetch(__tri_vnormal, tri_vindex.x);
- float3 n1 = kernel_tex_fetch(__tri_vnormal, tri_vindex.y);
- float3 n2 = kernel_tex_fetch(__tri_vnormal, tri_vindex.z);
+ const uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
+ float3 n0 = kernel_data_fetch(tri_vnormal, tri_vindex.x);
+ float3 n1 = kernel_data_fetch(tri_vnormal, tri_vindex.y);
+ float3 n2 = kernel_data_fetch(tri_vnormal, tri_vindex.z);
float3 N = safe_normalize((1.0f - u - v) * n2 + u * n0 + v * n1);
@@ -106,10 +106,10 @@ ccl_device_inline float3 triangle_smooth_normal_unnormalized(
KernelGlobals kg, ccl_private const ShaderData *sd, float3 Ng, int prim, float u, float v)
{
/* load triangle vertices */
- const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
- float3 n0 = kernel_tex_fetch(__tri_vnormal, tri_vindex.x);
- float3 n1 = kernel_tex_fetch(__tri_vnormal, tri_vindex.y);
- float3 n2 = kernel_tex_fetch(__tri_vnormal, tri_vindex.z);
+ const uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
+ float3 n0 = kernel_data_fetch(tri_vnormal, tri_vindex.x);
+ float3 n1 = kernel_data_fetch(tri_vnormal, tri_vindex.y);
+ float3 n2 = kernel_data_fetch(tri_vnormal, tri_vindex.z);
/* ensure that the normals are in object space */
if (sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED) {
@@ -131,10 +131,10 @@ ccl_device_inline void triangle_dPdudv(KernelGlobals kg,
ccl_private float3 *dPdv)
{
/* fetch triangle vertex coordinates */
- const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
- const float3 p0 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0);
- const float3 p1 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1);
- const float3 p2 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2);
+ const uint4 tri_vindex = kernel_data_fetch(tri_vindex, prim);
+ const float3 p0 = kernel_data_fetch(tri_verts, tri_vindex.w + 0);
+ const float3 p1 = kernel_data_fetch(tri_verts, tri_vindex.w + 1);
+ const float3 p2 = kernel_data_fetch(tri_verts, tri_vindex.w + 2);
/* compute derivatives of P w.r.t. uv */
*dPdu = (p0 - p2);
@@ -153,16 +153,16 @@ ccl_device float triangle_attribute_float(KernelGlobals kg,
float f0, f1, f2;
if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION)) {
- const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
- f0 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.x);
- f1 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.y);
- f2 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.z);
+ const uint4 tri_vindex = kernel_data_fetch(tri_vindex, sd->prim);
+ f0 = kernel_data_fetch(attributes_float, desc.offset + tri_vindex.x);
+ f1 = kernel_data_fetch(attributes_float, desc.offset + tri_vindex.y);
+ f2 = kernel_data_fetch(attributes_float, desc.offset + tri_vindex.z);
}
else {
const int tri = desc.offset + sd->prim * 3;
- f0 = kernel_tex_fetch(__attributes_float, tri + 0);
- f1 = kernel_tex_fetch(__attributes_float, tri + 1);
- f2 = kernel_tex_fetch(__attributes_float, tri + 2);
+ f0 = kernel_data_fetch(attributes_float, tri + 0);
+ f1 = kernel_data_fetch(attributes_float, tri + 1);
+ f2 = kernel_data_fetch(attributes_float, tri + 2);
}
#ifdef __RAY_DIFFERENTIALS__
@@ -185,7 +185,7 @@ ccl_device float triangle_attribute_float(KernelGlobals kg,
if (desc.element & (ATTR_ELEMENT_FACE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) {
const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim :
desc.offset;
- return kernel_tex_fetch(__attributes_float, offset);
+ return kernel_data_fetch(attributes_float, offset);
}
else {
return 0.0f;
@@ -203,16 +203,16 @@ ccl_device float2 triangle_attribute_float2(KernelGlobals kg,
float2 f0, f1, f2;
if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION)) {
- const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
- f0 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.x);
- f1 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.y);
- f2 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.z);
+ const uint4 tri_vindex = kernel_data_fetch(tri_vindex, sd->prim);
+ f0 = kernel_data_fetch(attributes_float2, desc.offset + tri_vindex.x);
+ f1 = kernel_data_fetch(attributes_float2, desc.offset + tri_vindex.y);
+ f2 = kernel_data_fetch(attributes_float2, desc.offset + tri_vindex.z);
}
else {
const int tri = desc.offset + sd->prim * 3;
- f0 = kernel_tex_fetch(__attributes_float2, tri + 0);
- f1 = kernel_tex_fetch(__attributes_float2, tri + 1);
- f2 = kernel_tex_fetch(__attributes_float2, tri + 2);
+ f0 = kernel_data_fetch(attributes_float2, tri + 0);
+ f1 = kernel_data_fetch(attributes_float2, tri + 1);
+ f2 = kernel_data_fetch(attributes_float2, tri + 2);
}
#ifdef __RAY_DIFFERENTIALS__
@@ -235,7 +235,7 @@ ccl_device float2 triangle_attribute_float2(KernelGlobals kg,
if (desc.element & (ATTR_ELEMENT_FACE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) {
const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim :
desc.offset;
- return kernel_tex_fetch(__attributes_float2, offset);
+ return kernel_data_fetch(attributes_float2, offset);
}
else {
return make_float2(0.0f, 0.0f);
@@ -253,16 +253,16 @@ ccl_device float3 triangle_attribute_float3(KernelGlobals kg,
float3 f0, f1, f2;
if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION)) {
- const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
- f0 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.x);
- f1 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.y);
- f2 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.z);
+ const uint4 tri_vindex = kernel_data_fetch(tri_vindex, sd->prim);
+ f0 = kernel_data_fetch(attributes_float3, desc.offset + tri_vindex.x);
+ f1 = kernel_data_fetch(attributes_float3, desc.offset + tri_vindex.y);
+ f2 = kernel_data_fetch(attributes_float3, desc.offset + tri_vindex.z);
}
else {
const int tri = desc.offset + sd->prim * 3;
- f0 = kernel_tex_fetch(__attributes_float3, tri + 0);
- f1 = kernel_tex_fetch(__attributes_float3, tri + 1);
- f2 = kernel_tex_fetch(__attributes_float3, tri + 2);
+ f0 = kernel_data_fetch(attributes_float3, tri + 0);
+ f1 = kernel_data_fetch(attributes_float3, tri + 1);
+ f2 = kernel_data_fetch(attributes_float3, tri + 2);
}
#ifdef __RAY_DIFFERENTIALS__
@@ -285,7 +285,7 @@ ccl_device float3 triangle_attribute_float3(KernelGlobals kg,
if (desc.element & (ATTR_ELEMENT_FACE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) {
const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim :
desc.offset;
- return kernel_tex_fetch(__attributes_float3, offset);
+ return kernel_data_fetch(attributes_float3, offset);
}
else {
return make_float3(0.0f, 0.0f, 0.0f);
@@ -304,25 +304,25 @@ ccl_device float4 triangle_attribute_float4(KernelGlobals kg,
float4 f0, f1, f2;
if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION)) {
- const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
- f0 = kernel_tex_fetch(__attributes_float4, desc.offset + tri_vindex.x);
- f1 = kernel_tex_fetch(__attributes_float4, desc.offset + tri_vindex.y);
- f2 = kernel_tex_fetch(__attributes_float4, desc.offset + tri_vindex.z);
+ const uint4 tri_vindex = kernel_data_fetch(tri_vindex, sd->prim);
+ f0 = kernel_data_fetch(attributes_float4, desc.offset + tri_vindex.x);
+ f1 = kernel_data_fetch(attributes_float4, desc.offset + tri_vindex.y);
+ f2 = kernel_data_fetch(attributes_float4, desc.offset + tri_vindex.z);
}
else {
const int tri = desc.offset + sd->prim * 3;
if (desc.element == ATTR_ELEMENT_CORNER) {
- f0 = kernel_tex_fetch(__attributes_float4, tri + 0);
- f1 = kernel_tex_fetch(__attributes_float4, tri + 1);
- f2 = kernel_tex_fetch(__attributes_float4, tri + 2);
+ f0 = kernel_data_fetch(attributes_float4, tri + 0);
+ f1 = kernel_data_fetch(attributes_float4, tri + 1);
+ f2 = kernel_data_fetch(attributes_float4, tri + 2);
}
else {
f0 = color_srgb_to_linear_v4(
- color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 0)));
+ color_uchar4_to_float4(kernel_data_fetch(attributes_uchar4, tri + 0)));
f1 = color_srgb_to_linear_v4(
- color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 1)));
+ color_uchar4_to_float4(kernel_data_fetch(attributes_uchar4, tri + 1)));
f2 = color_srgb_to_linear_v4(
- color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 2)));
+ color_uchar4_to_float4(kernel_data_fetch(attributes_uchar4, tri + 2)));
}
}
@@ -346,7 +346,7 @@ ccl_device float4 triangle_attribute_float4(KernelGlobals kg,
if (desc.element & (ATTR_ELEMENT_FACE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) {
const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim :
desc.offset;
- return kernel_tex_fetch(__attributes_float4, offset);
+ return kernel_data_fetch(attributes_float4, offset);
}
else {
return zero_float4();
diff --git a/intern/cycles/kernel/geom/triangle_intersect.h b/intern/cycles/kernel/geom/triangle_intersect.h
index fe531e6868a..0c76de9ccc7 100644
--- a/intern/cycles/kernel/geom/triangle_intersect.h
+++ b/intern/cycles/kernel/geom/triangle_intersect.h
@@ -23,17 +23,17 @@ ccl_device_inline bool triangle_intersect(KernelGlobals kg,
int prim,
int prim_addr)
{
- const uint tri_vindex = kernel_tex_fetch(__tri_vindex, prim).w;
- const float3 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
- tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
- tri_c = kernel_tex_fetch(__tri_verts, tri_vindex + 2);
+ const uint tri_vindex = kernel_data_fetch(tri_vindex, prim).w;
+ const float3 tri_a = kernel_data_fetch(tri_verts, tri_vindex + 0),
+ tri_b = kernel_data_fetch(tri_verts, tri_vindex + 1),
+ tri_c = kernel_data_fetch(tri_verts, tri_vindex + 2);
float t, u, v;
if (ray_triangle_intersect(P, dir, tmax, tri_a, tri_b, tri_c, &u, &v, &t)) {
#ifdef __VISIBILITY_FLAG__
/* Visibility flag test. we do it here under the assumption
* that most triangles are culled by node flags.
*/
- if (kernel_tex_fetch(__prim_visibility, prim_addr) & visibility)
+ if (kernel_data_fetch(prim_visibility, prim_addr) & visibility)
#endif
{
isect->object = object;
@@ -66,10 +66,10 @@ ccl_device_inline bool triangle_intersect_local(KernelGlobals kg,
ccl_private uint *lcg_state,
int max_hits)
{
- const uint tri_vindex = kernel_tex_fetch(__tri_vindex, prim).w;
- const float3 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
- tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
- tri_c = kernel_tex_fetch(__tri_verts, tri_vindex + 2);
+ const uint tri_vindex = kernel_data_fetch(tri_vindex, prim).w;
+ const float3 tri_a = kernel_data_fetch(tri_verts, tri_vindex + 0),
+ tri_b = kernel_data_fetch(tri_verts, tri_vindex + 1),
+ tri_c = kernel_data_fetch(tri_verts, tri_vindex + 2);
float t, u, v;
if (!ray_triangle_intersect(P, dir, tmax, tri_a, tri_b, tri_c, &u, &v, &t)) {
return false;
@@ -139,10 +139,10 @@ ccl_device_inline float3 triangle_point_from_uv(KernelGlobals kg,
const float u,
const float v)
{
- const uint tri_vindex = kernel_tex_fetch(__tri_vindex, isect_prim).w;
- const packed_float3 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
- tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
- tri_c = kernel_tex_fetch(__tri_verts, tri_vindex + 2);
+ const uint tri_vindex = kernel_data_fetch(tri_vindex, isect_prim).w;
+ const packed_float3 tri_a = kernel_data_fetch(tri_verts, tri_vindex + 0),
+ tri_b = kernel_data_fetch(tri_verts, tri_vindex + 1),
+ tri_c = kernel_data_fetch(tri_verts, tri_vindex + 2);
float w = 1.0f - u - v;
float3 P = u * tri_a + v * tri_b + w * tri_c;
diff --git a/intern/cycles/kernel/geom/volume.h b/intern/cycles/kernel/geom/volume.h
index 22715dee5bf..3510a905def 100644
--- a/intern/cycles/kernel/geom/volume.h
+++ b/intern/cycles/kernel/geom/volume.h
@@ -62,7 +62,7 @@ ccl_device float4 volume_attribute_float4(KernelGlobals kg,
const AttributeDescriptor desc)
{
if (desc.element & (ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) {
- return kernel_tex_fetch(__attributes_float4, desc.offset);
+ return kernel_data_fetch(attributes_float4, desc.offset);
}
else if (desc.element == ATTR_ELEMENT_VOXEL) {
/* todo: optimize this so we don't have to transform both here and in
diff --git a/intern/cycles/kernel/integrator/init_from_bake.h b/intern/cycles/kernel/integrator/init_from_bake.h
index 0db4241b6e3..7d53bf479bf 100644
--- a/intern/cycles/kernel/integrator/init_from_bake.h
+++ b/intern/cycles/kernel/integrator/init_from_bake.h
@@ -160,7 +160,7 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg,
int shader;
triangle_point_normal(kg, object, prim, u, v, &P, &Ng, &shader);
- const int object_flag = kernel_tex_fetch(__object_flag, object);
+ const int object_flag = kernel_data_fetch(object_flag, object);
if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
P = transform_point_auto(&tfm, P);
@@ -193,7 +193,7 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg,
}
const int shader_index = shader & SHADER_MASK;
- const int shader_flags = kernel_tex_fetch(__shaders, shader_index).flags;
+ const int shader_flags = kernel_data_fetch(shaders, shader_index).flags;
/* Fast path for position and normal passes not affected by shaders. */
if (kernel_data.film.pass_position != PASS_UNUSED) {
diff --git a/intern/cycles/kernel/integrator/intersect_closest.h b/intern/cycles/kernel/integrator/intersect_closest.h
index 2dfac44b414..621aa05f46b 100644
--- a/intern/cycles/kernel/integrator/intersect_closest.h
+++ b/intern/cycles/kernel/integrator/intersect_closest.h
@@ -122,7 +122,7 @@ ccl_device_forceinline void integrator_split_shadow_catcher(
/* Continue with shading shadow catcher surface. */
const int shader = intersection_get_shader(kg, isect);
- const int flags = kernel_tex_fetch(__shaders, shader).flags;
+ const int flags = kernel_data_fetch(shaders, shader).flags;
const bool use_caustics = kernel_data.integrator.use_caustics &&
(object_flags & SD_OBJECT_CAUSTICS);
const bool use_raytrace_kernel = (flags & SD_HAS_RAYTRACE);
@@ -149,7 +149,7 @@ ccl_device_forceinline void integrator_intersect_next_kernel_after_shadow_catche
integrator_state_read_isect(kg, state, &isect);
const int shader = intersection_get_shader(kg, &isect);
- const int flags = kernel_tex_fetch(__shaders, shader).flags;
+ const int flags = kernel_data_fetch(shaders, shader).flags;
const int object_flags = intersection_get_object_flags(kg, &isect);
const bool use_caustics = kernel_data.integrator.use_caustics &&
(object_flags & SD_OBJECT_CAUSTICS);
@@ -203,7 +203,7 @@ ccl_device_forceinline void integrator_intersect_next_kernel(
if (!integrator_state_volume_stack_is_empty(kg, state)) {
const bool hit_surface = hit && !(isect->type & PRIMITIVE_LAMP);
const int shader = (hit_surface) ? intersection_get_shader(kg, isect) : SHADER_NONE;
- const int flags = (hit_surface) ? kernel_tex_fetch(__shaders, shader).flags : 0;
+ const int flags = (hit_surface) ? kernel_data_fetch(shaders, shader).flags : 0;
if (!integrator_intersect_terminate(kg, state, flags)) {
INTEGRATOR_PATH_NEXT(current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME);
@@ -223,7 +223,7 @@ ccl_device_forceinline void integrator_intersect_next_kernel(
else {
/* Hit a surface, continue with surface kernel unless terminated. */
const int shader = intersection_get_shader(kg, isect);
- const int flags = kernel_tex_fetch(__shaders, shader).flags;
+ const int flags = kernel_data_fetch(shaders, shader).flags;
if (!integrator_intersect_terminate(kg, state, flags)) {
const int object_flags = intersection_get_object_flags(kg, isect);
@@ -279,7 +279,7 @@ ccl_device_forceinline void integrator_intersect_next_kernel_after_volume(
else {
/* Hit a surface, continue with surface kernel unless terminated. */
const int shader = intersection_get_shader(kg, isect);
- const int flags = kernel_tex_fetch(__shaders, shader).flags;
+ const int flags = kernel_data_fetch(shaders, shader).flags;
const int object_flags = intersection_get_object_flags(kg, isect);
const bool use_caustics = kernel_data.integrator.use_caustics &&
(object_flags & SD_OBJECT_CAUSTICS);
@@ -332,7 +332,7 @@ ccl_device void integrator_intersect_closest(KernelGlobals kg,
ray.t = kernel_data.integrator.ao_bounces_distance;
if (last_isect_object != OBJECT_NONE) {
- const float object_ao_distance = kernel_tex_fetch(__objects, last_isect_object).ao_distance;
+ const float object_ao_distance = kernel_data_fetch(objects, last_isect_object).ao_distance;
if (object_ao_distance != 0.0f) {
ray.t = object_ao_distance;
}
@@ -366,7 +366,7 @@ ccl_device void integrator_intersect_closest(KernelGlobals kg,
bool from_caustic_caster = false;
bool from_caustic_receiver = false;
if (!(path_flag & PATH_RAY_CAMERA) && last_isect_object != OBJECT_NONE) {
- const int object_flags = kernel_tex_fetch(__object_flag, last_isect_object);
+ const int object_flags = kernel_data_fetch(object_flag, last_isect_object);
from_caustic_receiver = (object_flags & SD_OBJECT_CAUSTICS_RECEIVER);
from_caustic_caster = (object_flags & SD_OBJECT_CAUSTICS_CASTER);
}
diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h
index ad83f82d091..75d30a0aeff 100644
--- a/intern/cycles/kernel/integrator/mnee.h
+++ b/intern/cycles/kernel/integrator/mnee.h
@@ -115,7 +115,7 @@ ccl_device_forceinline void mnee_update_light_sample(KernelGlobals kg,
{
/* correct light sample position/direction and pdf
* NOTE: preserve pdf in area measure */
- const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, ls->lamp);
+ const ccl_global KernelLight *klight = &kernel_data_fetch(lights, ls->lamp);
if (ls->type == LIGHT_POINT || ls->type == LIGHT_SPOT) {
ls->D = normalize_len(ls->P - P, &ls->t);
@@ -154,12 +154,12 @@ ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg,
ccl_private const Intersection *isect,
ccl_private ShaderData *sd_vtx)
{
- sd_vtx->object = (isect->object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, isect->prim) :
+ sd_vtx->object = (isect->object == OBJECT_NONE) ? kernel_data_fetch(prim_object, isect->prim) :
isect->object;
sd_vtx->type = isect->type;
sd_vtx->flag = 0;
- sd_vtx->object_flag = kernel_tex_fetch(__object_flag, sd_vtx->object);
+ sd_vtx->object_flag = kernel_data_fetch(object_flag, sd_vtx->object);
/* Matrices and time. */
shader_setup_object_transforms(kg, sd_vtx, ray->time);
@@ -171,7 +171,7 @@ ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg,
sd_vtx->u = isect->u;
sd_vtx->v = isect->v;
- sd_vtx->shader = kernel_tex_fetch(__tri_shader, sd_vtx->prim);
+ sd_vtx->shader = kernel_data_fetch(tri_shader, sd_vtx->prim);
float3 verts[3];
float3 normals[3];
@@ -509,7 +509,7 @@ ccl_device_forceinline bool mnee_newton_solver(KernelGlobals kg,
break;
int hit_object = (projection_isect.object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, projection_isect.prim) :
+ kernel_data_fetch(prim_object, projection_isect.prim) :
projection_isect.object;
if (hit_object == mv.object) {
@@ -870,7 +870,7 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg,
probe_ray.D = normalize_len(v.p - probe_ray.P, &probe_ray.t);
if (scene_intersect(kg, &probe_ray, PATH_RAY_TRANSMIT, &probe_isect)) {
int hit_object = (probe_isect.object == OBJECT_NONE) ?
- kernel_tex_fetch(__prim_object, probe_isect.prim) :
+ kernel_data_fetch(prim_object, probe_isect.prim) :
probe_isect.object;
/* Test whether the ray hit the appropriate object at its intended location. */
if (hit_object != v.object || fabsf(probe_ray.t - probe_isect.t) > MNEE_MIN_DISTANCE)
diff --git a/intern/cycles/kernel/integrator/shade_background.h b/intern/cycles/kernel/integrator/shade_background.h
index 72ecf67e8a0..4791a963ae6 100644
--- a/intern/cycles/kernel/integrator/shade_background.h
+++ b/intern/cycles/kernel/integrator/shade_background.h
@@ -107,7 +107,7 @@ ccl_device_inline void integrate_background(KernelGlobals kg,
for (int lamp = 0; lamp < kernel_data.integrator.num_all_lights; lamp++) {
/* This path should have been resolved with mnee, it will
* generate a firefly for small lights since it is improbable. */
- const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, lamp);
+ const ccl_global KernelLight *klight = &kernel_data_fetch(lights, lamp);
if (klight->type == LIGHT_BACKGROUND && klight->use_caustics) {
eval_background = false;
break;
@@ -160,7 +160,7 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg,
if (INTEGRATOR_STATE(state, path, mnee) & PATH_MNEE_CULL_LIGHT_CONNECTION) {
/* This path should have been resolved with mnee, it will
* generate a firefly for small lights since it is improbable. */
- const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, lamp);
+ const ccl_global KernelLight *klight = &kernel_data_fetch(lights, lamp);
if (klight->use_caustics)
return;
}
diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h
index ce1398859b7..e0a7f998a3f 100644
--- a/intern/cycles/kernel/integrator/shade_surface.h
+++ b/intern/cycles/kernel/integrator/shade_surface.h
@@ -141,7 +141,7 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
{
if (ls.lamp != LAMP_NONE) {
/* Is this a caustic light? */
- const bool use_caustics = kernel_tex_fetch(__lights, ls.lamp).use_caustics;
+ const bool use_caustics = kernel_data_fetch(lights, ls.lamp).use_caustics;
if (use_caustics) {
/* Are we on a caustic caster? */
if (is_transmission && (sd->object_flag & SD_OBJECT_CAUSTICS_CASTER))
diff --git a/intern/cycles/kernel/integrator/shader_eval.h b/intern/cycles/kernel/integrator/shader_eval.h
index 4da92929366..ed4d973e864 100644
--- a/intern/cycles/kernel/integrator/shader_eval.h
+++ b/intern/cycles/kernel/integrator/shader_eval.h
@@ -528,12 +528,12 @@ ccl_device bool shader_constant_emission_eval(KernelGlobals kg,
ccl_private float3 *eval)
{
int shader_index = shader & SHADER_MASK;
- int shader_flag = kernel_tex_fetch(__shaders, shader_index).flags;
+ int shader_flag = kernel_data_fetch(shaders, shader_index).flags;
if (shader_flag & SD_HAS_CONSTANT_EMISSION) {
- *eval = make_float3(kernel_tex_fetch(__shaders, shader_index).constant_emission[0],
- kernel_tex_fetch(__shaders, shader_index).constant_emission[1],
- kernel_tex_fetch(__shaders, shader_index).constant_emission[2]);
+ *eval = make_float3(kernel_data_fetch(shaders, shader_index).constant_emission[0],
+ kernel_data_fetch(shaders, shader_index).constant_emission[1],
+ kernel_data_fetch(shaders, shader_index).constant_emission[2]);
return true;
}
@@ -821,11 +821,11 @@ ccl_device_inline void shader_eval_volume(KernelGlobals kg,
sd->shader = entry.shader;
sd->flag &= ~SD_SHADER_FLAGS;
- sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+ sd->flag |= kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).flags;
sd->object_flag &= ~SD_OBJECT_FLAGS;
if (sd->object != OBJECT_NONE) {
- sd->object_flag |= kernel_tex_fetch(__object_flag, sd->object);
+ sd->object_flag |= kernel_data_fetch(object_flag, sd->object);
# ifdef __OBJECT_MOTION__
/* todo: this is inefficient for motion blur, we should be
@@ -837,7 +837,7 @@ ccl_device_inline void shader_eval_volume(KernelGlobals kg,
kernel_assert(v_desc.offset != ATTR_STD_NOT_FOUND);
const float3 P = sd->P;
- const float velocity_scale = kernel_tex_fetch(__objects, sd->object).velocity_scale;
+ const float velocity_scale = kernel_data_fetch(objects, sd->object).velocity_scale;
const float time_offset = kernel_data.cam.motion_position == MOTION_POSITION_CENTER ?
0.5f :
0.0f;
@@ -946,7 +946,7 @@ ccl_device void shader_eval_displacement(KernelGlobals kg,
ccl_device float shader_cryptomatte_id(KernelGlobals kg, int shader)
{
- return kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).cryptomatte_id;
+ return kernel_data_fetch(shaders, (shader & SHADER_MASK)).cryptomatte_id;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/integrator/subsurface.h b/intern/cycles/kernel/integrator/subsurface.h
index b449f807290..1e6fcf4aff0 100644
--- a/intern/cycles/kernel/integrator/subsurface.h
+++ b/intern/cycles/kernel/integrator/subsurface.h
@@ -147,7 +147,7 @@ ccl_device_inline bool subsurface_scatter(KernelGlobals kg, IntegratorState stat
/* Update volume stack if needed. */
if (kernel_data.integrator.use_volumes) {
const int object = ss_isect.hits[0].object;
- const int object_flag = kernel_tex_fetch(__object_flag, object);
+ const int object_flag = kernel_data_fetch(object_flag, object);
if (object_flag & SD_OBJECT_INTERSECTS_VOLUME) {
float3 P = INTEGRATOR_STATE(state, ray, P);
@@ -170,7 +170,7 @@ ccl_device_inline bool subsurface_scatter(KernelGlobals kg, IntegratorState stat
INTEGRATOR_STATE_WRITE(state, path, rng_offset) += PRNG_BOUNCE_NUM;
const int shader = intersection_get_shader(kg, &ss_isect.hits[0]);
- const int shader_flags = kernel_tex_fetch(__shaders, shader).flags;
+ const int shader_flags = kernel_data_fetch(shaders, shader).flags;
const int object_flags = intersection_get_object_flags(kg, &ss_isect.hits[0]);
const bool use_caustics = kernel_data.integrator.use_caustics &&
(object_flags & SD_OBJECT_CAUSTICS);
diff --git a/intern/cycles/kernel/integrator/subsurface_disk.h b/intern/cycles/kernel/integrator/subsurface_disk.h
index 34330671748..ae857c50493 100644
--- a/intern/cycles/kernel/integrator/subsurface_disk.h
+++ b/intern/cycles/kernel/integrator/subsurface_disk.h
@@ -113,7 +113,7 @@ ccl_device_inline bool subsurface_disk(KernelGlobals kg,
for (int hit = 0; hit < num_eval_hits; hit++) {
/* Get geometric normal. */
const int object = ss_isect.hits[hit].object;
- const int object_flag = kernel_tex_fetch(__object_flag, object);
+ const int object_flag = kernel_data_fetch(object_flag, object);
float3 hit_Ng = ss_isect.Ng[hit];
if (path_flag & PATH_RAY_SUBSURFACE_BACKFACING) {
hit_Ng = -hit_Ng;
diff --git a/intern/cycles/kernel/integrator/volume_stack.h b/intern/cycles/kernel/integrator/volume_stack.h
index 5256349a0cc..97a0f0f386c 100644
--- a/intern/cycles/kernel/integrator/volume_stack.h
+++ b/intern/cycles/kernel/integrator/volume_stack.h
@@ -133,7 +133,7 @@ ccl_device float volume_stack_step_size(KernelGlobals kg, StackReadOp stack_read
break;
}
- int shader_flag = kernel_tex_fetch(__shaders, (entry.shader & SHADER_MASK)).flags;
+ int shader_flag = kernel_data_fetch(shaders, (entry.shader & SHADER_MASK)).flags;
bool heterogeneous = false;
@@ -146,7 +146,7 @@ ccl_device float volume_stack_step_size(KernelGlobals kg, StackReadOp stack_read
* heterogeneous volume objects may be using the same shader. */
int object = entry.object;
if (object != OBJECT_NONE) {
- int object_flag = kernel_tex_fetch(__object_flag, object);
+ int object_flag = kernel_data_fetch(object_flag, object);
if (object_flag & SD_OBJECT_HAS_VOLUME_ATTRIBUTES) {
heterogeneous = true;
}
@@ -180,7 +180,7 @@ ccl_device VolumeSampleMethod volume_stack_sample_method(KernelGlobals kg, Integ
break;
}
- int shader_flag = kernel_tex_fetch(__shaders, (entry.shader & SHADER_MASK)).flags;
+ int shader_flag = kernel_data_fetch(shaders, (entry.shader & SHADER_MASK)).flags;
if (shader_flag & SD_VOLUME_MIS) {
/* Multiple importance sampling. */
diff --git a/intern/cycles/kernel/light/background.h b/intern/cycles/kernel/light/background.h
index 0cbf7fb76fe..2a97d43c9ce 100644
--- a/intern/cycles/kernel/light/background.h
+++ b/intern/cycles/kernel/light/background.h
@@ -31,7 +31,7 @@ ccl_device float3 background_map_sample(KernelGlobals kg,
int step = count >> 1;
int middle = first + step;
- if (kernel_tex_fetch(__light_background_marginal_cdf, middle).y < randv) {
+ if (kernel_data_fetch(light_background_marginal_cdf, middle).y < randv) {
first = middle + 1;
count -= step + 1;
}
@@ -42,9 +42,9 @@ ccl_device float3 background_map_sample(KernelGlobals kg,
int index_v = max(0, first - 1);
kernel_assert(index_v >= 0 && index_v < res_y);
- float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v);
- float2 cdf_next_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v + 1);
- float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res_y);
+ float2 cdf_v = kernel_data_fetch(light_background_marginal_cdf, index_v);
+ float2 cdf_next_v = kernel_data_fetch(light_background_marginal_cdf, index_v + 1);
+ float2 cdf_last_v = kernel_data_fetch(light_background_marginal_cdf, res_y);
/* importance-sampled V direction */
float dv = inverse_lerp(cdf_v.y, cdf_next_v.y, randv);
@@ -57,7 +57,7 @@ ccl_device float3 background_map_sample(KernelGlobals kg,
int step = count >> 1;
int middle = first + step;
- if (kernel_tex_fetch(__light_background_conditional_cdf, index_v * cdf_width + middle).y <
+ if (kernel_data_fetch(light_background_conditional_cdf, index_v * cdf_width + middle).y <
randu) {
first = middle + 1;
count -= step + 1;
@@ -69,12 +69,12 @@ ccl_device float3 background_map_sample(KernelGlobals kg,
int index_u = max(0, first - 1);
kernel_assert(index_u >= 0 && index_u < res_x);
- float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf,
- index_v * cdf_width + index_u);
- float2 cdf_next_u = kernel_tex_fetch(__light_background_conditional_cdf,
- index_v * cdf_width + index_u + 1);
- float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf,
- index_v * cdf_width + res_x);
+ float2 cdf_u = kernel_data_fetch(light_background_conditional_cdf,
+ index_v * cdf_width + index_u);
+ float2 cdf_next_u = kernel_data_fetch(light_background_conditional_cdf,
+ index_v * cdf_width + index_u + 1);
+ float2 cdf_last_u = kernel_data_fetch(light_background_conditional_cdf,
+ index_v * cdf_width + res_x);
/* importance-sampled U direction */
float du = inverse_lerp(cdf_u.y, cdf_next_u.y, randu);
@@ -112,9 +112,9 @@ ccl_device float background_map_pdf(KernelGlobals kg, float3 direction)
int index_v = clamp(float_to_int(uv.y * res_y), 0, res_y - 1);
/* pdfs in V direction */
- float2 cdf_last_u = kernel_tex_fetch(__light_background_conditional_cdf,
- index_v * cdf_width + res_x);
- float2 cdf_last_v = kernel_tex_fetch(__light_background_marginal_cdf, res_y);
+ float2 cdf_last_u = kernel_data_fetch(light_background_conditional_cdf,
+ index_v * cdf_width + res_x);
+ float2 cdf_last_v = kernel_data_fetch(light_background_marginal_cdf, res_y);
float denom = (M_2PI_F * M_PI_F * sin_theta) * cdf_last_u.x * cdf_last_v.x;
@@ -122,9 +122,9 @@ ccl_device float background_map_pdf(KernelGlobals kg, float3 direction)
return 0.0f;
/* pdfs in U direction */
- float2 cdf_u = kernel_tex_fetch(__light_background_conditional_cdf,
- index_v * cdf_width + index_u);
- float2 cdf_v = kernel_tex_fetch(__light_background_marginal_cdf, index_v);
+ float2 cdf_u = kernel_data_fetch(light_background_conditional_cdf,
+ index_v * cdf_width + index_u);
+ float2 cdf_v = kernel_data_fetch(light_background_marginal_cdf, index_v);
return (cdf_u.x * cdf_v.x) / denom;
}
@@ -133,7 +133,7 @@ ccl_device_inline bool background_portal_data_fetch_and_check_side(
KernelGlobals kg, float3 P, int index, ccl_private float3 *lightpos, ccl_private float3 *dir)
{
int portal = kernel_data.background.portal_offset + index;
- const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, portal);
+ const ccl_global KernelLight *klight = &kernel_data_fetch(lights, portal);
*lightpos = make_float3(klight->co[0], klight->co[1], klight->co[2]);
*dir = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]);
@@ -166,7 +166,7 @@ ccl_device_inline float background_portal_pdf(
num_possible++;
int portal = kernel_data.background.portal_offset + p;
- const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, portal);
+ const ccl_global KernelLight *klight = &kernel_data_fetch(lights, portal);
float3 axisu = make_float3(
klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]);
float3 axisv = make_float3(
@@ -242,7 +242,7 @@ ccl_device float3 background_portal_sample(KernelGlobals kg,
if (portal == 0) {
/* p is the portal to be sampled. */
int portal = kernel_data.background.portal_offset + p;
- const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, portal);
+ const ccl_global KernelLight *klight = &kernel_data_fetch(lights, portal);
float3 axisu = make_float3(
klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]);
float3 axisv = make_float3(
diff --git a/intern/cycles/kernel/light/light.h b/intern/cycles/kernel/light/light.h
index 1df1615ed99..1e7a333d013 100644
--- a/intern/cycles/kernel/light/light.h
+++ b/intern/cycles/kernel/light/light.h
@@ -38,7 +38,7 @@ ccl_device_inline bool light_sample(KernelGlobals kg,
const uint32_t path_flag,
ccl_private LightSample *ls)
{
- const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, lamp);
+ const ccl_global KernelLight *klight = &kernel_data_fetch(lights, lamp);
if (path_flag & PATH_RAY_SHADOW_CATCHER_PASS) {
if (klight->shader_id & SHADER_EXCLUDE_SHADOW_CATCHER) {
return false;
@@ -237,7 +237,7 @@ ccl_device bool lights_intersect(KernelGlobals kg,
const uint32_t path_flag)
{
for (int lamp = 0; lamp < kernel_data.integrator.num_all_lights; lamp++) {
- const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, lamp);
+ const ccl_global KernelLight *klight = &kernel_data_fetch(lights, lamp);
if (path_flag & PATH_RAY_CAMERA) {
if (klight->shader_id & SHADER_EXCLUDE_CAMERA) {
@@ -358,7 +358,7 @@ ccl_device bool light_sample_from_distant_ray(KernelGlobals kg,
const int lamp,
ccl_private LightSample *ccl_restrict ls)
{
- ccl_global const KernelLight *klight = &kernel_tex_fetch(__lights, lamp);
+ ccl_global const KernelLight *klight = &kernel_data_fetch(lights, lamp);
const int shader = klight->shader_id;
const float radius = klight->distant.radius;
const LightType type = (LightType)klight->type;
@@ -433,7 +433,7 @@ ccl_device bool light_sample_from_intersection(KernelGlobals kg,
ccl_private LightSample *ccl_restrict ls)
{
const int lamp = isect->prim;
- ccl_global const KernelLight *klight = &kernel_tex_fetch(__lights, lamp);
+ ccl_global const KernelLight *klight = &kernel_data_fetch(lights, lamp);
LightType type = (LightType)klight->type;
ls->type = type;
ls->shader = klight->shader_id;
@@ -562,7 +562,7 @@ ccl_device_inline bool triangle_world_space_vertices(
KernelGlobals kg, int object, int prim, float time, float3 V[3])
{
bool has_motion = false;
- const int object_flag = kernel_tex_fetch(__object_flag, object);
+ const int object_flag = kernel_data_fetch(object_flag, object);
if (object_flag & SD_OBJECT_HAS_VERTEX_MOTION && time >= 0.0f) {
motion_triangle_vertices(kg, object, prim, time, V);
@@ -699,12 +699,12 @@ ccl_device_forceinline void triangle_light_sample(KernelGlobals kg,
float area = 0.5f * Nl;
/* flip normal if necessary */
- const int object_flag = kernel_tex_fetch(__object_flag, object);
+ const int object_flag = kernel_data_fetch(object_flag, object);
if (object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
ls->Ng = -ls->Ng;
}
ls->eval_fac = 1.0f;
- ls->shader = kernel_tex_fetch(__tri_shader, prim);
+ ls->shader = kernel_data_fetch(tri_shader, prim);
ls->object = object;
ls->prim = prim;
ls->lamp = LAMP_NONE;
@@ -845,7 +845,7 @@ ccl_device int light_distribution_sample(KernelGlobals kg, ccl_private float *ra
int half_len = len >> 1;
int middle = first + half_len;
- if (r < kernel_tex_fetch(__light_distribution, middle).totarea) {
+ if (r < kernel_data_fetch(light_distribution, middle).totarea) {
len = half_len;
}
else {
@@ -860,8 +860,8 @@ ccl_device int light_distribution_sample(KernelGlobals kg, ccl_private float *ra
/* Rescale to reuse random number. this helps the 2D samples within
* each area light be stratified as well. */
- float distr_min = kernel_tex_fetch(__light_distribution, index).totarea;
- float distr_max = kernel_tex_fetch(__light_distribution, index + 1).totarea;
+ float distr_min = kernel_data_fetch(light_distribution, index).totarea;
+ float distr_max = kernel_data_fetch(light_distribution, index + 1).totarea;
*randu = (r - distr_min) / (distr_max - distr_min);
return index;
@@ -871,7 +871,7 @@ ccl_device int light_distribution_sample(KernelGlobals kg, ccl_private float *ra
ccl_device_inline bool light_select_reached_max_bounces(KernelGlobals kg, int index, int bounce)
{
- return (bounce > kernel_tex_fetch(__lights, index).max_bounces);
+ return (bounce > kernel_data_fetch(lights, index).max_bounces);
}
template<bool in_volume_segment>
@@ -886,8 +886,8 @@ ccl_device_noinline bool light_distribution_sample(KernelGlobals kg,
{
/* Sample light index from distribution. */
const int index = light_distribution_sample(kg, &randu);
- ccl_global const KernelLightDistribution *kdistribution = &kernel_tex_fetch(__light_distribution,
- index);
+ ccl_global const KernelLightDistribution *kdistribution = &kernel_data_fetch(light_distribution,
+ index);
const int prim = kdistribution->prim;
if (prim >= 0) {
@@ -896,7 +896,7 @@ ccl_device_noinline bool light_distribution_sample(KernelGlobals kg,
/* Exclude synthetic meshes from shadow catcher pass. */
if ((path_flag & PATH_RAY_SHADOW_CATCHER_PASS) &&
- !(kernel_tex_fetch(__object_flag, object) & SD_OBJECT_SHADOW_CATCHER)) {
+ !(kernel_data_fetch(object_flag, object) & SD_OBJECT_SHADOW_CATCHER)) {
return false;
}
diff --git a/intern/cycles/kernel/light/sample.h b/intern/cycles/kernel/light/sample.h
index 9bbbd5b0d10..ea7b9950268 100644
--- a/intern/cycles/kernel/light/sample.h
+++ b/intern/cycles/kernel/light/sample.h
@@ -81,7 +81,7 @@ light_sample_shader_eval(KernelGlobals kg,
eval *= ls->eval_fac;
if (ls->lamp != LAMP_NONE) {
- ccl_global const KernelLight *klight = &kernel_tex_fetch(__lights, ls->lamp);
+ ccl_global const KernelLight *klight = &kernel_data_fetch(lights, ls->lamp);
eval *= make_float3(klight->strength[0], klight->strength[1], klight->strength[2]);
}
@@ -187,7 +187,7 @@ ccl_device_inline float3 shadow_ray_offset(KernelGlobals kg,
if ((sd->type & PRIMITIVE_TRIANGLE) && (sd->shader & SHADER_SMOOTH_NORMAL)) {
const float offset_cutoff =
- kernel_tex_fetch(__objects, sd->object).shadow_terminator_geometry_offset;
+ kernel_data_fetch(objects, sd->object).shadow_terminator_geometry_offset;
/* Do ray offset (heavy stuff) only for close to be terminated triangles:
* offset_cutoff = 0.1f means that 10-20% of rays will be affected. Also
* make a smooth transition near the threshold. */
diff --git a/intern/cycles/kernel/osl/services.cpp b/intern/cycles/kernel/osl/services.cpp
index e2e10b5b83f..6e75ae54f33 100644
--- a/intern/cycles/kernel/osl/services.cpp
+++ b/intern/cycles/kernel/osl/services.cpp
@@ -132,7 +132,7 @@ OSLRenderServices::OSLRenderServices(OSL::TextureSystem *texture_system)
OSLRenderServices::~OSLRenderServices()
{
if (texture_system) {
- VLOG(2) << "OSL texture system stats:\n" << texture_system->getstats();
+ VLOG_INFO << "OSL texture system stats:\n" << texture_system->getstats();
}
}
diff --git a/intern/cycles/kernel/sample/jitter.h b/intern/cycles/kernel/sample/jitter.h
index b8da94248a4..b5cfa624406 100644
--- a/intern/cycles/kernel/sample/jitter.h
+++ b/intern/cycles/kernel/sample/jitter.h
@@ -97,7 +97,7 @@ ccl_device float pmj_sample_1D(KernelGlobals kg, uint sample, uint rng_hash, uin
* the x part is used for even dims and the y for odd. */
int index = 2 * ((dim >> 1) * NUM_PMJ_SAMPLES + (s % NUM_PMJ_SAMPLES)) + (dim & 1);
- float fx = kernel_tex_fetch(__sample_pattern_lut, index);
+ float fx = kernel_data_fetch(sample_pattern_lut, index);
#ifndef _NO_CRANLEY_PATTERSON_ROTATION_
/* Use Cranley-Patterson rotation to displace the sample pattern. */
@@ -154,8 +154,8 @@ ccl_device void pmj_sample_2D(KernelGlobals kg,
uint dim = d % NUM_PMJ_PATTERNS;
int index = 2 * (dim * NUM_PMJ_SAMPLES + (s % NUM_PMJ_SAMPLES));
- float fx = kernel_tex_fetch(__sample_pattern_lut, index);
- float fy = kernel_tex_fetch(__sample_pattern_lut, index + 1);
+ float fx = kernel_data_fetch(sample_pattern_lut, index);
+ float fy = kernel_data_fetch(sample_pattern_lut, index + 1);
#ifndef _NO_CRANLEY_PATTERSON_ROTATION_
/* Use Cranley-Patterson rotation to displace the sample pattern. */
diff --git a/intern/cycles/kernel/sample/pattern.h b/intern/cycles/kernel/sample/pattern.h
index 1e66f39ede2..89500d51872 100644
--- a/intern/cycles/kernel/sample/pattern.h
+++ b/intern/cycles/kernel/sample/pattern.h
@@ -32,7 +32,7 @@ ccl_device uint sobol_dimension(KernelGlobals kg, int index, int dimension)
uint i = index + SOBOL_SKIP;
for (int j = 0, x; (x = find_first_set(i)); i >>= x) {
j += x;
- result ^= __float_as_uint(kernel_tex_fetch(__sample_pattern_lut, 32 * dimension + j - 1));
+ result ^= __float_as_uint(kernel_data_fetch(sample_pattern_lut, 32 * dimension + j - 1));
}
return result;
}
diff --git a/intern/cycles/kernel/svm/bevel.h b/intern/cycles/kernel/svm/bevel.h
index 5abffe1c771..f79bcae5cd2 100644
--- a/intern/cycles/kernel/svm/bevel.h
+++ b/intern/cycles/kernel/svm/bevel.h
@@ -222,7 +222,7 @@ ccl_device float3 svm_bevel(
/* Get geometric normal. */
float3 hit_Ng = isect.Ng[hit];
int object = isect.hits[hit].object;
- int object_flag = kernel_tex_fetch(__object_flag, object);
+ int object_flag = kernel_data_fetch(object_flag, object);
if (object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
hit_Ng = -hit_Ng;
}
@@ -230,7 +230,7 @@ ccl_device float3 svm_bevel(
/* Compute smooth normal. */
float3 N = hit_Ng;
int prim = isect.hits[hit].prim;
- int shader = kernel_tex_fetch(__tri_shader, prim);
+ int shader = kernel_data_fetch(tri_shader, prim);
if (shader & SHADER_SMOOTH_NORMAL) {
float u = isect.hits[hit].u;
diff --git a/intern/cycles/kernel/svm/ies.h b/intern/cycles/kernel/svm/ies.h
index 201d88101cd..3648cb580d5 100644
--- a/intern/cycles/kernel/svm/ies.h
+++ b/intern/cycles/kernel/svm/ies.h
@@ -17,7 +17,7 @@ ccl_device_inline float interpolate_ies_vertical(
* Therefore, the assumption is made that the light is going to be symmetrical, which means that
* we can just take the corresponding value at the current horizontal coordinate. */
-#define IES_LOOKUP(v) kernel_tex_fetch(__ies, ofs + h * v_num + (v))
+#define IES_LOOKUP(v) kernel_data_fetch(ies, ofs + h * v_num + (v))
/* If v is zero, assume symmetry and read at v=1 instead of v=-1. */
float a = IES_LOOKUP((v == 0) ? 1 : v - 1);
float b = IES_LOOKUP(v);
@@ -31,16 +31,16 @@ ccl_device_inline float interpolate_ies_vertical(
ccl_device_inline float kernel_ies_interp(KernelGlobals kg, int slot, float h_angle, float v_angle)
{
/* Find offset of the IES data in the table. */
- int ofs = __float_as_int(kernel_tex_fetch(__ies, slot));
+ int ofs = __float_as_int(kernel_data_fetch(ies, slot));
if (ofs == -1) {
return 100.0f;
}
- int h_num = __float_as_int(kernel_tex_fetch(__ies, ofs++));
- int v_num = __float_as_int(kernel_tex_fetch(__ies, ofs++));
+ int h_num = __float_as_int(kernel_data_fetch(ies, ofs++));
+ int v_num = __float_as_int(kernel_data_fetch(ies, ofs++));
-#define IES_LOOKUP_ANGLE_H(h) kernel_tex_fetch(__ies, ofs + (h))
-#define IES_LOOKUP_ANGLE_V(v) kernel_tex_fetch(__ies, ofs + h_num + (v))
+#define IES_LOOKUP_ANGLE_H(h) kernel_data_fetch(ies, ofs + (h))
+#define IES_LOOKUP_ANGLE_V(v) kernel_data_fetch(ies, ofs + h_num + (v))
/* Check whether the angle is within the bounds of the IES texture. */
if (v_angle >= IES_LOOKUP_ANGLE_V(v_num - 1)) {
diff --git a/intern/cycles/kernel/svm/ramp.h b/intern/cycles/kernel/svm/ramp.h
index 342b15da9ed..0df9268bd9c 100644
--- a/intern/cycles/kernel/svm/ramp.h
+++ b/intern/cycles/kernel/svm/ramp.h
@@ -9,7 +9,7 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline float fetch_float(KernelGlobals kg, int offset)
{
- uint4 node = kernel_tex_fetch(__svm_nodes, offset);
+ uint4 node = kernel_data_fetch(svm_nodes, offset);
return __uint_as_float(node.x);
}
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 5def943c87f..624ef810e85 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -95,14 +95,14 @@ ccl_device_inline bool stack_valid(uint a)
ccl_device_inline uint4 read_node(KernelGlobals kg, ccl_private int *offset)
{
- uint4 node = kernel_tex_fetch(__svm_nodes, *offset);
+ uint4 node = kernel_data_fetch(svm_nodes, *offset);
(*offset)++;
return node;
}
ccl_device_inline float4 read_node_float(KernelGlobals kg, ccl_private int *offset)
{
- uint4 node = kernel_tex_fetch(__svm_nodes, *offset);
+ uint4 node = kernel_data_fetch(svm_nodes, *offset);
float4 f = make_float4(__uint_as_float(node.x),
__uint_as_float(node.y),
__uint_as_float(node.z),
@@ -113,7 +113,7 @@ ccl_device_inline float4 read_node_float(KernelGlobals kg, ccl_private int *offs
ccl_device_inline float4 fetch_node_float(KernelGlobals kg, int offset)
{
- uint4 node = kernel_tex_fetch(__svm_nodes, offset);
+ uint4 node = kernel_data_fetch(svm_nodes, offset);
return make_float4(__uint_as_float(node.x),
__uint_as_float(node.y),
__uint_as_float(node.z),
diff --git a/intern/cycles/kernel/textures.h b/intern/cycles/kernel/textures.h
deleted file mode 100644
index 7deb589a0a9..00000000000
--- a/intern/cycles/kernel/textures.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* SPDX-License-Identifier: Apache-2.0
- * Copyright 2011-2022 Blender Foundation */
-
-#ifndef KERNEL_TEX
-# define KERNEL_TEX(type, name)
-#endif
-
-/* BVH2, not used for OptiX or Embree. */
-KERNEL_TEX(float4, __bvh_nodes)
-KERNEL_TEX(float4, __bvh_leaf_nodes)
-KERNEL_TEX(uint, __prim_type)
-KERNEL_TEX(uint, __prim_visibility)
-KERNEL_TEX(uint, __prim_index)
-KERNEL_TEX(uint, __prim_object)
-KERNEL_TEX(uint, __object_node)
-KERNEL_TEX(float2, __prim_time)
-
-/* objects */
-KERNEL_TEX(KernelObject, __objects)
-KERNEL_TEX(Transform, __object_motion_pass)
-KERNEL_TEX(DecomposedTransform, __object_motion)
-KERNEL_TEX(uint, __object_flag)
-KERNEL_TEX(float, __object_volume_step)
-KERNEL_TEX(uint, __object_prim_offset)
-
-/* cameras */
-KERNEL_TEX(DecomposedTransform, __camera_motion)
-
-/* triangles */
-KERNEL_TEX(uint, __tri_shader)
-KERNEL_TEX(packed_float3, __tri_vnormal)
-KERNEL_TEX(uint4, __tri_vindex)
-KERNEL_TEX(uint, __tri_patch)
-KERNEL_TEX(float2, __tri_patch_uv)
-KERNEL_TEX(packed_float3, __tri_verts)
-
-/* curves */
-KERNEL_TEX(KernelCurve, __curves)
-KERNEL_TEX(float4, __curve_keys)
-KERNEL_TEX(KernelCurveSegment, __curve_segments)
-
-/* patches */
-KERNEL_TEX(uint, __patches)
-
-/* pointclouds */
-KERNEL_TEX(float4, __points)
-KERNEL_TEX(uint, __points_shader)
-
-/* attributes */
-KERNEL_TEX(uint4, __attributes_map)
-KERNEL_TEX(float, __attributes_float)
-KERNEL_TEX(float2, __attributes_float2)
-KERNEL_TEX(packed_float3, __attributes_float3)
-KERNEL_TEX(float4, __attributes_float4)
-KERNEL_TEX(uchar4, __attributes_uchar4)
-
-/* lights */
-KERNEL_TEX(KernelLightDistribution, __light_distribution)
-KERNEL_TEX(KernelLight, __lights)
-KERNEL_TEX(float2, __light_background_marginal_cdf)
-KERNEL_TEX(float2, __light_background_conditional_cdf)
-
-/* particles */
-KERNEL_TEX(KernelParticle, __particles)
-
-/* shaders */
-KERNEL_TEX(uint4, __svm_nodes)
-KERNEL_TEX(KernelShader, __shaders)
-
-/* lookup tables */
-KERNEL_TEX(float, __lookup_table)
-
-/* sobol */
-KERNEL_TEX(float, __sample_pattern_lut)
-
-/* image textures */
-KERNEL_TEX(TextureInfo, __texture_info)
-
-/* ies lights */
-KERNEL_TEX(float, __ies)
-
-#undef KERNEL_TEX
diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h
index b1ca379bab8..ad022716207 100644
--- a/intern/cycles/kernel/types.h
+++ b/intern/cycles/kernel/types.h
@@ -670,6 +670,16 @@ typedef struct AttributeDescriptor {
int offset;
} AttributeDescriptor;
+/* For looking up attributes on objects and geometry. */
+typedef struct AttributeMap {
+ uint id; /* Global unique identifier. */
+ uint element; /* AttributeElement. */
+ int offset; /* Offset into __attributes global arrays. */
+ uint8_t type; /* NodeAttributeType. */
+ uint8_t flags; /* AttributeFlag. */
+ uint8_t pad[2];
+} AttributeMap;
+
/* Closure data */
#ifndef __MAX_CLOSURE__
diff --git a/intern/cycles/kernel/util/lookup_table.h b/intern/cycles/kernel/util/lookup_table.h
index e19e2ce5bd1..4db4dadab0e 100644
--- a/intern/cycles/kernel/util/lookup_table.h
+++ b/intern/cycles/kernel/util/lookup_table.h
@@ -15,11 +15,11 @@ ccl_device float lookup_table_read(KernelGlobals kg, float x, int offset, int si
int nindex = min(index + 1, size - 1);
float t = x - index;
- float data0 = kernel_tex_fetch(__lookup_table, index + offset);
+ float data0 = kernel_data_fetch(lookup_table, index + offset);
if (t == 0.0f)
return data0;
- float data1 = kernel_tex_fetch(__lookup_table, nindex + offset);
+ float data1 = kernel_data_fetch(lookup_table, nindex + offset);
return (1.0f - t) * data0 + t * data1;
}
diff --git a/intern/cycles/scene/alembic.cpp b/intern/cycles/scene/alembic.cpp
index c1e2d306fcc..e6f39bf8625 100644
--- a/intern/cycles/scene/alembic.cpp
+++ b/intern/cycles/scene/alembic.cpp
@@ -1514,7 +1514,7 @@ void AlembicProcedural::build_caches(Progress &progress)
}
}
- VLOG(1) << "AlembicProcedural memory usage : " << string_human_readable_size(memory_used);
+ VLOG_WORK << "AlembicProcedural memory usage : " << string_human_readable_size(memory_used);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/scene/camera.cpp b/intern/cycles/scene/camera.cpp
index 710f1c5ee90..eec269ab542 100644
--- a/intern/cycles/scene/camera.cpp
+++ b/intern/cycles/scene/camera.cpp
@@ -530,7 +530,7 @@ void Camera::device_update_volume(Device * /*device*/, DeviceScene *dscene, Scen
if (object->get_geometry()->has_volume &&
viewplane_boundbox.intersects(object->bounds)) {
/* TODO(sergey): Consider adding more grained check. */
- VLOG(1) << "Detected camera inside volume.";
+ VLOG_INFO << "Detected camera inside volume.";
kcam->is_inside_volume = 1;
parallel_for_cancel();
break;
@@ -539,7 +539,7 @@ void Camera::device_update_volume(Device * /*device*/, DeviceScene *dscene, Scen
});
if (!kcam->is_inside_volume) {
- VLOG(1) << "Camera is outside of the volume.";
+ VLOG_INFO << "Camera is outside of the volume.";
}
}
diff --git a/intern/cycles/scene/colorspace.cpp b/intern/cycles/scene/colorspace.cpp
index f87b4c62ab2..189e3bc752d 100644
--- a/intern/cycles/scene/colorspace.cpp
+++ b/intern/cycles/scene/colorspace.cpp
@@ -55,8 +55,8 @@ ColorSpaceProcessor *ColorSpaceManager::get_processor(ustring colorspace)
}
catch (OCIO::Exception &exception) {
cached_processors[colorspace] = OCIO::ConstProcessorRcPtr();
- VLOG(1) << "Colorspace " << colorspace.c_str()
- << " can't be converted to scene_linear: " << exception.what();
+ VLOG_WARNING << "Colorspace " << colorspace.c_str()
+ << " can't be converted to scene_linear: " << exception.what();
}
}
@@ -132,12 +132,12 @@ ustring ColorSpaceManager::detect_known_colorspace(ustring colorspace,
thread_scoped_lock cache_lock(cache_colorspaces_mutex);
if (is_scene_linear) {
- VLOG(1) << "Colorspace " << colorspace.string() << " is no-op";
+ VLOG_INFO << "Colorspace " << colorspace.string() << " is no-op";
cached_colorspaces[colorspace] = u_colorspace_raw;
return u_colorspace_raw;
}
else if (is_srgb) {
- VLOG(1) << "Colorspace " << colorspace.string() << " is sRGB";
+ VLOG_INFO << "Colorspace " << colorspace.string() << " is sRGB";
cached_colorspaces[colorspace] = u_colorspace_srgb;
return u_colorspace_srgb;
}
@@ -146,22 +146,23 @@ ustring ColorSpaceManager::detect_known_colorspace(ustring colorspace,
if (!get_processor(colorspace)) {
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
if (!config || !config->getColorSpace(colorspace.c_str())) {
- VLOG(1) << "Colorspace " << colorspace.c_str() << " not found, using raw instead";
+ VLOG_WARNING << "Colorspace " << colorspace.c_str() << " not found, using raw instead";
}
else {
- VLOG(1) << "Colorspace " << colorspace.c_str()
- << " can't be converted to scene_linear, using raw instead";
+ VLOG_WARNING << "Colorspace " << colorspace.c_str()
+ << " can't be converted to scene_linear, using raw instead";
}
cached_colorspaces[colorspace] = u_colorspace_raw;
return u_colorspace_raw;
}
/* Convert to/from colorspace with OpenColorIO. */
- VLOG(1) << "Colorspace " << colorspace.string() << " handled through OpenColorIO";
+ VLOG_INFO << "Colorspace " << colorspace.string() << " handled through OpenColorIO";
cached_colorspaces[colorspace] = colorspace;
return colorspace;
#else
- VLOG(1) << "Colorspace " << colorspace.c_str() << " not available, built without OpenColorIO";
+ VLOG_WARNING << "Colorspace " << colorspace.c_str()
+ << " not available, built without OpenColorIO";
return u_colorspace_raw;
#endif
}
diff --git a/intern/cycles/scene/constant_fold.cpp b/intern/cycles/scene/constant_fold.cpp
index 46ffbe9043a..4bce5661f9b 100644
--- a/intern/cycles/scene/constant_fold.cpp
+++ b/intern/cycles/scene/constant_fold.cpp
@@ -30,8 +30,8 @@ bool ConstantFolder::all_inputs_constant() const
void ConstantFolder::make_constant(float value) const
{
- VLOG(3) << "Folding " << node->name << "::" << output->name() << " to constant (" << value
- << ").";
+ VLOG_DEBUG << "Folding " << node->name << "::" << output->name() << " to constant (" << value
+ << ").";
foreach (ShaderInput *sock, output->links) {
sock->set(value);
@@ -43,7 +43,8 @@ void ConstantFolder::make_constant(float value) const
void ConstantFolder::make_constant(float3 value) const
{
- VLOG(3) << "Folding " << node->name << "::" << output->name() << " to constant " << value << ".";
+ VLOG_DEBUG << "Folding " << node->name << "::" << output->name() << " to constant " << value
+ << ".";
foreach (ShaderInput *sock, output->links) {
sock->set(value);
@@ -99,8 +100,8 @@ void ConstantFolder::bypass(ShaderOutput *new_output) const
{
assert(new_output);
- VLOG(3) << "Folding " << node->name << "::" << output->name() << " to socket "
- << new_output->parent->name << "::" << new_output->name() << ".";
+ VLOG_DEBUG << "Folding " << node->name << "::" << output->name() << " to socket "
+ << new_output->parent->name << "::" << new_output->name() << ".";
/* Remove all outgoing links from socket and connect them to new_output instead.
* The graph->relink method affects node inputs, so it's not safe to use in constant
@@ -118,7 +119,7 @@ void ConstantFolder::discard() const
{
assert(output->type() == SocketType::CLOSURE);
- VLOG(3) << "Discarding closure " << node->name << ".";
+ VLOG_DEBUG << "Discarding closure " << node->name << ".";
graph->disconnect(output);
}
diff --git a/intern/cycles/scene/film.cpp b/intern/cycles/scene/film.cpp
index 7f69df7b321..8239ee84b82 100644
--- a/intern/cycles/scene/film.cpp
+++ b/intern/cycles/scene/film.cpp
@@ -152,7 +152,7 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
KernelFilm *kfilm = &dscene->data.film;
- /* update __data */
+ /* update data */
kfilm->exposure = exposure;
kfilm->pass_alpha_threshold = pass_alpha_threshold;
kfilm->pass_flag = 0;
@@ -580,10 +580,10 @@ void Film::update_passes(Scene *scene, bool add_sample_count_pass)
tag_modified();
/* Debug logging. */
- if (VLOG_IS_ON(2)) {
- VLOG(2) << "Effective scene passes:";
+ if (VLOG_INFO_IS_ON) {
+ VLOG_INFO << "Effective scene passes:";
for (const Pass *pass : scene->passes) {
- VLOG(2) << "- " << *pass;
+ VLOG_INFO << "- " << *pass;
}
}
}
diff --git a/intern/cycles/scene/geometry.cpp b/intern/cycles/scene/geometry.cpp
index 9152abacbdb..bdc8839e277 100644
--- a/intern/cycles/scene/geometry.cpp
+++ b/intern/cycles/scene/geometry.cpp
@@ -407,43 +407,47 @@ void GeometryManager::update_osl_attributes(Device *device,
/* Generate a normal attribute map entry from an attribute descriptor. */
static void emit_attribute_map_entry(
- uint4 *attr_map, int index, uint id, TypeDesc type, const AttributeDescriptor &desc)
+ AttributeMap *attr_map, int index, uint id, TypeDesc type, const AttributeDescriptor &desc)
{
- attr_map[index].x = id;
- attr_map[index].y = desc.element;
- attr_map[index].z = as_uint(desc.offset);
+ attr_map[index].id = id;
+ attr_map[index].element = desc.element;
+ attr_map[index].offset = as_uint(desc.offset);
if (type == TypeDesc::TypeFloat)
- attr_map[index].w = NODE_ATTR_FLOAT;
+ attr_map[index].type = NODE_ATTR_FLOAT;
else if (type == TypeDesc::TypeMatrix)
- attr_map[index].w = NODE_ATTR_MATRIX;
+ attr_map[index].type = NODE_ATTR_MATRIX;
else if (type == TypeFloat2)
- attr_map[index].w = NODE_ATTR_FLOAT2;
+ attr_map[index].type = NODE_ATTR_FLOAT2;
else if (type == TypeFloat4)
- attr_map[index].w = NODE_ATTR_FLOAT4;
+ attr_map[index].type = NODE_ATTR_FLOAT4;
else if (type == TypeRGBA)
- attr_map[index].w = NODE_ATTR_RGBA;
+ attr_map[index].type = NODE_ATTR_RGBA;
else
- attr_map[index].w = NODE_ATTR_FLOAT3;
+ attr_map[index].type = NODE_ATTR_FLOAT3;
- attr_map[index].w |= desc.flags << 8;
+ attr_map[index].flags = desc.flags;
}
/* Generate an attribute map end marker, optionally including a link to another map.
* Links are used to connect object attribute maps to mesh attribute maps. */
-static void emit_attribute_map_terminator(uint4 *attr_map, int index, bool chain, uint chain_link)
+static void emit_attribute_map_terminator(AttributeMap *attr_map,
+ int index,
+ bool chain,
+ uint chain_link)
{
for (int j = 0; j < ATTR_PRIM_TYPES; j++) {
- attr_map[index + j].x = ATTR_STD_NONE;
- attr_map[index + j].y = chain; /* link is valid flag */
- attr_map[index + j].z = chain ? chain_link + j : 0; /* link to the correct sub-entry */
- attr_map[index + j].w = 0;
+ attr_map[index + j].id = ATTR_STD_NONE;
+ attr_map[index + j].element = chain; /* link is valid flag */
+ attr_map[index + j].offset = chain ? chain_link + j : 0; /* link to the correct sub-entry */
+ attr_map[index + j].type = 0;
+ attr_map[index + j].flags = 0;
}
}
/* Generate all necessary attribute map entries from the attribute request. */
static void emit_attribute_mapping(
- uint4 *attr_map, int index, Scene *scene, AttributeRequest &req, Geometry *geom)
+ AttributeMap *attr_map, int index, Scene *scene, AttributeRequest &req, Geometry *geom)
{
uint id;
@@ -501,8 +505,8 @@ void GeometryManager::update_svm_attributes(Device *,
}
/* create attribute map */
- uint4 *attr_map = dscene->attributes_map.alloc(attr_map_size);
- memset(attr_map, 0, dscene->attributes_map.size() * sizeof(uint));
+ AttributeMap *attr_map = dscene->attributes_map.alloc(attr_map_size);
+ memset(attr_map, 0, dscene->attributes_map.size() * sizeof(*attr_map));
for (size_t i = 0; i < scene->geometry.size(); i++) {
Geometry *geom = scene->geometry[i];
@@ -1288,7 +1292,7 @@ void GeometryManager::device_update_bvh(Device *device,
bparams.bvh_type = scene->params.bvh_type;
bparams.curve_subdivisions = scene->params.curve_subdivisions();
- VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout.";
+ VLOG_INFO << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout.";
const bool can_refit = scene->bvh != nullptr &&
(bparams.bvh_layout == BVHLayout::BVH_LAYOUT_OPTIX ||
@@ -1799,7 +1803,7 @@ void GeometryManager::device_update(Device *device,
if (!need_update())
return;
- VLOG(1) << "Total " << scene->geometry.size() << " meshes.";
+ VLOG_INFO << "Total " << scene->geometry.size() << " meshes.";
bool true_displacement_used = false;
bool curve_shadow_transparency_used = false;
@@ -1953,7 +1957,7 @@ void GeometryManager::device_update(Device *device,
{
/* Copy constant data needed by shader evaluation. */
- device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
+ device->const_copy_to("data", &dscene->data, sizeof(dscene->data));
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
@@ -2038,7 +2042,7 @@ void GeometryManager::device_update(Device *device,
TaskPool::Summary summary;
pool.wait_work(&summary);
- VLOG(2) << "Objects BVH build pool statistics:\n" << summary.full_report();
+ VLOG_WORK << "Objects BVH build pool statistics:\n" << summary.full_report();
}
foreach (Shader *shader, scene->shaders) {
diff --git a/intern/cycles/scene/image.cpp b/intern/cycles/scene/image.cpp
index 1b44162351a..0352ed3e66c 100644
--- a/intern/cycles/scene/image.cpp
+++ b/intern/cycles/scene/image.cpp
@@ -653,8 +653,8 @@ bool ImageManager::file_load_image(Image *img, int texture_limit)
while (max_size * scale_factor > texture_limit) {
scale_factor *= 0.5f;
}
- VLOG(1) << "Scaling image " << img->loader->name() << " by a factor of " << scale_factor
- << ".";
+ VLOG_WORK << "Scaling image " << img->loader->name() << " by a factor of " << scale_factor
+ << ".";
vector<StorageType> scaled_pixels;
size_t scaled_width, scaled_height, scaled_depth;
util_image_resize_pixels(pixels_storage,
@@ -697,7 +697,7 @@ void ImageManager::device_load_image(Device *device, Scene *scene, int slot, Pro
ImageDataType type = img->metadata.type;
/* Name for debugging. */
- img->mem_name = string_printf("__tex_image_%s_%03d", name_from_type(type), slot);
+ img->mem_name = string_printf("tex_image_%s_%03d", name_from_type(type), slot);
/* Free previous texture in slot. */
if (img->mem) {
diff --git a/intern/cycles/scene/image_oiio.cpp b/intern/cycles/scene/image_oiio.cpp
index 09676455308..500e53ed763 100644
--- a/intern/cycles/scene/image_oiio.cpp
+++ b/intern/cycles/scene/image_oiio.cpp
@@ -22,11 +22,11 @@ bool OIIOImageLoader::load_metadata(const ImageDeviceFeatures & /*features*/,
{
/* Perform preliminary checks, with meaningful logging. */
if (!path_exists(filepath.string())) {
- VLOG(1) << "File '" << filepath.string() << "' does not exist.";
+ VLOG_WARNING << "File '" << filepath.string() << "' does not exist.";
return false;
}
if (path_is_directory(filepath.string())) {
- VLOG(1) << "File '" << filepath.string() << "' is a directory, can't use as image.";
+ VLOG_WARNING << "File '" << filepath.string() << "' is a directory, can't use as image.";
return false;
}
diff --git a/intern/cycles/scene/image_vdb.cpp b/intern/cycles/scene/image_vdb.cpp
index 2209be60a97..059eb09fef4 100644
--- a/intern/cycles/scene/image_vdb.cpp
+++ b/intern/cycles/scene/image_vdb.cpp
@@ -70,7 +70,7 @@ struct ToNanoOp {
nanogrid = nanovdb::openToNanoVDB(floatgrid);
}
catch (const std::exception &e) {
- VLOG(1) << "Error converting OpenVDB to NanoVDB grid: " << e.what();
+ VLOG_WARNING << "Error converting OpenVDB to NanoVDB grid: " << e.what();
}
return true;
}
diff --git a/intern/cycles/scene/integrator.cpp b/intern/cycles/scene/integrator.cpp
index fda6ecc8d14..aa11004fb48 100644
--- a/intern/cycles/scene/integrator.cpp
+++ b/intern/cycles/scene/integrator.cpp
@@ -338,7 +338,7 @@ AdaptiveSampling Integrator::get_adaptive_sampling() const
if (aa_samples > 0 && adaptive_threshold == 0.0f) {
adaptive_sampling.threshold = max(0.001f, 1.0f / (float)aa_samples);
- VLOG(1) << "Cycles adaptive sampling: automatic threshold = " << adaptive_sampling.threshold;
+ VLOG_INFO << "Cycles adaptive sampling: automatic threshold = " << adaptive_sampling.threshold;
}
else {
adaptive_sampling.threshold = adaptive_threshold;
@@ -350,8 +350,8 @@ AdaptiveSampling Integrator::get_adaptive_sampling() const
* in various test scenes. */
const int min_samples = (int)ceilf(16.0f / powf(adaptive_sampling.threshold, 0.3f));
adaptive_sampling.min_samples = max(4, min_samples);
- VLOG(1) << "Cycles adaptive sampling: automatic min samples = "
- << adaptive_sampling.min_samples;
+ VLOG_INFO << "Cycles adaptive sampling: automatic min samples = "
+ << adaptive_sampling.min_samples;
}
else {
adaptive_sampling.min_samples = max(4, adaptive_min_samples);
diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp
index 5e311d3051f..ea1f45793fa 100644
--- a/intern/cycles/scene/light.cpp
+++ b/intern/cycles/scene/light.cpp
@@ -34,7 +34,7 @@ static void shade_background_pixels(Device *device,
Progress &progress)
{
/* Needs to be up to data for attribute access. */
- device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
+ device->const_copy_to("data", &dscene->data, sizeof(dscene->data));
const int size = width * height;
const int num_channels = 3;
@@ -215,7 +215,9 @@ void LightManager::test_enabled_lights(Scene *scene)
*/
Shader *shader = scene->background->get_shader(scene);
const bool disable_mis = !(has_portal || shader->has_surface_spatial_varying);
- VLOG_IF(1, disable_mis) << "Background MIS has been disabled.\n";
+ if (disable_mis) {
+ VLOG_INFO << "Background MIS has been disabled.\n";
+ }
foreach (Light *light, scene->lights) {
if (light->light_type == LIGHT_BACKGROUND) {
light->is_enabled = !disable_mis;
@@ -309,7 +311,7 @@ void LightManager::device_update_distribution(Device *,
}
size_t num_distribution = num_triangles + num_lights;
- VLOG(1) << "Total " << num_distribution << " of light distribution primitives.";
+ VLOG_INFO << "Total " << num_distribution << " of light distribution primitives.";
/* emission area */
KernelLightDistribution *distribution = dscene->light_distribution.alloc(num_distribution + 1);
@@ -655,13 +657,14 @@ void LightManager::device_update_background(Device *device,
if (res.x == 0) {
res = environment_res;
if (res.x > 0 && res.y > 0) {
- VLOG(2) << "Automatically set World MIS resolution to " << res.x << " by " << res.y << "\n";
+ VLOG_INFO << "Automatically set World MIS resolution to " << res.x << " by " << res.y
+ << "\n";
}
}
/* If it's still unknown, just use the default. */
if (res.x == 0 || res.y == 0) {
res = make_int2(1024, 512);
- VLOG(2) << "Setting World MIS resolution to default\n";
+ VLOG_INFO << "Setting World MIS resolution to default\n";
}
kbackground->map_res_x = res.x;
kbackground->map_res_y = res.y;
@@ -704,7 +707,7 @@ void LightManager::device_update_background(Device *device,
marg_cdf[res.y].y = 1.0f;
- VLOG(2) << "Background MIS build time " << time_dt() - time_start << "\n";
+ VLOG_WORK << "Background MIS build time " << time_dt() - time_start << "\n";
/* update device */
dscene->light_background_marginal_cdf.copy_to_device();
@@ -725,7 +728,7 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc
KernelLight *klights = dscene->lights.alloc(num_lights);
if (num_lights == 0) {
- VLOG(1) << "No effective light, ignoring points update.";
+ VLOG_WORK << "No effective light, ignoring points update.";
return;
}
@@ -955,9 +958,9 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc
light_index++;
}
- VLOG(1) << "Number of lights sent to the device: " << light_index;
+ VLOG_INFO << "Number of lights sent to the device: " << light_index;
- VLOG(1) << "Number of lights without contribution: " << num_scene_lights - light_index;
+ VLOG_INFO << "Number of lights without contribution: " << num_scene_lights - light_index;
dscene->lights.copy_to_device();
}
@@ -976,7 +979,7 @@ void LightManager::device_update(Device *device,
}
});
- VLOG(1) << "Total " << scene->lights.size() << " lights.";
+ VLOG_INFO << "Total " << scene->lights.size() << " lights.";
/* Detect which lights are enabled, also determines if we need to update the background. */
test_enabled_lights(scene);
diff --git a/intern/cycles/scene/object.cpp b/intern/cycles/scene/object.cpp
index ddd89a16640..3a1c177fe3b 100644
--- a/intern/cycles/scene/object.cpp
+++ b/intern/cycles/scene/object.cpp
@@ -688,7 +688,7 @@ void ObjectManager::device_update(Device *device,
dscene->objects.tag_modified();
}
- VLOG(1) << "Total " << scene->objects.size() << " objects.";
+ VLOG_INFO << "Total " << scene->objects.size() << " objects.";
device_free(device, dscene, false);
diff --git a/intern/cycles/scene/osl.cpp b/intern/cycles/scene/osl.cpp
index 6698e6e2cce..f5ee0c0f1d3 100644
--- a/intern/cycles/scene/osl.cpp
+++ b/intern/cycles/scene/osl.cpp
@@ -92,7 +92,7 @@ void OSLShaderManager::device_update_specific(Device *device,
}
});
- VLOG(1) << "Total " << scene->shaders.size() << " shaders.";
+ VLOG_INFO << "Total " << scene->shaders.size() << " shaders.";
device_free(device, dscene, scene);
@@ -240,7 +240,7 @@ void OSLShaderManager::shading_system_init()
ss_shared->attribute("searchpath:shader", shader_path);
ss_shared->attribute("greedyjit", 1);
- VLOG(1) << "Using shader search path: " << shader_path;
+ VLOG_INFO << "Using shader search path: " << shader_path;
/* our own ray types */
static const char *raytypes[] = {
diff --git a/intern/cycles/scene/particles.cpp b/intern/cycles/scene/particles.cpp
index a05acf17ccf..b527dd0ebe8 100644
--- a/intern/cycles/scene/particles.cpp
+++ b/intern/cycles/scene/particles.cpp
@@ -105,7 +105,7 @@ void ParticleSystemManager::device_update(Device *device,
}
});
- VLOG(1) << "Total " << scene->particle_systems.size() << " particle systems.";
+ VLOG_INFO << "Total " << scene->particle_systems.size() << " particle systems.";
device_free(device, dscene);
diff --git a/intern/cycles/scene/scene.cpp b/intern/cycles/scene/scene.cpp
index 8b5604eba72..1fcc3331337 100644
--- a/intern/cycles/scene/scene.cpp
+++ b/intern/cycles/scene/scene.cpp
@@ -34,49 +34,49 @@
CCL_NAMESPACE_BEGIN
DeviceScene::DeviceScene(Device *device)
- : bvh_nodes(device, "__bvh_nodes", MEM_GLOBAL),
- bvh_leaf_nodes(device, "__bvh_leaf_nodes", MEM_GLOBAL),
- object_node(device, "__object_node", MEM_GLOBAL),
- prim_type(device, "__prim_type", MEM_GLOBAL),
- prim_visibility(device, "__prim_visibility", MEM_GLOBAL),
- prim_index(device, "__prim_index", MEM_GLOBAL),
- prim_object(device, "__prim_object", MEM_GLOBAL),
- prim_time(device, "__prim_time", MEM_GLOBAL),
- tri_verts(device, "__tri_verts", MEM_GLOBAL),
- tri_shader(device, "__tri_shader", MEM_GLOBAL),
- tri_vnormal(device, "__tri_vnormal", MEM_GLOBAL),
- tri_vindex(device, "__tri_vindex", MEM_GLOBAL),
- tri_patch(device, "__tri_patch", MEM_GLOBAL),
- tri_patch_uv(device, "__tri_patch_uv", MEM_GLOBAL),
- curves(device, "__curves", MEM_GLOBAL),
- curve_keys(device, "__curve_keys", MEM_GLOBAL),
- curve_segments(device, "__curve_segments", MEM_GLOBAL),
- patches(device, "__patches", MEM_GLOBAL),
- points(device, "__points", MEM_GLOBAL),
- points_shader(device, "__points_shader", MEM_GLOBAL),
- objects(device, "__objects", MEM_GLOBAL),
- object_motion_pass(device, "__object_motion_pass", MEM_GLOBAL),
- object_motion(device, "__object_motion", MEM_GLOBAL),
- object_flag(device, "__object_flag", MEM_GLOBAL),
- object_volume_step(device, "__object_volume_step", MEM_GLOBAL),
- object_prim_offset(device, "__object_prim_offset", MEM_GLOBAL),
- camera_motion(device, "__camera_motion", MEM_GLOBAL),
- attributes_map(device, "__attributes_map", MEM_GLOBAL),
- attributes_float(device, "__attributes_float", MEM_GLOBAL),
- attributes_float2(device, "__attributes_float2", MEM_GLOBAL),
- attributes_float3(device, "__attributes_float3", MEM_GLOBAL),
- attributes_float4(device, "__attributes_float4", MEM_GLOBAL),
- attributes_uchar4(device, "__attributes_uchar4", MEM_GLOBAL),
- light_distribution(device, "__light_distribution", MEM_GLOBAL),
- lights(device, "__lights", MEM_GLOBAL),
- light_background_marginal_cdf(device, "__light_background_marginal_cdf", MEM_GLOBAL),
- light_background_conditional_cdf(device, "__light_background_conditional_cdf", MEM_GLOBAL),
- particles(device, "__particles", MEM_GLOBAL),
- svm_nodes(device, "__svm_nodes", MEM_GLOBAL),
- shaders(device, "__shaders", MEM_GLOBAL),
- lookup_table(device, "__lookup_table", MEM_GLOBAL),
- sample_pattern_lut(device, "__sample_pattern_lut", MEM_GLOBAL),
- ies_lights(device, "__ies", MEM_GLOBAL)
+ : bvh_nodes(device, "bvh_nodes", MEM_GLOBAL),
+ bvh_leaf_nodes(device, "bvh_leaf_nodes", MEM_GLOBAL),
+ object_node(device, "object_node", MEM_GLOBAL),
+ prim_type(device, "prim_type", MEM_GLOBAL),
+ prim_visibility(device, "prim_visibility", MEM_GLOBAL),
+ prim_index(device, "prim_index", MEM_GLOBAL),
+ prim_object(device, "prim_object", MEM_GLOBAL),
+ prim_time(device, "prim_time", MEM_GLOBAL),
+ tri_verts(device, "tri_verts", MEM_GLOBAL),
+ tri_shader(device, "tri_shader", MEM_GLOBAL),
+ tri_vnormal(device, "tri_vnormal", MEM_GLOBAL),
+ tri_vindex(device, "tri_vindex", MEM_GLOBAL),
+ tri_patch(device, "tri_patch", MEM_GLOBAL),
+ tri_patch_uv(device, "tri_patch_uv", MEM_GLOBAL),
+ curves(device, "curves", MEM_GLOBAL),
+ curve_keys(device, "curve_keys", MEM_GLOBAL),
+ curve_segments(device, "curve_segments", MEM_GLOBAL),
+ patches(device, "patches", MEM_GLOBAL),
+ points(device, "points", MEM_GLOBAL),
+ points_shader(device, "points_shader", MEM_GLOBAL),
+ objects(device, "objects", MEM_GLOBAL),
+ object_motion_pass(device, "object_motion_pass", MEM_GLOBAL),
+ object_motion(device, "object_motion", MEM_GLOBAL),
+ object_flag(device, "object_flag", MEM_GLOBAL),
+ object_volume_step(device, "object_volume_step", MEM_GLOBAL),
+ object_prim_offset(device, "object_prim_offset", MEM_GLOBAL),
+ camera_motion(device, "camera_motion", MEM_GLOBAL),
+ attributes_map(device, "attributes_map", MEM_GLOBAL),
+ attributes_float(device, "attributes_float", MEM_GLOBAL),
+ attributes_float2(device, "attributes_float2", MEM_GLOBAL),
+ attributes_float3(device, "attributes_float3", MEM_GLOBAL),
+ attributes_float4(device, "attributes_float4", MEM_GLOBAL),
+ attributes_uchar4(device, "attributes_uchar4", MEM_GLOBAL),
+ light_distribution(device, "light_distribution", MEM_GLOBAL),
+ lights(device, "lights", MEM_GLOBAL),
+ light_background_marginal_cdf(device, "light_background_marginal_cdf", MEM_GLOBAL),
+ light_background_conditional_cdf(device, "light_background_conditional_cdf", MEM_GLOBAL),
+ particles(device, "particles", MEM_GLOBAL),
+ svm_nodes(device, "svm_nodes", MEM_GLOBAL),
+ shaders(device, "shaders", MEM_GLOBAL),
+ lookup_table(device, "lookup_table", MEM_GLOBAL),
+ sample_pattern_lut(device, "sample_pattern_lut", MEM_GLOBAL),
+ ies_lights(device, "ies", MEM_GLOBAL)
{
memset((void *)&data, 0, sizeof(data));
}
@@ -366,18 +366,18 @@ void Scene::device_update(Device *device_, Progress &progress)
dscene.data.volume_stack_size = get_volume_stack_size();
progress.set_status("Updating Device", "Writing constant memory");
- device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
+ device->const_copy_to("data", &dscene.data, sizeof(dscene.data));
}
if (print_stats) {
size_t mem_used = util_guarded_get_mem_used();
size_t mem_peak = util_guarded_get_mem_peak();
- VLOG(1) << "System memory statistics after full device sync:\n"
- << " Usage: " << string_human_readable_number(mem_used) << " ("
- << string_human_readable_size(mem_used) << ")\n"
- << " Peak: " << string_human_readable_number(mem_peak) << " ("
- << string_human_readable_size(mem_peak) << ")";
+ VLOG_INFO << "System memory statistics after full device sync:\n"
+ << " Usage: " << string_human_readable_number(mem_used) << " ("
+ << string_human_readable_size(mem_used) << ")\n"
+ << " Peak: " << string_human_readable_number(mem_peak) << " ("
+ << string_human_readable_size(mem_peak) << ")";
}
}
@@ -586,35 +586,38 @@ bool Scene::update(Progress &progress)
static void log_kernel_features(const uint features)
{
- VLOG(2) << "Requested features:\n";
- VLOG(2) << "Use BSDF " << string_from_bool(features & KERNEL_FEATURE_NODE_BSDF) << "\n";
- VLOG(2) << "Use Principled BSDF " << string_from_bool(features & KERNEL_FEATURE_PRINCIPLED)
- << "\n";
- VLOG(2) << "Use Emission " << string_from_bool(features & KERNEL_FEATURE_NODE_EMISSION) << "\n";
- VLOG(2) << "Use Volume " << string_from_bool(features & KERNEL_FEATURE_NODE_VOLUME) << "\n";
- VLOG(2) << "Use Bump " << string_from_bool(features & KERNEL_FEATURE_NODE_BUMP) << "\n";
- VLOG(2) << "Use Voronoi " << string_from_bool(features & KERNEL_FEATURE_NODE_VORONOI_EXTRA)
- << "\n";
- VLOG(2) << "Use Shader Raytrace " << string_from_bool(features & KERNEL_FEATURE_NODE_RAYTRACE)
- << "\n";
- VLOG(2) << "Use MNEE" << string_from_bool(features & KERNEL_FEATURE_MNEE) << "\n";
- VLOG(2) << "Use Transparent " << string_from_bool(features & KERNEL_FEATURE_TRANSPARENT) << "\n";
- VLOG(2) << "Use Denoising " << string_from_bool(features & KERNEL_FEATURE_DENOISING) << "\n";
- VLOG(2) << "Use Path Tracing " << string_from_bool(features & KERNEL_FEATURE_PATH_TRACING)
- << "\n";
- VLOG(2) << "Use Hair " << string_from_bool(features & KERNEL_FEATURE_HAIR) << "\n";
- VLOG(2) << "Use Pointclouds " << string_from_bool(features & KERNEL_FEATURE_POINTCLOUD) << "\n";
- VLOG(2) << "Use Object Motion " << string_from_bool(features & KERNEL_FEATURE_OBJECT_MOTION)
- << "\n";
- VLOG(2) << "Use Camera Motion " << string_from_bool(features & KERNEL_FEATURE_CAMERA_MOTION)
- << "\n";
- VLOG(2) << "Use Baking " << string_from_bool(features & KERNEL_FEATURE_BAKING) << "\n";
- VLOG(2) << "Use Subsurface " << string_from_bool(features & KERNEL_FEATURE_SUBSURFACE) << "\n";
- VLOG(2) << "Use Volume " << string_from_bool(features & KERNEL_FEATURE_VOLUME) << "\n";
- VLOG(2) << "Use Patch Evaluation "
- << string_from_bool(features & KERNEL_FEATURE_PATCH_EVALUATION) << "\n";
- VLOG(2) << "Use Shadow Catcher " << string_from_bool(features & KERNEL_FEATURE_SHADOW_CATCHER)
- << "\n";
+ VLOG_INFO << "Requested features:\n";
+ VLOG_INFO << "Use BSDF " << string_from_bool(features & KERNEL_FEATURE_NODE_BSDF) << "\n";
+ VLOG_INFO << "Use Principled BSDF " << string_from_bool(features & KERNEL_FEATURE_PRINCIPLED)
+ << "\n";
+ VLOG_INFO << "Use Emission " << string_from_bool(features & KERNEL_FEATURE_NODE_EMISSION)
+ << "\n";
+ VLOG_INFO << "Use Volume " << string_from_bool(features & KERNEL_FEATURE_NODE_VOLUME) << "\n";
+ VLOG_INFO << "Use Bump " << string_from_bool(features & KERNEL_FEATURE_NODE_BUMP) << "\n";
+ VLOG_INFO << "Use Voronoi " << string_from_bool(features & KERNEL_FEATURE_NODE_VORONOI_EXTRA)
+ << "\n";
+ VLOG_INFO << "Use Shader Raytrace " << string_from_bool(features & KERNEL_FEATURE_NODE_RAYTRACE)
+ << "\n";
+ VLOG_INFO << "Use MNEE" << string_from_bool(features & KERNEL_FEATURE_MNEE) << "\n";
+ VLOG_INFO << "Use Transparent " << string_from_bool(features & KERNEL_FEATURE_TRANSPARENT)
+ << "\n";
+ VLOG_INFO << "Use Denoising " << string_from_bool(features & KERNEL_FEATURE_DENOISING) << "\n";
+ VLOG_INFO << "Use Path Tracing " << string_from_bool(features & KERNEL_FEATURE_PATH_TRACING)
+ << "\n";
+ VLOG_INFO << "Use Hair " << string_from_bool(features & KERNEL_FEATURE_HAIR) << "\n";
+ VLOG_INFO << "Use Pointclouds " << string_from_bool(features & KERNEL_FEATURE_POINTCLOUD)
+ << "\n";
+ VLOG_INFO << "Use Object Motion " << string_from_bool(features & KERNEL_FEATURE_OBJECT_MOTION)
+ << "\n";
+ VLOG_INFO << "Use Camera Motion " << string_from_bool(features & KERNEL_FEATURE_CAMERA_MOTION)
+ << "\n";
+ VLOG_INFO << "Use Baking " << string_from_bool(features & KERNEL_FEATURE_BAKING) << "\n";
+ VLOG_INFO << "Use Subsurface " << string_from_bool(features & KERNEL_FEATURE_SUBSURFACE) << "\n";
+ VLOG_INFO << "Use Volume " << string_from_bool(features & KERNEL_FEATURE_VOLUME) << "\n";
+ VLOG_INFO << "Use Patch Evaluation "
+ << string_from_bool(features & KERNEL_FEATURE_PATCH_EVALUATION) << "\n";
+ VLOG_INFO << "Use Shadow Catcher " << string_from_bool(features & KERNEL_FEATURE_SHADOW_CATCHER)
+ << "\n";
}
bool Scene::load_kernels(Progress &progress, bool lock_scene)
@@ -675,8 +678,8 @@ int Scene::get_max_closure_count()
* closures discarded due to mixing or low weights. We need to limit
* to MAX_CLOSURE as this is hardcoded in CPU/mega kernels, and it
* avoids excessive memory usage for split kernels. */
- VLOG(2) << "Maximum number of closures exceeded: " << max_closure_global << " > "
- << MAX_CLOSURE;
+ VLOG_WARNING << "Maximum number of closures exceeded: " << max_closure_global << " > "
+ << MAX_CLOSURE;
max_closure_global = MAX_CLOSURE;
}
@@ -723,7 +726,7 @@ int Scene::get_volume_stack_size() const
volume_stack_size = min(volume_stack_size, MAX_VOLUME_STACK_SIZE);
- VLOG(3) << "Detected required volume stack size " << volume_stack_size;
+ VLOG_WORK << "Detected required volume stack size " << volume_stack_size;
return volume_stack_size;
}
diff --git a/intern/cycles/scene/scene.h b/intern/cycles/scene/scene.h
index a0d2f4a6c06..d04c6a27f11 100644
--- a/intern/cycles/scene/scene.h
+++ b/intern/cycles/scene/scene.h
@@ -98,7 +98,7 @@ class DeviceScene {
device_vector<DecomposedTransform> camera_motion;
/* attributes */
- device_vector<uint4> attributes_map;
+ device_vector<AttributeMap> attributes_map;
device_vector<float> attributes_float;
device_vector<float2> attributes_float2;
device_vector<packed_float3> attributes_float3;
diff --git a/intern/cycles/scene/shader_graph.cpp b/intern/cycles/scene/shader_graph.cpp
index f25d0b7c7b9..ef3f142ed4e 100644
--- a/intern/cycles/scene/shader_graph.cpp
+++ b/intern/cycles/scene/shader_graph.cpp
@@ -659,7 +659,7 @@ void ShaderGraph::deduplicate_nodes()
}
if (num_deduplicated > 0) {
- VLOG(1) << "Deduplicated " << num_deduplicated << " nodes.";
+ VLOG_DEBUG << "Deduplicated " << num_deduplicated << " nodes.";
}
}
@@ -700,7 +700,7 @@ void ShaderGraph::verify_volume_output()
}
}
if (!has_valid_volume) {
- VLOG(1) << "Disconnect meaningless volume output.";
+ VLOG_DEBUG << "Disconnect meaningless volume output.";
disconnect(volume_in->link);
}
}
diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp
index 3b58556f601..f93a1a5231a 100644
--- a/intern/cycles/scene/shader_nodes.cpp
+++ b/intern/cycles/scene/shader_nodes.cpp
@@ -2391,7 +2391,7 @@ void GlossyBsdfNode::simplify_settings(Scene *scene)
* NOTE: Keep the epsilon in sync with kernel!
*/
if (!roughness_input->link && roughness <= 1e-4f) {
- VLOG(3) << "Using sharp glossy BSDF.";
+ VLOG_DEBUG << "Using sharp glossy BSDF.";
distribution = CLOSURE_BSDF_REFLECTION_ID;
}
}
@@ -2400,7 +2400,7 @@ void GlossyBsdfNode::simplify_settings(Scene *scene)
* benefit from closure blur to remove unwanted noise.
*/
if (roughness_input->link == NULL && distribution == CLOSURE_BSDF_REFLECTION_ID) {
- VLOG(3) << "Using GGX glossy with filter glossy.";
+ VLOG_DEBUG << "Using GGX glossy with filter glossy.";
distribution = CLOSURE_BSDF_MICROFACET_GGX_ID;
roughness = 0.0f;
}
@@ -2484,7 +2484,7 @@ void GlassBsdfNode::simplify_settings(Scene *scene)
* NOTE: Keep the epsilon in sync with kernel!
*/
if (!roughness_input->link && roughness <= 1e-4f) {
- VLOG(3) << "Using sharp glass BSDF.";
+ VLOG_DEBUG << "Using sharp glass BSDF.";
distribution = CLOSURE_BSDF_SHARP_GLASS_ID;
}
}
@@ -2493,7 +2493,7 @@ void GlassBsdfNode::simplify_settings(Scene *scene)
* benefit from closure blur to remove unwanted noise.
*/
if (roughness_input->link == NULL && distribution == CLOSURE_BSDF_SHARP_GLASS_ID) {
- VLOG(3) << "Using GGX glass with filter glossy.";
+ VLOG_DEBUG << "Using GGX glass with filter glossy.";
distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
roughness = 0.0f;
}
@@ -2577,7 +2577,7 @@ void RefractionBsdfNode::simplify_settings(Scene *scene)
* NOTE: Keep the epsilon in sync with kernel!
*/
if (!roughness_input->link && roughness <= 1e-4f) {
- VLOG(3) << "Using sharp refraction BSDF.";
+ VLOG_DEBUG << "Using sharp refraction BSDF.";
distribution = CLOSURE_BSDF_REFRACTION_ID;
}
}
@@ -2586,7 +2586,7 @@ void RefractionBsdfNode::simplify_settings(Scene *scene)
* benefit from closure blur to remove unwanted noise.
*/
if (roughness_input->link == NULL && distribution == CLOSURE_BSDF_REFRACTION_ID) {
- VLOG(3) << "Using GGX refraction with filter glossy.";
+ VLOG_DEBUG << "Using GGX refraction with filter glossy.";
distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
roughness = 0.0f;
}
diff --git a/intern/cycles/scene/svm.cpp b/intern/cycles/scene/svm.cpp
index 484a7d6de72..4bc5a1b9cc2 100644
--- a/intern/cycles/scene/svm.cpp
+++ b/intern/cycles/scene/svm.cpp
@@ -51,9 +51,9 @@ void SVMShaderManager::device_update_shader(Scene *scene,
compiler.background = (shader == scene->background->get_shader(scene));
compiler.compile(shader, *svm_nodes, 0, &summary);
- VLOG(3) << "Compilation summary:\n"
- << "Shader name: " << shader->name << "\n"
- << summary.full_report();
+ VLOG_WORK << "Compilation summary:\n"
+ << "Shader name: " << shader->name << "\n"
+ << summary.full_report();
}
void SVMShaderManager::device_update_specific(Device *device,
@@ -72,7 +72,7 @@ void SVMShaderManager::device_update_specific(Device *device,
const int num_shaders = scene->shaders.size();
- VLOG(1) << "Total " << num_shaders << " shaders.";
+ VLOG_INFO << "Total " << num_shaders << " shaders.";
double start_time = time_dt();
@@ -148,8 +148,8 @@ void SVMShaderManager::device_update_specific(Device *device,
update_flags = UPDATE_NONE;
- VLOG(1) << "Shader manager updated " << num_shaders << " shaders in " << time_dt() - start_time
- << " seconds.";
+ VLOG_INFO << "Shader manager updated " << num_shaders << " shaders in " << time_dt() - start_time
+ << " seconds.";
}
void SVMShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *scene)
diff --git a/intern/cycles/scene/tables.cpp b/intern/cycles/scene/tables.cpp
index bb35880d37e..3e57b535f35 100644
--- a/intern/cycles/scene/tables.cpp
+++ b/intern/cycles/scene/tables.cpp
@@ -34,7 +34,7 @@ void LookupTables::device_update(Device *, DeviceScene *dscene, Scene *scene)
}
});
- VLOG(1) << "Total " << lookup_tables.size() << " lookup tables.";
+ VLOG_INFO << "Total " << lookup_tables.size() << " lookup tables.";
if (lookup_tables.size() > 0)
dscene->lookup_table.copy_to_device();
diff --git a/intern/cycles/scene/volume.cpp b/intern/cycles/scene/volume.cpp
index 39e9b0bbbf4..77955350305 100644
--- a/intern/cycles/scene/volume.cpp
+++ b/intern/cycles/scene/volume.cpp
@@ -754,11 +754,11 @@ void GeometryManager::create_volume_mesh(const Scene *scene, Volume *volume, Pro
}
/* Print stats. */
- VLOG(1) << "Memory usage volume mesh: "
- << ((vertices.size() + face_normals.size()) * sizeof(float3) +
- indices.size() * sizeof(int)) /
- (1024.0 * 1024.0)
- << "Mb.";
+ VLOG_WORK << "Memory usage volume mesh: "
+ << ((vertices.size() + face_normals.size()) * sizeof(float3) +
+ indices.size() * sizeof(int)) /
+ (1024.0 * 1024.0)
+ << "Mb.";
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/session/session.cpp b/intern/cycles/session/session.cpp
index ef177636046..ba30be817cf 100644
--- a/intern/cycles/session/session.cpp
+++ b/intern/cycles/session/session.cpp
@@ -146,11 +146,11 @@ void Session::run_main_render_loop()
RenderWork render_work = run_update_for_next_iteration();
if (!render_work) {
- if (VLOG_IS_ON(2)) {
+ if (VLOG_WORK_IS_ON) {
double total_time, render_time;
progress.get_time(total_time, render_time);
- VLOG(2) << "Rendering in main loop is done in " << render_time << " seconds.";
- VLOG(2) << path_trace_->full_report();
+ VLOG_WORK << "Rendering in main loop is done in " << render_time << " seconds.";
+ VLOG_WORK << path_trace_->full_report();
}
if (params.background) {
diff --git a/intern/cycles/session/tile.cpp b/intern/cycles/session/tile.cpp
index 82272a7dbf5..f4930cbb945 100644
--- a/intern/cycles/session/tile.cpp
+++ b/intern/cycles/session/tile.cpp
@@ -335,7 +335,7 @@ int TileManager::compute_render_tile_size(const int suggested_tile_size) const
void TileManager::reset_scheduling(const BufferParams &params, int2 tile_size)
{
- VLOG(3) << "Using tile size of " << tile_size;
+ VLOG_WORK << "Using tile size of " << tile_size;
close_tile_output();
@@ -466,7 +466,7 @@ bool TileManager::open_tile_output()
write_state_.num_tiles_written = 0;
- VLOG(3) << "Opened tile file " << write_state_.filename;
+ VLOG_WORK << "Opened tile file " << write_state_.filename;
return true;
}
@@ -485,7 +485,7 @@ bool TileManager::close_tile_output()
return false;
}
- VLOG(3) << "Tile output is closed.";
+ VLOG_WORK << "Tile output is closed.";
return true;
}
@@ -536,7 +536,7 @@ bool TileManager::write_tile(const RenderBuffers &tile_buffers)
pixels = pixel_storage.data();
}
- VLOG(3) << "Write tile at " << tile_x << ", " << tile_y;
+ VLOG_WORK << "Write tile at " << tile_x << ", " << tile_y;
/* The image tile sizes in the OpenEXR file are different from the size of our big tiles. The
* write_tiles() method expects a contiguous image region that will be split into tiles
@@ -567,7 +567,7 @@ bool TileManager::write_tile(const RenderBuffers &tile_buffers)
++write_state_.num_tiles_written;
- VLOG(3) << "Tile written in " << time_dt() - time_start << " seconds.";
+ VLOG_WORK << "Tile written in " << time_dt() - time_start << " seconds.";
return true;
}
@@ -591,7 +591,7 @@ void TileManager::finish_write_tiles()
const int tile_x = tile.x + tile.window_x;
const int tile_y = tile.y + tile.window_y;
- VLOG(3) << "Write dummy tile at " << tile_x << ", " << tile_y;
+ VLOG_WORK << "Write dummy tile at " << tile_x << ", " << tile_y;
write_state_.tile_out->write_tiles(tile_x,
tile_x + tile.window_width,
@@ -610,8 +610,8 @@ void TileManager::finish_write_tiles()
full_buffer_written_cb(write_state_.filename);
}
- VLOG(3) << "Tile file size is "
- << string_human_readable_number(path_file_size(write_state_.filename)) << " bytes.";
+ VLOG_WORK << "Tile file size is "
+ << string_human_readable_number(path_file_size(write_state_.filename)) << " bytes.";
/* Advance the counter upon explicit finish of the file.
* Makes it possible to re-use tile manager for another scene, and avoids unnecessary increments
diff --git a/intern/cycles/test/render_graph_finalize_test.cpp b/intern/cycles/test/render_graph_finalize_test.cpp
index dac36ab0135..2dc13f0eccb 100644
--- a/intern/cycles/test/render_graph_finalize_test.cpp
+++ b/intern/cycles/test/render_graph_finalize_test.cpp
@@ -166,7 +166,7 @@ class RenderGraph : public testing::Test {
virtual void SetUp()
{
util_logging_start();
- util_logging_verbosity_set(3);
+ util_logging_verbosity_set(5);
device_cpu = Device::create(device_info, stats, profiler);
scene = new Scene(scene_params, device_cpu);
diff --git a/intern/cycles/util/debug.cpp b/intern/cycles/util/debug.cpp
index 65d108bb9d1..faa54a92c24 100644
--- a/intern/cycles/util/debug.cpp
+++ b/intern/cycles/util/debug.cpp
@@ -25,7 +25,7 @@ void DebugFlags::CPU::reset()
do { \
flag = (getenv(env) == NULL); \
if (!flag) { \
- VLOG(1) << "Disabling " << STRINGIFY(flag) << " instruction set."; \
+ VLOG_INFO << "Disabling " << STRINGIFY(flag) << " instruction set."; \
} \
} while (0)
diff --git a/intern/cycles/util/log.h b/intern/cycles/util/log.h
index b33c826d6f5..3780d03c0d1 100644
--- a/intern/cycles/util/log.h
+++ b/intern/cycles/util/log.h
@@ -69,9 +69,22 @@ class LogMessageVoidify {
# define LOG_ASSERT(expression) LOG_SUPPRESS()
#endif
-#define VLOG_ONCE(level, flag) \
- if (!flag) \
- flag = true, VLOG(level)
+/* Verbose logging categories. */
+
+/* Warnings. */
+#define VLOG_WARNING VLOG(1)
+/* Info about devices, scene contents and features used. */
+#define VLOG_INFO VLOG(2)
+#define VLOG_INFO_IS_ON VLOG_IS_ON(2)
+/* Work being performed and timing/memory stats about that work. */
+#define VLOG_WORK VLOG(3)
+#define VLOG_WORK_IS_ON VLOG_IS_ON(3)
+/* Detailed device timing stats. */
+#define VLOG_DEVICE_STATS VLOG(4)
+#define VLOG_DEVICE_STATS_IS_ON VLOG_IS_ON(4)
+/* Verbose debug messages. */
+#define VLOG_DEBUG VLOG(5)
+#define VLOG_DEBUG_IS_ON VLOG_IS_ON(5)
struct int2;
struct float3;
diff --git a/intern/cycles/util/task.cpp b/intern/cycles/util/task.cpp
index 2edc82eb7c3..12f661f752d 100644
--- a/intern/cycles/util/task.cpp
+++ b/intern/cycles/util/task.cpp
@@ -70,7 +70,7 @@ void TaskScheduler::init(int num_threads)
}
if (num_threads > 0) {
/* Automatic number of threads. */
- VLOG(1) << "Overriding number of TBB threads to " << num_threads << ".";
+ VLOG_INFO << "Overriding number of TBB threads to " << num_threads << ".";
global_control = new tbb::global_control(tbb::global_control::max_allowed_parallelism,
num_threads);
active_num_threads = num_threads;
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index 5b06b5d98e6..945b3261562 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -303,59 +303,63 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
message(FATAL_ERROR "path to wayland-protocols not found")
endif()
+ set(INC_DST ${CMAKE_CURRENT_BINARY_DIR}/libwayland)
+
# Generate protocols bindings.
- macro(generate_protocol_bindings NAME PROT_DEF)
+ macro(generate_protocol_bindings PROT_DEF)
+ # File name without directory or extension (use for header name).
+ get_filename_component(_name ${PROT_DEF} NAME_WLE)
add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}-client-protocol.h
- COMMAND ${WAYLAND_SCANNER} client-header ${PROT_DEF} ${NAME}-client-protocol.h
+ OUTPUT ${INC_DST}/${_name}-client-protocol.h
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${INC_DST}
+ COMMAND ${WAYLAND_SCANNER} client-header ${PROT_DEF} ${INC_DST}/${_name}-client-protocol.h
)
add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}-client-protocol.c
- COMMAND ${WAYLAND_SCANNER} private-code ${PROT_DEF} ${NAME}-client-protocol.c
- DEPENDS ${NAME}-client-protocol.h
+ OUTPUT ${INC_DST}/${_name}-client-protocol.c
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${INC_DST}
+ COMMAND ${WAYLAND_SCANNER} private-code ${PROT_DEF} ${INC_DST}/${_name}-client-protocol.c
+ DEPENDS ${INC_DST}/${_name}-client-protocol.h
)
list(APPEND SRC
- ${CMAKE_CURRENT_BINARY_DIR}/${NAME}-client-protocol.c
- ${CMAKE_CURRENT_BINARY_DIR}/${NAME}-client-protocol.h
+ ${INC_DST}/${_name}-client-protocol.c
+ ${INC_DST}/${_name}-client-protocol.h
)
+ unset(_name)
endmacro()
+
list(APPEND INC_SYS
- ${CMAKE_CURRENT_BINARY_DIR}
+ ${INC_DST}
)
# `xdg-shell`.
generate_protocol_bindings(
- xdg-shell
"${WAYLAND_PROTOCOLS_DIR}/stable/xdg-shell/xdg-shell.xml"
)
# `xdg-decoration`.
generate_protocol_bindings(
- xdg-decoration
"${WAYLAND_PROTOCOLS_DIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"
)
# `xdg-output`.
generate_protocol_bindings(
- xdg-output
"${WAYLAND_PROTOCOLS_DIR}/unstable/xdg-output/xdg-output-unstable-v1.xml"
)
# Pointer-constraints.
generate_protocol_bindings(
- pointer-constraints
"${WAYLAND_PROTOCOLS_DIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml"
)
# Relative-pointer.
generate_protocol_bindings(
- relative-pointer
"${WAYLAND_PROTOCOLS_DIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml"
)
# Tablet.
generate_protocol_bindings(
- tablet
"${WAYLAND_PROTOCOLS_DIR}/unstable/tablet/tablet-unstable-v2.xml"
)
add_definitions(-DWITH_GHOST_WAYLAND)
+
+ unset(INC_DST)
endif()
if(WITH_INPUT_NDOF)
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index c92e6ba78c1..5ace0fcc9d2 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -20,7 +20,7 @@ extern "C" {
* \param event: The event received.
* \param userdata: The callback's user data, supplied to #GHOST_CreateSystem.
*/
-typedef int (*GHOST_EventCallbackProcPtr)(GHOST_EventHandle event, GHOST_TUserDataPtr userdata);
+typedef bool (*GHOST_EventCallbackProcPtr)(GHOST_EventHandle event, GHOST_TUserDataPtr userdata);
/**
* Creates the one and only system.
@@ -206,7 +206,7 @@ extern GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandl
*/
extern void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle, GHOST_TUserDataPtr userdata);
-extern int GHOST_IsDialogWindow(GHOST_WindowHandle windowhandle);
+extern bool GHOST_IsDialogWindow(GHOST_WindowHandle windowhandle);
/**
* Dispose a window.
@@ -223,7 +223,7 @@ extern GHOST_TSuccess GHOST_DisposeWindow(GHOST_SystemHandle systemhandle,
* \param windowhandle: Handle to the window to be checked.
* \return Indication of validity.
*/
-extern int GHOST_ValidWindow(GHOST_SystemHandle systemhandle, GHOST_WindowHandle windowhandle);
+extern bool GHOST_ValidWindow(GHOST_SystemHandle systemhandle, GHOST_WindowHandle windowhandle);
/**
* Begins full screen mode.
@@ -235,7 +235,7 @@ extern int GHOST_ValidWindow(GHOST_SystemHandle systemhandle, GHOST_WindowHandle
*/
extern GHOST_WindowHandle GHOST_BeginFullScreen(GHOST_SystemHandle systemhandle,
GHOST_DisplaySetting *setting,
- const int stereoVisual);
+ const bool stereoVisual);
/**
* Ends full screen mode.
@@ -249,7 +249,7 @@ extern GHOST_TSuccess GHOST_EndFullScreen(GHOST_SystemHandle systemhandle);
* \param systemhandle: The handle to the system.
* \return The current status.
*/
-extern int GHOST_GetFullScreen(GHOST_SystemHandle systemhandle);
+extern bool GHOST_GetFullScreen(GHOST_SystemHandle systemhandle);
/**
* Get the Window under the cursor.
@@ -364,12 +364,15 @@ extern GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle
int hotY,
bool canInvertColor);
+extern GHOST_TSuccess GHOST_GetCursorBitmap(GHOST_WindowHandle windowhandle,
+ GHOST_CursorBitmapRef *bitmap);
+
/**
* Returns the visibility state of the cursor.
* \param windowhandle: The handle to the window.
* \return The visibility state of the cursor.
*/
-extern int GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle);
+extern bool GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle);
/**
* Shows or hides the cursor.
@@ -377,7 +380,7 @@ extern int GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle);
* \param visible: The new visibility state of the cursor.
* \return Indication of success.
*/
-extern GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle, int visible);
+extern GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle, bool visible);
/**
* Returns the current location of the cursor (location in screen coordinates)
@@ -404,8 +407,9 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
void GHOST_GetCursorGrabState(GHOST_WindowHandle windowhandle,
GHOST_TGrabCursorMode *r_mode,
- GHOST_TAxisFlag *r_wrap_axis,
- int r_bounds[4]);
+ GHOST_TAxisFlag *r_axis_flag,
+ int r_bounds[4],
+ bool *r_use_software_cursor);
/**
* Grabs the cursor for a modal operation, to keep receiving
@@ -436,7 +440,7 @@ extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
*/
extern GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle,
GHOST_TModifierKeyMask mask,
- int *isDown);
+ bool *r_is_down);
/**
* Returns the state of a mouse button (outside the message queue).
@@ -447,7 +451,7 @@ extern GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle,
*/
extern GHOST_TSuccess GHOST_GetButtonState(GHOST_SystemHandle systemhandle,
GHOST_TButtonMask mask,
- int *isDown);
+ bool *r_is_down);
#ifdef WITH_INPUT_NDOF
/***************************************************************************************
@@ -468,7 +472,7 @@ extern void GHOST_setNDOFDeadZone(float deadzone);
/**
* Tells if the ongoing drag'n'drop object can be accepted upon mouse drop
*/
-extern void GHOST_setAcceptDragOperation(GHOST_WindowHandle windowhandle, bool canAccept);
+extern void GHOST_setAcceptDragOperation(GHOST_WindowHandle windowhandle, bool can_accept);
/**
* Returns the event type.
@@ -534,7 +538,7 @@ extern void GHOST_SetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle,
* \param windowhandle: The handle to the window.
* \return The validity of the window.
*/
-extern int GHOST_GetValid(GHOST_WindowHandle windowhandle);
+extern bool GHOST_GetValid(GHOST_WindowHandle windowhandle);
/**
* Returns the type of drawing context used in this window.
@@ -894,22 +898,22 @@ extern void GHOST_putClipboard(const char *buffer, bool selection);
* \param action: console state
* \return current status (1 -visible, 0 - hidden)
*/
-extern int setConsoleWindowState(GHOST_TConsoleWindowState action);
+extern bool GHOST_setConsoleWindowState(GHOST_TConsoleWindowState action);
/**
* Use native pixel size (MacBook pro 'retina'), if supported.
*/
-extern int GHOST_UseNativePixels(void);
+extern bool GHOST_UseNativePixels(void);
/**
* Warp the cursor, if supported.
*/
-extern int GHOST_SupportsCursorWarp(void);
+extern bool GHOST_SupportsCursorWarp(void);
/**
* Support positioning windows (when false `wmWindow.x,y` are meaningless).
*/
-extern int GHOST_SupportsWindowPosition(void);
+extern bool GHOST_SupportsWindowPosition(void);
/**
* Assign the callback which generates a back-trace (may be NULL).
@@ -919,7 +923,7 @@ extern void GHOST_SetBacktraceHandler(GHOST_TBacktraceFn backtrace_fn);
/**
* Focus window after opening, or put them in the background.
*/
-extern void GHOST_UseWindowFocus(int use_focus);
+extern void GHOST_UseWindowFocus(bool use_focus);
/**
* If window was opened using native pixel size, it returns scaling factor.
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index 7927190de04..f712d9bd9f0 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -258,7 +258,10 @@ class GHOST_IWindow {
virtual void getCursorGrabState(GHOST_TGrabCursorMode &mode,
GHOST_TAxisFlag &axis_flag,
- GHOST_Rect &bounds) = 0;
+ GHOST_Rect &bounds,
+ bool &use_software_cursor) = 0;
+
+ virtual bool getCursorGrabUseSoftwareDisplay() = 0;
/**
* Test if the standard cursor shape is supported by current platform.
@@ -282,6 +285,8 @@ class GHOST_IWindow {
int hotY,
bool canInvertColor) = 0;
+ virtual GHOST_TSuccess getCursorBitmap(GHOST_CursorBitmapRef *bitmap) = 0;
+
/**
* Returns the visibility state of the cursor.
* \return The visibility state of the cursor.
diff --git a/intern/ghost/GHOST_Rect.h b/intern/ghost/GHOST_Rect.h
index 0a5561b7d68..1cbc75fe60b 100644
--- a/intern/ghost/GHOST_Rect.h
+++ b/intern/ghost/GHOST_Rect.h
@@ -101,6 +101,12 @@ class GHOST_Rect {
* \param y: The y-coordinate of the point.
*/
virtual inline void wrapPoint(int32_t &x, int32_t &y, int32_t ofs, GHOST_TAxisFlag axis);
+ /**
+ * Confine x & y within the rectangle (inclusive).
+ * \param x: The x-coordinate of the point.
+ * \param y: The y-coordinate of the point.
+ */
+ virtual inline void clampPoint(int32_t &x, int32_t &y);
/**
* Returns whether the point is inside this rectangle.
@@ -190,26 +196,34 @@ inline bool GHOST_Rect::isValid() const
inline void GHOST_Rect::unionRect(const GHOST_Rect &r)
{
- if (r.m_l < m_l)
+ if (r.m_l < m_l) {
m_l = r.m_l;
- if (r.m_r > m_r)
+ }
+ if (r.m_r > m_r) {
m_r = r.m_r;
- if (r.m_t < m_t)
+ }
+ if (r.m_t < m_t) {
m_t = r.m_t;
- if (r.m_b > m_b)
+ }
+ if (r.m_b > m_b) {
m_b = r.m_b;
+ }
}
inline void GHOST_Rect::unionPoint(int32_t x, int32_t y)
{
- if (x < m_l)
+ if (x < m_l) {
m_l = x;
- if (x > m_r)
+ }
+ if (x > m_r) {
m_r = x;
- if (y < m_t)
+ }
+ if (y < m_t) {
m_t = y;
- if (y > m_b)
+ }
+ if (y > m_b) {
m_b = y;
+ }
}
inline void GHOST_Rect::wrapPoint(int32_t &x, int32_t &y, int32_t ofs, GHOST_TAxisFlag axis)
@@ -223,16 +237,37 @@ inline void GHOST_Rect::wrapPoint(int32_t &x, int32_t &y, int32_t ofs, GHOST_TAx
}
if (axis & GHOST_kAxisX) {
- while (x - ofs < m_l)
+ while (x - ofs < m_l) {
x += w - (ofs * 2);
- while (x + ofs > m_r)
+ }
+ while (x + ofs > m_r) {
x -= w - (ofs * 2);
+ }
}
if (axis & GHOST_kGrabAxisY) {
- while (y - ofs < m_t)
+ while (y - ofs < m_t) {
y += h - (ofs * 2);
- while (y + ofs > m_b)
+ }
+ while (y + ofs > m_b) {
y -= h - (ofs * 2);
+ }
+ }
+}
+
+inline void GHOST_Rect::clampPoint(int32_t &x, int32_t &y)
+{
+ if (x < m_l) {
+ x = m_l;
+ }
+ else if (x > m_r) {
+ x = m_r;
+ }
+
+ if (y < m_t) {
+ y = m_t;
+ }
+ else if (y > m_b) {
+ y = m_b;
}
}
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 78f2b24ea78..35bde3d4413 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -44,6 +44,16 @@ GHOST_DECLARE_HANDLE(GHOST_XrContextHandle);
typedef void (*GHOST_TBacktraceFn)(void *file_handle);
+/**
+ * A reference to cursor bitmap data.
+ */
+typedef struct {
+ /** `RGBA` bytes. */
+ const uint8_t *data;
+ int data_size[2];
+ int hot_spot[2];
+} GHOST_CursorBitmapRef;
+
typedef struct {
int flags;
} GHOST_GLSettings;
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index b1a15fdf4d7..2b5414cd47b 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -177,11 +177,11 @@ void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle, GHOST_TUserDataPtr
window->setUserData(userdata);
}
-int GHOST_IsDialogWindow(GHOST_WindowHandle windowhandle)
+bool GHOST_IsDialogWindow(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return (int)window->isDialog();
+ return window->isDialog();
}
GHOST_TSuccess GHOST_DisposeWindow(GHOST_SystemHandle systemhandle,
@@ -193,17 +193,17 @@ GHOST_TSuccess GHOST_DisposeWindow(GHOST_SystemHandle systemhandle,
return system->disposeWindow(window);
}
-int GHOST_ValidWindow(GHOST_SystemHandle systemhandle, GHOST_WindowHandle windowhandle)
+bool GHOST_ValidWindow(GHOST_SystemHandle systemhandle, GHOST_WindowHandle windowhandle)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return (int)system->validWindow(window);
+ return system->validWindow(window);
}
GHOST_WindowHandle GHOST_BeginFullScreen(GHOST_SystemHandle systemhandle,
GHOST_DisplaySetting *setting,
- const int stereoVisual)
+ const bool stereoVisual)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
GHOST_IWindow *window = nullptr;
@@ -228,11 +228,11 @@ GHOST_TSuccess GHOST_EndFullScreen(GHOST_SystemHandle systemhandle)
return system->endFullScreen();
}
-int GHOST_GetFullScreen(GHOST_SystemHandle systemhandle)
+bool GHOST_GetFullScreen(GHOST_SystemHandle systemhandle)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
- return (int)system->getFullScreen();
+ return system->getFullScreen();
}
GHOST_WindowHandle GHOST_GetWindowUnderCursor(GHOST_SystemHandle systemhandle,
@@ -326,18 +326,26 @@ GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle,
return window->setCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, canInvertColor);
}
-int GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle)
+GHOST_TSuccess GHOST_GetCursorBitmap(GHOST_WindowHandle windowhandle,
+ GHOST_CursorBitmapRef *bitmap)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return (int)window->getCursorVisibility();
+ return window->getCursorBitmap(bitmap);
}
-GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle, int visible)
+bool GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return window->setCursorVisibility(visible ? true : false);
+ return window->getCursorVisibility();
+}
+
+GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle, bool visible)
+{
+ GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
+
+ return window->setCursorVisibility(visible);
}
GHOST_TSuccess GHOST_GetCursorPosition(GHOST_SystemHandle systemhandle, int32_t *x, int32_t *y)
@@ -379,41 +387,44 @@ GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
void GHOST_GetCursorGrabState(GHOST_WindowHandle windowhandle,
GHOST_TGrabCursorMode *r_mode,
GHOST_TAxisFlag *r_axis_flag,
- int r_bounds[4])
+ int r_bounds[4],
+ bool *r_use_software_cursor)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
GHOST_Rect bounds_rect;
- window->getCursorGrabState(*r_mode, *r_axis_flag, bounds_rect);
+ bool use_software_cursor;
+ window->getCursorGrabState(*r_mode, *r_axis_flag, bounds_rect, use_software_cursor);
r_bounds[0] = bounds_rect.m_l;
r_bounds[1] = bounds_rect.m_t;
r_bounds[2] = bounds_rect.m_r;
r_bounds[3] = bounds_rect.m_b;
+ *r_use_software_cursor = use_software_cursor;
}
GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle,
GHOST_TModifierKeyMask mask,
- int *isDown)
+ bool *r_is_down)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
GHOST_TSuccess result;
- bool isdown = false;
+ bool is_down = false;
- result = system->getModifierKeyState(mask, isdown);
- *isDown = (int)isdown;
+ result = system->getModifierKeyState(mask, is_down);
+ *r_is_down = is_down;
return result;
}
GHOST_TSuccess GHOST_GetButtonState(GHOST_SystemHandle systemhandle,
GHOST_TButtonMask mask,
- int *isDown)
+ bool *r_is_down)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
GHOST_TSuccess result;
- bool isdown = false;
+ bool is_down = false;
- result = system->getButtonState(mask, isdown);
- *isDown = (int)isdown;
+ result = system->getButtonState(mask, is_down);
+ *r_is_down = is_down;
return result;
}
@@ -426,11 +437,11 @@ void GHOST_setNDOFDeadZone(float deadzone)
}
#endif
-void GHOST_setAcceptDragOperation(GHOST_WindowHandle windowhandle, bool canAccept)
+void GHOST_setAcceptDragOperation(GHOST_WindowHandle windowhandle, bool can_accept)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- window->setAcceptDragOperation(canAccept);
+ window->setAcceptDragOperation(can_accept);
}
GHOST_TEventType GHOST_GetEventType(GHOST_EventHandle eventhandle)
@@ -489,11 +500,11 @@ void GHOST_SetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle, GHOST_TUs
timertask->setUserData(userdata);
}
-int GHOST_GetValid(GHOST_WindowHandle windowhandle)
+bool GHOST_GetValid(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
- return (int)window->getValid();
+ return window->getValid();
}
GHOST_TDrawingContextType GHOST_GetDrawingContextType(GHOST_WindowHandle windowhandle)
@@ -817,25 +828,26 @@ void GHOST_putClipboard(const char *buffer, bool selection)
system->putClipboard(buffer, selection);
}
-int setConsoleWindowState(GHOST_TConsoleWindowState action)
+bool GHOST_setConsoleWindowState(GHOST_TConsoleWindowState action)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
- return system->setConsoleWindowState(action);
+ /* FIXME: use `bool` instead of int for this value. */
+ return (bool)system->setConsoleWindowState(action);
}
-int GHOST_UseNativePixels(void)
+bool GHOST_UseNativePixels(void)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->useNativePixel();
}
-int GHOST_SupportsCursorWarp(void)
+bool GHOST_SupportsCursorWarp(void)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->supportsCursorWarp();
}
-int GHOST_SupportsWindowPosition(void)
+bool GHOST_SupportsWindowPosition(void)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->supportsWindowPosition();
@@ -846,7 +858,7 @@ void GHOST_SetBacktraceHandler(GHOST_TBacktraceFn backtrace_fn)
GHOST_ISystem::setBacktraceFn(backtrace_fn);
}
-void GHOST_UseWindowFocus(int use_focus)
+void GHOST_UseWindowFocus(bool use_focus)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->useWindowFocus(use_focus);
diff --git a/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp b/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp
index 72aeebdc876..9f14d56cd9a 100644
--- a/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp
+++ b/intern/ghost/intern/GHOST_CallbackEventConsumer.cpp
@@ -22,5 +22,5 @@ GHOST_CallbackEventConsumer::GHOST_CallbackEventConsumer(GHOST_EventCallbackProc
bool GHOST_CallbackEventConsumer::processEvent(GHOST_IEvent *event)
{
- return m_eventCallback((GHOST_EventHandle)event, m_userData) != 0;
+ return m_eventCallback((GHOST_EventHandle)event, m_userData);
}
diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp
index baabdc6c521..b4a076e4598 100644
--- a/intern/ghost/intern/GHOST_ContextGLX.cpp
+++ b/intern/ghost/intern/GHOST_ContextGLX.cpp
@@ -105,7 +105,7 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store);
/* -------------------------------------------------------------------- */
- /* Begin Inline Glew */
+ /* Begin Inline GLEW. */
#ifdef USE_GLXEW_INIT_WORKAROUND
const GLubyte *extStart = (GLubyte *)"";
@@ -142,11 +142,11 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
"GLX_EXT_create_context_es2_profile", extStart, extEnd);
# endif /* WITH_GLEW_ES */
- /* End Inline Glew */
+ /* End Inline GLEW. */
/* -------------------------------------------------------------------- */
#else
- /* important to initialize only glxew (_not_ glew),
- * since this breaks w/ Mesa's `swrast`, see: T46431 */
+ /* Important to initialize only glxew (_not_ GLEW),
+ * since this breaks w/ Mesa's `swrast`, see: T46431. */
glxewInit();
#endif /* USE_GLXEW_INIT_WORKAROUND */
@@ -395,7 +395,7 @@ int GHOST_X11_GL_GetAttributes(
return i;
}
-/* excuse inlining part of glew */
+/* Excuse inlining part of GLEW. */
#ifdef USE_GLXEW_INIT_WORKAROUND
static GLuint _glewStrLen(const GLubyte *s)
{
diff --git a/intern/ghost/intern/GHOST_DropTargetX11.cpp b/intern/ghost/intern/GHOST_DropTargetX11.cpp
index 70c2eb8c29e..900e46c3732 100644
--- a/intern/ghost/intern/GHOST_DropTargetX11.cpp
+++ b/intern/ghost/intern/GHOST_DropTargetX11.cpp
@@ -31,7 +31,7 @@ int GHOST_DropTargetX11::m_refCounter = 0;
#define dndTypePlainText m_dndTypes[dndTypePlainTextID]
#define dndTypeOctetStream m_dndTypes[dndTypeOctetStreamID]
-void GHOST_DropTargetX11::Initialize(void)
+void GHOST_DropTargetX11::Initialize()
{
Display *display = m_system->getXDisplay();
int dndTypesCount = sizeof(m_dndMimeTypes) / sizeof(char *);
@@ -60,7 +60,7 @@ void GHOST_DropTargetX11::Initialize(void)
m_dndActions[counter++] = 0;
}
-void GHOST_DropTargetX11::Uninitialize(void)
+void GHOST_DropTargetX11::Uninitialize()
{
xdnd_shut(&m_dndClass);
@@ -98,12 +98,12 @@ GHOST_DropTargetX11::~GHOST_DropTargetX11()
/* Based on: https://stackoverflow.com/a/2766963/432509 */
-typedef enum DecodeState_e {
+using DecodeState_e = enum DecodeState_e {
/** Searching for an ampersand to convert. */
STATE_SEARCH = 0,
/** Convert the two proceeding characters from hex. */
STATE_CONVERTING
-} DecodeState_e;
+};
void GHOST_DropTargetX11::UrlDecode(char *decodedOut, int bufferSize, const char *encodedIn)
{
@@ -122,7 +122,7 @@ void GHOST_DropTargetX11::UrlDecode(char *decodedOut, int bufferSize, const char
case STATE_SEARCH:
if (encodedIn[i] != '%') {
strncat(decodedOut, &encodedIn[i], 1);
- assert(strlen(decodedOut) < bufferSize);
+ assert((int)strlen(decodedOut) < bufferSize);
break;
}
@@ -145,18 +145,19 @@ void GHOST_DropTargetX11::UrlDecode(char *decodedOut, int bufferSize, const char
/* Ensure both characters are hexadecimal */
for (j = 0; j < 2; ++j) {
- if (!isxdigit(tempNumBuf[j]))
+ if (!isxdigit(tempNumBuf[j])) {
bothDigits = false;
+ }
}
- if (!bothDigits)
+ if (!bothDigits) {
break;
-
+ }
/* Convert two hexadecimal characters into one character */
sscanf(tempNumBuf, "%x", &asciiCharacter);
/* Ensure we aren't going to overflow */
- assert(strlen(decodedOut) < bufferSize);
+ assert((int)strlen(decodedOut) < bufferSize);
/* Concatenate this character onto the output */
strncat(decodedOut, (char *)&asciiCharacter, 1);
diff --git a/intern/ghost/intern/GHOST_EventPrinter.cpp b/intern/ghost/intern/GHOST_EventPrinter.cpp
index 758938e879e..2620bcc075d 100644
--- a/intern/ghost/intern/GHOST_EventPrinter.cpp
+++ b/intern/ghost/intern/GHOST_EventPrinter.cpp
@@ -12,7 +12,7 @@
#include "GHOST_EventKey.h"
#include <iostream>
-#include <stdio.h>
+#include <cstdio>
bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
{
@@ -20,9 +20,9 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
GHOST_ASSERT(event, "event==0");
- if (event->getType() == GHOST_kEventWindowUpdate)
+ if (event->getType() == GHOST_kEventWindowUpdate) {
return false;
-
+ }
std::cout << "GHOST_EventPrinter::processEvent, time: " << (int32_t)event->getTime()
<< ", type: ";
switch (event->getType()) {
@@ -106,8 +106,9 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
std::cout << " type : GHOST_kDragnDropTypeFilenames,";
std::cout << "\n Received " << strArray->count << " filename"
<< (strArray->count > 1 ? "s:" : ":");
- for (i = 0; i < strArray->count; i++)
+ for (i = 0; i < strArray->count; i++) {
std::cout << "\n File[" << i << "] : " << strArray->strings[i];
+ }
} break;
default:
break;
@@ -117,10 +118,12 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
case GHOST_kEventOpenMainFile: {
GHOST_TEventDataPtr eventData = ((GHOST_IEvent *)event)->getData();
- if (eventData)
+ if (eventData) {
std::cout << "GHOST_kEventOpenMainFile for path : " << (char *)eventData;
- else
+ }
+ else {
std::cout << "GHOST_kEventOpenMainFile with no path specified!!";
+ }
} break;
case GHOST_kEventQuitRequest:
@@ -167,7 +170,7 @@ void GHOST_EventPrinter::getKeyString(GHOST_TKey key, char str[32]) const
sprintf(str, "F%d", key - GHOST_kKeyF1 + 1);
}
else {
- const char *tstr = NULL;
+ const char *tstr = nullptr;
switch (key) {
case GHOST_kKeyBackSpace:
tstr = "BackSpace";
diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp
index 7f6b5f53316..2298ba86521 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManager.cpp
@@ -6,10 +6,10 @@
#include "GHOST_EventNDOF.h"
#include "GHOST_WindowManager.h"
-#include <limits.h>
-#include <math.h>
-#include <stdio.h> /* For error/info reporting. */
-#include <string.h> /* For memory functions. */
+#include <climits>
+#include <cmath>
+#include <cstdio> /* For error/info reporting. */
+#include <cstring> /* For memory functions. */
#ifdef DEBUG_NDOF_MOTION
/* Printable version of each GHOST_TProgress value. */
@@ -255,8 +255,9 @@ bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ
printf("ndof: unknown device %04hx:%04hx\n", vendor_id, product_id);
}
- if (m_buttonMask == 0)
+ if (m_buttonMask == 0) {
m_buttonMask = (int)~(UINT_MAX << m_buttonCount);
+ }
#ifdef DEBUG_NDOF_BUTTONS
printf("ndof: %d buttons -> hex:%X\n", m_buttonCount, m_buttonMask);
diff --git a/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp b/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp
index 7e53ce45f70..7770f5f39ce 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManagerUnix.cpp
@@ -32,10 +32,11 @@ GHOST_NDOFManagerUnix::GHOST_NDOFManagerUnix(GHOST_System &sys)
char line[MAX_LINE_LENGTH] = {0};
while (fgets(line, MAX_LINE_LENGTH, command_output)) {
unsigned short vendor_id = 0, product_id = 0;
- if (sscanf(line, "Bus %*d Device %*d: ID %hx:%hx", &vendor_id, &product_id) == 2)
+ if (sscanf(line, "Bus %*d Device %*d: ID %hx:%hx", &vendor_id, &product_id) == 2) {
if (setDevice(vendor_id, product_id)) {
break; /* stop looking once the first 3D mouse is found */
}
+ }
}
pclose(command_output);
}
@@ -44,8 +45,9 @@ GHOST_NDOFManagerUnix::GHOST_NDOFManagerUnix(GHOST_System &sys)
GHOST_NDOFManagerUnix::~GHOST_NDOFManagerUnix()
{
- if (m_available)
+ if (m_available) {
spnav_close();
+ }
}
bool GHOST_NDOFManagerUnix::available()
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index c8308b3586b..cc8d0915c5a 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -158,7 +158,7 @@ GHOST_TSuccess GHOST_System::updateFullScreen(const GHOST_DisplaySetting &settin
return success;
}
-GHOST_TSuccess GHOST_System::endFullScreen(void)
+GHOST_TSuccess GHOST_System::endFullScreen()
{
GHOST_TSuccess success = GHOST_kFailure;
GHOST_ASSERT(m_windowManager, "GHOST_System::endFullScreen(): invalid window manager");
@@ -177,7 +177,7 @@ GHOST_TSuccess GHOST_System::endFullScreen(void)
return success;
}
-bool GHOST_System::getFullScreen(void)
+bool GHOST_System::getFullScreen()
{
bool fullScreen;
if (m_windowManager) {
@@ -289,7 +289,7 @@ void GHOST_System::setTabletAPI(GHOST_TTabletAPI api)
m_tabletAPI = api;
}
-GHOST_TTabletAPI GHOST_System::getTabletAPI(void)
+GHOST_TTabletAPI GHOST_System::getTabletAPI()
{
return m_tabletAPI;
}
@@ -319,9 +319,7 @@ GHOST_TSuccess GHOST_System::init()
if (m_timerManager && m_windowManager && m_eventManager) {
return GHOST_kSuccess;
}
- else {
- return GHOST_kFailure;
- }
+ return GHOST_kFailure;
}
GHOST_TSuccess GHOST_System::exit()
@@ -357,10 +355,12 @@ GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window,
{
GHOST_GLSettings glSettings = {0};
- if (stereoVisual)
+ if (stereoVisual) {
glSettings.flags |= GHOST_glStereoVisual;
- if (alphaBackground)
+ }
+ if (alphaBackground) {
glSettings.flags |= GHOST_glAlphaBackground;
+ }
/* NOTE: don't use #getCurrentDisplaySetting() because on X11 we may
* be zoomed in and the desktop may be bigger than the viewport. */
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp
index d8fbe875f67..33afb5f3155 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.cpp
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -26,15 +26,18 @@
#include <unordered_map>
#include <unordered_set>
-#include "GHOST_WaylandCursorSettings.h"
-#include <pointer-constraints-client-protocol.h>
-#include <relative-pointer-client-protocol.h>
-#include <tablet-client-protocol.h>
#include <wayland-cursor.h>
-#include <xdg-output-client-protocol.h>
+
+#include "GHOST_WaylandCursorSettings.h"
#include <xkbcommon/xkbcommon.h>
+/* Generated by `wayland-scanner`. */
+#include <pointer-constraints-unstable-v1-client-protocol.h>
+#include <relative-pointer-unstable-v1-client-protocol.h>
+#include <tablet-unstable-v2-client-protocol.h>
+#include <xdg-output-unstable-v1-client-protocol.h>
+
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
@@ -44,6 +47,24 @@
static GHOST_WindowWayland *window_from_surface(struct wl_surface *surface);
+/**
+ * GNOME (mutter 42.2 had a bug with confine not respecting scale - Hi-DPI), See: T98793.
+ * Even though this has been fixed, at time of writing it's not yet in a release.
+ * Workaround the problem by implementing confine with a software cursor.
+ * While this isn't ideal, it's not adding a lot of overhead as software
+ * cursors are already used for warping (which WAYLAND doesn't support).
+ */
+#define USE_GNOME_CONFINE_HACK
+/**
+ * Always use software confine (not just in GNOME).
+ * Useful for developing with compositors that don't need this workaround.
+ */
+// #define USE_GNOME_CONFINE_HACK_ALWAYS_ON
+
+#ifdef USE_GNOME_CONFINE_HACK
+static bool use_gnome_confine_hack = false;
+#endif
+
/* -------------------------------------------------------------------- */
/** \name Private Types & Defines
* \{ */
@@ -78,6 +99,14 @@ struct buffer_t {
struct cursor_t {
bool visible = false;
+ /**
+ * When false, hide the hardware cursor, while the cursor is still considered to be `visible`,
+ * since the grab-mode determines the state of the software cursor,
+ * this may change - removing the need for a software cursor and in this case it's important
+ * the hardware cursor is used.
+ */
+ bool is_hardware = true;
+ bool is_custom = false;
struct wl_surface *wl_surface = nullptr;
struct wl_buffer *wl_buffer = nullptr;
struct wl_cursor_image wl_image = {0};
@@ -87,7 +116,9 @@ struct cursor_t {
std::string theme_name;
/** Outputs on which the cursor is visible. */
std::unordered_set<const output_t *> outputs;
- int scale = 1;
+
+ int theme_scale = 1;
+ int custom_scale = 1;
};
/**
@@ -125,6 +156,12 @@ struct key_repeat_payload_t {
GHOST_TEventKeyData key_data = {GHOST_kKeyUnknown};
};
+/** Internal variables used to track grab-state. */
+struct input_grab_state_t {
+ bool use_lock = false;
+ bool use_confine = false;
+};
+
struct input_t {
GHOST_SystemWayland *system = nullptr;
@@ -153,9 +190,14 @@ struct input_t {
* wl_fixed_to_int(scale * input->xy[0]),
* wl_fixed_to_int(scale * input->xy[1]),
* };
- * \endocde
+ * \endcode
*/
wl_fixed_t xy[2] = {0, 0};
+
+#ifdef USE_GNOME_CONFINE_HACK
+ bool xy_software_confine = false;
+#endif
+
GHOST_Buttons buttons = GHOST_Buttons();
struct cursor_t cursor;
@@ -496,7 +538,7 @@ static GHOST_TTabletMode tablet_tool_map_type(enum zwp_tablet_tool_v2_type wl_ta
static const int default_cursor_size = 24;
-static const std::unordered_map<GHOST_TStandardCursor, std::string> cursors = {
+static const std::unordered_map<GHOST_TStandardCursor, const char *> cursors = {
{GHOST_kStandardCursorDefault, "left_ptr"},
{GHOST_kStandardCursorRightArrow, "right_ptr"},
{GHOST_kStandardCursorLeftArrow, "left_ptr"},
@@ -590,6 +632,21 @@ static void relative_pointer_handle_relative_motion(
input->xy[0] += dx / scale;
input->xy[1] += dy / scale;
+#ifdef USE_GNOME_CONFINE_HACK
+ if (input->xy_software_confine) {
+ GHOST_Rect bounds;
+ win->getClientBounds(bounds);
+ /* Needed or the cursor is considered outside the window and doesn't restore the location. */
+ bounds.m_r -= 1;
+ bounds.m_b -= 1;
+
+ bounds.m_l = wl_fixed_from_int(bounds.m_l) / scale;
+ bounds.m_t = wl_fixed_from_int(bounds.m_t) / scale;
+ bounds.m_r = wl_fixed_from_int(bounds.m_r) / scale;
+ bounds.m_b = wl_fixed_from_int(bounds.m_b) / scale;
+ bounds.clampPoint(input->xy[0], input->xy[1]);
+ }
+#endif
input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(),
GHOST_kEventCursorMove,
win,
@@ -1039,9 +1096,11 @@ static bool update_cursor_scale(cursor_t &cursor, wl_shm *shm)
}
}
- if (scale > 0 && cursor.scale != scale) {
- cursor.scale = scale;
- wl_surface_set_buffer_scale(cursor.wl_surface, scale);
+ if (scale > 0 && cursor.theme_scale != scale) {
+ cursor.theme_scale = scale;
+ if (!cursor.is_custom) {
+ wl_surface_set_buffer_scale(cursor.wl_surface, scale);
+ }
wl_cursor_theme_destroy(cursor.wl_theme);
cursor.wl_theme = wl_cursor_theme_load(cursor.theme_name.c_str(), scale * cursor.size, shm);
return true;
@@ -1123,12 +1182,13 @@ static void pointer_handle_leave(void *data,
uint32_t /*serial*/,
struct wl_surface *surface)
{
+ /* First clear the `focus_pointer`, since the window won't exist when closing the window. */
+ static_cast<input_t *>(data)->focus_pointer = nullptr;
+
GHOST_IWindow *win = window_from_surface(surface);
if (!win) {
return;
}
-
- static_cast<input_t *>(data)->focus_pointer = nullptr;
static_cast<GHOST_WindowWayland *>(win)->deactivate();
}
@@ -1860,16 +1920,21 @@ static void xdg_output_handle_logical_size(void *data,
if (output->size_logical[0] != 0 && output->size_logical[1] != 0) {
/* Original comment from SDL. */
- /* FIXME: GNOME has a bug where the logical size does not account for
+ /* FIXME(@flibit): GNOME has a bug where the logical size does not account for
* scale, resulting in bogus viewport sizes.
*
* Until this is fixed, validate that _some_ kind of scaling is being
* done (we can't match exactly because fractional scaling can't be
- * detected otherwise), then override if necessary.
- * -flibit
- */
+ * detected otherwise), then override if necessary. */
if ((output->size_logical[0] == width) && (output->scale_fractional == wl_fixed_from_int(1))) {
GHOST_PRINT("xdg_output scale did not match, overriding with wl_output scale");
+
+#ifdef USE_GNOME_CONFINE_HACK
+ /* Use a bug in GNOME to check GNOME is in use. If the bug is fixed this won't cause an issue
+ * as T98793 has been fixed up-stream too, but not in a release at time of writing. */
+ use_gnome_confine_hack = true;
+#endif
+
return;
}
}
@@ -1968,7 +2033,7 @@ static void output_handle_done(void *data, struct wl_output * /*wl_output*/)
int32_t size_native[2];
if (output->transform & WL_OUTPUT_TRANSFORM_90) {
size_native[0] = output->size_native[1];
- size_native[1] = output->size_native[1];
+ size_native[1] = output->size_native[0];
}
else {
size_native[0] = output->size_native[0];
@@ -2317,16 +2382,33 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorPosition(int32_t /*x*/, int32_t /*y
void GHOST_SystemWayland::getMainDisplayDimensions(uint32_t &width, uint32_t &height) const
{
- if (getNumDisplays() > 0) {
- /* We assume first output as main. */
- width = uint32_t(d->outputs[0]->size_native[0]) / d->outputs[0]->scale;
- height = uint32_t(d->outputs[0]->size_native[1]) / d->outputs[0]->scale;
+ if (getNumDisplays() == 0) {
+ return;
}
+ /* We assume first output as main. */
+ width = uint32_t(d->outputs[0]->size_native[0]);
+ height = uint32_t(d->outputs[0]->size_native[1]);
}
void GHOST_SystemWayland::getAllDisplayDimensions(uint32_t &width, uint32_t &height) const
{
- getMainDisplayDimensions(width, height);
+ int32_t xy_min[2] = {INT32_MAX, INT32_MAX};
+ int32_t xy_max[2] = {INT32_MIN, INT32_MIN};
+
+ for (const output_t *output : d->outputs) {
+ int32_t xy[2] = {0, 0};
+ if (output->has_position_logical) {
+ xy[0] = output->position_logical[0];
+ xy[1] = output->position_logical[1];
+ }
+ xy_min[0] = std::min(xy_min[0], xy[0]);
+ xy_min[1] = std::min(xy_min[1], xy[1]);
+ xy_max[0] = std::max(xy_max[0], xy[0] + output->size_native[0]);
+ xy_max[1] = std::max(xy_max[1], xy[1] + output->size_native[1]);
+ }
+
+ width = xy_max[0] - xy_min[0];
+ height = xy_max[1] - xy_min[1];
}
GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GLSettings /*glSettings*/)
@@ -2466,47 +2548,152 @@ void GHOST_SystemWayland::setSelection(const std::string &selection)
this->selection = selection;
}
-static void set_cursor_buffer(input_t *input, wl_buffer *buffer)
+/**
+ * Show the buffer defined by #cursor_buffer_set without changing anything else,
+ * so #cursor_buffer_hide can be used to display it again.
+ *
+ * The caller is responsible for setting `input->cursor.visible`.
+ */
+static void cursor_buffer_show(const input_t *input)
+{
+ const cursor_t *c = &input->cursor;
+ const int scale = c->is_custom ? c->custom_scale : c->theme_scale;
+ const int32_t hotspot_x = int32_t(c->wl_image.hotspot_x) / scale;
+ const int32_t hotspot_y = int32_t(c->wl_image.hotspot_y) / scale;
+ wl_pointer_set_cursor(
+ input->wl_pointer, input->pointer_serial, c->wl_surface, hotspot_x, hotspot_y);
+ for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : input->tablet_tools) {
+ tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(
+ zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2));
+ zwp_tablet_tool_v2_set_cursor(zwp_tablet_tool_v2,
+ input->tablet_serial,
+ tool_input->cursor_surface,
+ hotspot_x,
+ hotspot_y);
+ }
+}
+
+/**
+ * Hide the buffer defined by #cursor_buffer_set without changing anything else,
+ * so #cursor_buffer_show can be used to display it again.
+ *
+ * The caller is responsible for setting `input->cursor.visible`.
+ */
+static void cursor_buffer_hide(const input_t *input)
+{
+ wl_pointer_set_cursor(input->wl_pointer, input->pointer_serial, nullptr, 0, 0);
+ for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : input->tablet_tools) {
+ zwp_tablet_tool_v2_set_cursor(zwp_tablet_tool_v2, input->tablet_serial, nullptr, 0, 0);
+ }
+}
+
+static void cursor_buffer_set(const input_t *input, wl_buffer *buffer)
{
- cursor_t *c = &input->cursor;
+ const cursor_t *c = &input->cursor;
+ const int scale = c->is_custom ? c->custom_scale : c->theme_scale;
- c->visible = (buffer != nullptr);
+ const bool visible = (c->visible && c->is_hardware);
const int32_t image_size_x = int32_t(c->wl_image.width);
const int32_t image_size_y = int32_t(c->wl_image.height);
- const int32_t hotspot_x = int32_t(c->wl_image.hotspot_x) / c->scale;
- const int32_t hotspot_y = int32_t(c->wl_image.hotspot_y) / c->scale;
+ /* This is a requirement of WAYLAND, when this isn't the case,
+ * it causes Blender's window to close intermittently. */
+ GHOST_ASSERT((image_size_x % scale) == 0 && (image_size_y % scale) == 0,
+ "The size must be a multiple of the scale!");
+ const int32_t hotspot_x = int32_t(c->wl_image.hotspot_x) / scale;
+ const int32_t hotspot_y = int32_t(c->wl_image.hotspot_y) / scale;
+
+ wl_surface_set_buffer_scale(c->wl_surface, scale);
wl_surface_attach(c->wl_surface, buffer, 0, 0);
wl_surface_damage(c->wl_surface, 0, 0, image_size_x, image_size_y);
+ wl_surface_commit(c->wl_surface);
wl_pointer_set_cursor(input->wl_pointer,
input->pointer_serial,
- c->visible ? c->wl_surface : nullptr,
+ visible ? c->wl_surface : nullptr,
hotspot_x,
hotspot_y);
- wl_surface_commit(c->wl_surface);
-
/* Set the cursor for all tablet tools as well. */
for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : input->tablet_tools) {
tablet_tool_input_t *tool_input = static_cast<tablet_tool_input_t *>(
zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2));
+
/* FIXME: for some reason cursor scale is applied twice (when the scale isn't 1x),
* this happens both in gnome-shell & KDE. Setting the surface scale here doesn't help. */
- // wl_surface_set_buffer_scale(tool_input->cursor_surface, 1);
+ wl_surface_set_buffer_scale(tool_input->cursor_surface, scale);
wl_surface_attach(tool_input->cursor_surface, buffer, 0, 0);
wl_surface_damage(tool_input->cursor_surface, 0, 0, image_size_x, image_size_y);
+ wl_surface_commit(tool_input->cursor_surface);
zwp_tablet_tool_v2_set_cursor(zwp_tablet_tool_v2,
input->tablet_serial,
- c->visible ? tool_input->cursor_surface : nullptr,
+ visible ? tool_input->cursor_surface : nullptr,
hotspot_x,
hotspot_y);
+ }
+}
- wl_surface_commit(tool_input->cursor_surface);
+enum eCursorSetMode {
+ CURSOR_VISIBLE_ALWAYS_SET = 1,
+ CURSOR_VISIBLE_ONLY_HIDE,
+ CURSOR_VISIBLE_ONLY_SHOW,
+};
+
+static void cursor_visible_set(input_t *input,
+ const bool visible,
+ const bool is_hardware,
+ const enum eCursorSetMode set_mode)
+{
+ cursor_t *cursor = &input->cursor;
+ const bool was_visible = cursor->is_hardware && cursor->visible;
+ const bool use_visible = is_hardware && visible;
+
+ if (set_mode == CURSOR_VISIBLE_ALWAYS_SET) {
+ /* Pass. */
+ }
+ else if ((set_mode == CURSOR_VISIBLE_ONLY_SHOW)) {
+ if (!use_visible) {
+ return;
+ }
+ }
+ else if ((set_mode == CURSOR_VISIBLE_ONLY_HIDE)) {
+ if (use_visible) {
+ return;
+ }
+ }
+
+ if (use_visible) {
+ if (!was_visible) {
+ cursor_buffer_show(input);
+ }
+ }
+ else {
+ if (was_visible) {
+ cursor_buffer_hide(input);
+ }
+ }
+ cursor->visible = visible;
+ cursor->is_hardware = is_hardware;
+}
+
+static bool cursor_is_software(const GHOST_TGrabCursorMode mode, const bool use_software_confine)
+{
+ if (mode == GHOST_kGrabWrap) {
+ return true;
+ }
+#ifdef USE_GNOME_CONFINE_HACK
+ if (mode == GHOST_kGrabNormal) {
+ if (use_software_confine) {
+ return true;
+ }
}
+#else
+ (void)use_software_confine;
+#endif
+ return false;
}
GHOST_TSuccess GHOST_SystemWayland::setCursorShape(GHOST_TStandardCursor shape)
@@ -2514,8 +2701,10 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorShape(GHOST_TStandardCursor shape)
if (d->inputs.empty()) {
return GHOST_kFailure;
}
- const std::string cursor_name = cursors.count(shape) ? cursors.at(shape) :
- cursors.at(GHOST_kStandardCursorDefault);
+ auto cursor_find = cursors.find(shape);
+ const char *cursor_name = (cursor_find == cursors.end()) ?
+ cursors.at(GHOST_kStandardCursorDefault) :
+ (*cursor_find).second;
input_t *input = d->inputs[0];
cursor_t *c = &input->cursor;
@@ -2526,7 +2715,7 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorShape(GHOST_TStandardCursor shape)
c->theme_name.c_str(), c->size, d->inputs[0]->system->shm());
}
- wl_cursor *cursor = wl_cursor_theme_get_cursor(c->wl_theme, cursor_name.c_str());
+ wl_cursor *cursor = wl_cursor_theme_get_cursor(c->wl_theme, cursor_name);
if (!cursor) {
GHOST_PRINT("cursor '" << cursor_name << "' does not exist" << std::endl);
@@ -2539,17 +2728,27 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorShape(GHOST_TStandardCursor shape)
return GHOST_kFailure;
}
+ c->visible = true;
+ c->is_custom = false;
c->wl_buffer = buffer;
c->wl_image = *image;
- set_cursor_buffer(input, buffer);
+ cursor_buffer_set(input, buffer);
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_SystemWayland::hasCursorShape(GHOST_TStandardCursor cursorShape)
{
- return GHOST_TSuccess(cursors.count(cursorShape) && !cursors.at(cursorShape).empty());
+ auto cursor_find = cursors.find(cursorShape);
+ if (cursor_find == cursors.end()) {
+ return GHOST_kFailure;
+ }
+ const char *value = (*cursor_find).second;
+ if (*value == '\0') {
+ return GHOST_kFailure;
+ }
+ return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_SystemWayland::setCustomCursorShape(uint8_t *bitmap,
@@ -2602,6 +2801,7 @@ GHOST_TSuccess GHOST_SystemWayland::setCustomCursorShape(uint8_t *bitmap,
nullptr, cursor->file_buffer->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (cursor->file_buffer->data == MAP_FAILED) {
+ cursor->file_buffer->data = nullptr;
close(fd);
return GHOST_kFailure;
}
@@ -2646,37 +2846,49 @@ GHOST_TSuccess GHOST_SystemWayland::setCustomCursorShape(uint8_t *bitmap,
}
}
+ cursor->visible = true;
+ cursor->is_custom = true;
+ cursor->custom_scale = 1; /* TODO: support Hi-DPI custom cursors. */
cursor->wl_buffer = buffer;
cursor->wl_image.width = uint32_t(sizex);
cursor->wl_image.height = uint32_t(sizey);
cursor->wl_image.hotspot_x = uint32_t(hotX);
cursor->wl_image.hotspot_y = uint32_t(hotY);
- set_cursor_buffer(d->inputs[0], buffer);
+ cursor_buffer_set(d->inputs[0], buffer);
return GHOST_kSuccess;
}
-GHOST_TSuccess GHOST_SystemWayland::setCursorVisibility(bool visible)
+GHOST_TSuccess GHOST_SystemWayland::getCursorBitmap(GHOST_CursorBitmapRef *bitmap)
{
- if (d->inputs.empty()) {
+ cursor_t *cursor = &d->inputs[0]->cursor;
+ if (cursor->file_buffer->data == nullptr) {
+ return GHOST_kFailure;
+ }
+ if (!cursor->is_custom) {
return GHOST_kFailure;
}
- input_t *input = d->inputs[0];
+ bitmap->data_size[0] = cursor->wl_image.width;
+ bitmap->data_size[1] = cursor->wl_image.height;
- cursor_t *cursor = &input->cursor;
- if (visible) {
- if (!cursor->visible) {
- set_cursor_buffer(input, cursor->wl_buffer);
- }
- }
- else {
- if (cursor->visible) {
- set_cursor_buffer(input, nullptr);
- }
+ bitmap->hot_spot[0] = cursor->wl_image.hotspot_x;
+ bitmap->hot_spot[1] = cursor->wl_image.hotspot_y;
+
+ bitmap->data = (uint8_t *)static_cast<void *>(cursor->file_buffer->data);
+
+ return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_SystemWayland::setCursorVisibility(bool visible)
+{
+ if (d->inputs.empty()) {
+ return GHOST_kFailure;
}
+ input_t *input = d->inputs[0];
+ cursor_visible_set(input, visible, input->cursor.is_hardware, CURSOR_VISIBLE_ALWAYS_SET);
return GHOST_kSuccess;
}
@@ -2693,6 +2905,60 @@ bool GHOST_SystemWayland::supportsWindowPosition()
return false;
}
+bool GHOST_SystemWayland::getCursorGrabUseSoftwareDisplay(const GHOST_TGrabCursorMode mode)
+{
+ if (d->inputs.empty()) {
+ return false;
+ }
+
+#ifdef USE_GNOME_CONFINE_HACK
+ input_t *input = d->inputs[0];
+ const bool use_software_confine = input->xy_software_confine;
+#else
+ const bool use_software_confine = false;
+#endif
+
+ return cursor_is_software(mode, use_software_confine);
+}
+
+#ifdef USE_GNOME_CONFINE_HACK
+static bool setCursorGrab_use_software_confine(const GHOST_TGrabCursorMode mode,
+ wl_surface *surface)
+{
+# ifndef USE_GNOME_CONFINE_HACK_ALWAYS_ON
+ if (use_gnome_confine_hack == false) {
+ return false;
+ }
+# endif
+ if (mode != GHOST_kGrabNormal) {
+ return false;
+ }
+ GHOST_WindowWayland *win = window_from_surface(surface);
+ if (!win) {
+ return false;
+ }
+
+# ifndef USE_GNOME_CONFINE_HACK_ALWAYS_ON
+ if (win->scale() <= 1) {
+ return false;
+ }
+# endif
+ return true;
+}
+#endif
+
+static input_grab_state_t input_grab_state_from_mode(const GHOST_TGrabCursorMode mode,
+ const bool use_software_confine)
+{
+ /* Initialize all members. */
+ const struct input_grab_state_t grab_state = {
+ /* Warping happens to require software cursor which also hides. */
+ .use_lock = (mode == GHOST_kGrabWrap || mode == GHOST_kGrabHide) || use_software_confine,
+ .use_confine = (mode == GHOST_kGrabNormal) && (use_software_confine == false),
+ };
+ return grab_state;
+}
+
GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mode,
const GHOST_TGrabCursorMode mode_current,
wl_surface *surface)
@@ -2705,7 +2971,6 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mo
if (d->inputs.empty()) {
return GHOST_kFailure;
}
-
/* No change, success. */
if (mode == mode_current) {
return GHOST_kSuccess;
@@ -2713,32 +2978,33 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mo
input_t *input = d->inputs[0];
-#define MODE_NEEDS_LOCK(m) ((m) == GHOST_kGrabWrap || (m) == GHOST_kGrabHide)
-#define MODE_NEEDS_HIDE(m) ((m) == GHOST_kGrabHide)
-#define MODE_NEEDS_CONFINE(m) ((m) == GHOST_kGrabNormal)
+#ifdef USE_GNOME_CONFINE_HACK
+ const bool was_software_confine = input->xy_software_confine;
+ const bool use_software_confine = setCursorGrab_use_software_confine(mode, surface);
+#else
+ const bool was_software_confine = false;
+ const bool use_software_confine = false;
+#endif
- const bool was_lock = MODE_NEEDS_LOCK(mode_current);
- const bool use_lock = MODE_NEEDS_LOCK(mode);
+ const struct input_grab_state_t grab_state_prev = input_grab_state_from_mode(
+ mode_current, was_software_confine);
+ const struct input_grab_state_t grab_state_next = input_grab_state_from_mode(
+ mode, use_software_confine);
/* Check for wrap as #supportsCursorWarp isn't supported. */
- const bool was_hide = MODE_NEEDS_HIDE(mode_current) || (mode_current == GHOST_kGrabWrap);
- const bool use_hide = MODE_NEEDS_HIDE(mode) || (mode == GHOST_kGrabWrap);
+ const bool use_visible = !(((mode == GHOST_kGrabHide) || (mode == GHOST_kGrabWrap)) ||
+ use_software_confine);
- const bool was_confine = MODE_NEEDS_CONFINE(mode_current);
- const bool use_confine = MODE_NEEDS_CONFINE(mode);
+ const bool is_hardware_cursor = !cursor_is_software(mode, use_software_confine);
-#undef MODE_NEEDS_LOCK
-#undef MODE_NEEDS_HIDE
-#undef MODE_NEEDS_CONFINE
-
- if (!use_hide) {
- setCursorVisibility(true);
- }
+ /* Only hide so the cursor is not made visible before it's location is restored.
+ * This function is called again at the end of this function which only shows. */
+ cursor_visible_set(input, use_visible, is_hardware_cursor, CURSOR_VISIBLE_ONLY_HIDE);
/* Switching from one grab mode to another,
* in this case disable the current locks as it makes logic confusing,
* postpone changing the cursor to avoid flickering. */
- if (!use_lock) {
+ if (!grab_state_next.use_lock) {
if (input->relative_pointer) {
zwp_relative_pointer_v1_destroy(input->relative_pointer);
input->relative_pointer = nullptr;
@@ -2786,13 +3052,22 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mo
wl_surface_commit(surface);
}
}
+#ifdef USE_GNOME_CONFINE_HACK
+ else if (mode_current == GHOST_kGrabNormal) {
+ if (was_software_confine) {
+ zwp_locked_pointer_v1_set_cursor_position_hint(
+ input->locked_pointer, input->xy[0], input->xy[1]);
+ wl_surface_commit(surface);
+ }
+ }
+#endif
zwp_locked_pointer_v1_destroy(input->locked_pointer);
input->locked_pointer = nullptr;
}
}
- if (!use_confine) {
+ if (!grab_state_next.use_confine) {
if (input->confined_pointer) {
zwp_confined_pointer_v1_destroy(input->confined_pointer);
input->confined_pointer = nullptr;
@@ -2800,8 +3075,8 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mo
}
if (mode != GHOST_kGrabDisable) {
- if (use_lock) {
- if (!was_lock) {
+ if (grab_state_next.use_lock) {
+ if (!grab_state_prev.use_lock) {
/* TODO(@campbellbarton): As WAYLAND does not support warping the pointer it may not be
* possible to support #GHOST_kGrabWrap by pragmatically settings it's coordinates.
* An alternative could be to draw the cursor in software (and hide the real cursor),
@@ -2818,8 +3093,8 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mo
ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
}
}
- else if (use_confine) {
- if (!was_confine) {
+ else if (grab_state_next.use_confine) {
+ if (!grab_state_prev.use_confine) {
input->confined_pointer = zwp_pointer_constraints_v1_confine_pointer(
d->pointer_constraints,
surface,
@@ -2828,12 +3103,15 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mo
ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
}
}
-
- if (use_hide && !was_hide) {
- setCursorVisibility(false);
- }
}
+ /* Only show so the cursor is made visible as the last step. */
+ cursor_visible_set(input, use_visible, is_hardware_cursor, CURSOR_VISIBLE_ONLY_SHOW);
+
+#ifdef USE_GNOME_CONFINE_HACK
+ input->xy_software_confine = use_software_confine;
+#endif
+
return GHOST_kSuccess;
}
diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h
index 762ceb80e38..4b953dccac6 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.h
+++ b/intern/ghost/intern/GHOST_SystemWayland.h
@@ -12,7 +12,9 @@
#include "GHOST_WindowWayland.h"
#include <wayland-client.h>
-#include <xdg-decoration-client-protocol.h>
+
+/* Generated by `wayland-scanner`. */
+#include <xdg-decoration-unstable-v1-client-protocol.h>
#include <xdg-shell-client-protocol.h>
#include <string>
@@ -32,6 +34,7 @@ struct output_t {
int32_t size_logical[2] = {0, 0};
bool has_size_logical = false;
+ /** Monitor position in pixels. */
int32_t position_logical[2] = {0, 0};
bool has_position_logical = false;
@@ -122,11 +125,15 @@ class GHOST_SystemWayland : public GHOST_System {
int hotY,
bool canInvertColor);
+ GHOST_TSuccess getCursorBitmap(GHOST_CursorBitmapRef *bitmap);
+
GHOST_TSuccess setCursorVisibility(bool visible);
bool supportsCursorWarp();
bool supportsWindowPosition();
+ bool getCursorGrabUseSoftwareDisplay(const GHOST_TGrabCursorMode mode);
+
GHOST_TSuccess setCursorGrab(const GHOST_TGrabCursorMode mode,
const GHOST_TGrabCursorMode mode_current,
wl_surface *surface);
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index e93a56cc8d4..bed9cd6c784 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -506,8 +506,9 @@ static void destroyIMCallback(XIM /*xim*/, XPointer ptr, XPointer /*data*/)
{
GHOST_PRINT("XIM server died\n");
- if (ptr)
+ if (ptr) {
*(XIM *)ptr = nullptr;
+ }
}
bool GHOST_SystemX11::openX11_IM()
@@ -519,8 +520,9 @@ bool GHOST_SystemX11::openX11_IM()
XSetLocaleModifiers("");
m_xim = XOpenIM(m_display, nullptr, (char *)GHOST_X11_RES_NAME, (char *)GHOST_X11_RES_CLASS);
- if (!m_xim)
+ if (!m_xim) {
return false;
+ }
XIMCallback destroy;
destroy.callback = (XIMProc)destroyIMCallback;
@@ -641,10 +643,11 @@ bool GHOST_SystemX11::processEvents(bool waitForEvent)
SleepTillEvent(m_display, -1);
}
else {
- int64_t maxSleep = next - getMilliSeconds();
+ const int64_t maxSleep = next - getMilliSeconds();
- if (maxSleep >= 0)
+ if (maxSleep >= 0) {
SleepTillEvent(m_display, next - getMilliSeconds());
+ }
}
}
@@ -692,8 +695,9 @@ bool GHOST_SystemX11::processEvents(bool waitForEvent)
}
else if (xevent.type == KeyPress) {
if ((xevent.xkey.keycode == m_last_release_keycode) &&
- ((xevent.xkey.time <= m_last_release_time)))
+ ((xevent.xkey.time <= m_last_release_time))) {
continue;
+ }
}
processEvent(&xevent);
@@ -733,7 +737,7 @@ bool GHOST_SystemX11::processEvents(bool waitForEvent)
XK_Super_R,
};
- for (int i = 0; i < (sizeof(modifiers) / sizeof(*modifiers)); i++) {
+ for (int i = 0; i < (int)(sizeof(modifiers) / sizeof(*modifiers)); i++) {
KeyCode kc = XKeysymToKeycode(m_display, modifiers[i]);
if (kc != 0 && ((xevent.xkeymap.key_vector[kc >> 3] >> (kc & 7)) & 1) != 0) {
pushEvent(new GHOST_EventKey(getMilliSeconds(),
@@ -1233,36 +1237,46 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
/* process wheel mouse events and break, only pass on press events */
if (xbe.button == Button4) {
- if (xbe.type == ButtonPress)
+ if (xbe.type == ButtonPress) {
g_event = new GHOST_EventWheel(getMilliSeconds(), window, 1);
+ }
break;
}
- else if (xbe.button == Button5) {
- if (xbe.type == ButtonPress)
+ if (xbe.button == Button5) {
+ if (xbe.type == ButtonPress) {
g_event = new GHOST_EventWheel(getMilliSeconds(), window, -1);
+ }
break;
}
/* process rest of normal mouse buttons */
- if (xbe.button == Button1)
+ if (xbe.button == Button1) {
gbmask = GHOST_kButtonMaskLeft;
- else if (xbe.button == Button2)
+ }
+ else if (xbe.button == Button2) {
gbmask = GHOST_kButtonMaskMiddle;
- else if (xbe.button == Button3)
+ }
+ else if (xbe.button == Button3) {
gbmask = GHOST_kButtonMaskRight;
- /* It seems events 6 and 7 are for horizontal scrolling.
- * you can re-order button mapping like this... (swaps 6,7 with 8,9)
- * `xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7"` */
- else if (xbe.button == 6)
+ /* It seems events 6 and 7 are for horizontal scrolling.
+ * you can re-order button mapping like this... (swaps 6,7 with 8,9)
+ * `xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7"` */
+ }
+ else if (xbe.button == 6) {
gbmask = GHOST_kButtonMaskButton6;
- else if (xbe.button == 7)
+ }
+ else if (xbe.button == 7) {
gbmask = GHOST_kButtonMaskButton7;
- else if (xbe.button == 8)
+ }
+ else if (xbe.button == 8) {
gbmask = GHOST_kButtonMaskButton4;
- else if (xbe.button == 9)
+ }
+ else if (xbe.button == 9) {
gbmask = GHOST_kButtonMaskButton5;
- else
+ }
+ else {
break;
+ }
g_event = new GHOST_EventButton(
getMilliSeconds(), type, window, gbmask, window->GetTabletData());
@@ -1326,8 +1340,9 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
if (XGetWindowAttributes(m_display, xcme.window, &attr) == True) {
if (XGetInputFocus(m_display, &fwin, &revert_to) == True) {
if (attr.map_state == IsViewable) {
- if (fwin != xcme.window)
+ if (fwin != xcme.window) {
XSetInputFocus(m_display, xcme.window, RevertToParent, xcme.data.l[1]);
+ }
}
}
}
@@ -1376,10 +1391,12 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
// printf("X: %s window %d\n",
// xce.type == EnterNotify ? "entering" : "leaving", (int) xce.window);
- if (xce.type == EnterNotify)
+ if (xce.type == EnterNotify) {
m_windowManager->setActiveWindow(window);
- else
+ }
+ else {
m_windowManager->setWindowInactive(window);
+ }
break;
}
@@ -1645,10 +1662,10 @@ static GHOST_TSuccess getCursorPosition_impl(Display *display,
&mask_return) == False) {
return GHOST_kFailure;
}
- else {
- x = rx;
- y = ry;
- }
+
+ x = rx;
+ y = ry;
+
return GHOST_kSuccess;
}
@@ -1955,18 +1972,19 @@ void GHOST_SystemX11::getClipboard_xcout(const XEvent *evt,
return;
case XCLIB_XCOUT_SENTCONVSEL:
- if (evt->type != SelectionNotify)
+ if (evt->type != SelectionNotify) {
return;
+ }
if (target == m_atom.UTF8_STRING && evt->xselection.property == None) {
*context = XCLIB_XCOUT_FALLBACK_UTF8;
return;
}
- else if (target == m_atom.COMPOUND_TEXT && evt->xselection.property == None) {
+ if (target == m_atom.COMPOUND_TEXT && evt->xselection.property == None) {
*context = XCLIB_XCOUT_FALLBACK_COMP;
return;
}
- else if (target == m_atom.TEXT && evt->xselection.property == None) {
+ if (target == m_atom.TEXT && evt->xselection.property == None) {
*context = XCLIB_XCOUT_FALLBACK_TEXT;
return;
}
@@ -2042,12 +2060,14 @@ void GHOST_SystemX11::getClipboard_xcout(const XEvent *evt,
* then read it, delete it, etc. */
/* make sure that the event is relevant */
- if (evt->type != PropertyNotify)
+ if (evt->type != PropertyNotify) {
return;
+ }
/* skip unless the property has a new value */
- if (evt->xproperty.state != PropertyNewValue)
+ if (evt->xproperty.state != PropertyNewValue) {
return;
+ }
/* check size and format of the property */
XGetWindowProperty(m_display,
@@ -2121,7 +2141,6 @@ void GHOST_SystemX11::getClipboard_xcout(const XEvent *evt,
XFlush(m_display);
return;
}
- return;
}
char *GHOST_SystemX11::getClipboard(bool selection) const
@@ -2136,10 +2155,12 @@ char *GHOST_SystemX11::getClipboard(bool selection) const
XEvent evt;
unsigned int context = XCLIB_XCOUT_NONE;
- if (selection == True)
+ if (selection == True) {
sseln = m_atom.PRIMARY;
- else
+ }
+ else {
sseln = m_atom.CLIPBOARD;
+ }
const vector<GHOST_IWindow *> &win_vec = m_windowManager->getWindows();
vector<GHOST_IWindow *>::const_iterator win_it = win_vec.begin();
@@ -2154,20 +2175,18 @@ char *GHOST_SystemX11::getClipboard(bool selection) const
strcpy(sel_buf, txt_cut_buffer);
return sel_buf;
}
- else {
- sel_buf = (char *)malloc(strlen(txt_select_buffer) + 1);
- strcpy(sel_buf, txt_select_buffer);
- return sel_buf;
- }
+ sel_buf = (char *)malloc(strlen(txt_select_buffer) + 1);
+ strcpy(sel_buf, txt_select_buffer);
+ return sel_buf;
}
- else if (owner == None) {
+ if (owner == None) {
return nullptr;
}
/* Restore events so copy doesn't swallow other event types (keyboard/mouse). */
vector<XEvent> restore_events;
- while (1) {
+ while (true) {
/* only get an event if xcout() is doing something */
bool restore_this_event = false;
if (context != XCLIB_XCOUT_NONE) {
@@ -2188,26 +2207,27 @@ char *GHOST_SystemX11::getClipboard(bool selection) const
target = m_atom.STRING;
continue;
}
- else if (context == XCLIB_XCOUT_FALLBACK_UTF8) {
+ if (context == XCLIB_XCOUT_FALLBACK_UTF8) {
/* utf8 fail, move to compound text. */
context = XCLIB_XCOUT_NONE;
target = m_atom.COMPOUND_TEXT;
continue;
}
- else if (context == XCLIB_XCOUT_FALLBACK_COMP) {
+ if (context == XCLIB_XCOUT_FALLBACK_COMP) {
/* Compound text fail, move to text. */
context = XCLIB_XCOUT_NONE;
target = m_atom.TEXT;
continue;
}
- else if (context == XCLIB_XCOUT_FALLBACK_TEXT) {
+ if (context == XCLIB_XCOUT_FALLBACK_TEXT) {
/* Text fail, nothing else to try, break. */
context = XCLIB_XCOUT_NONE;
}
/* Only continue if #xcout() is doing something. */
- if (context == XCLIB_XCOUT_NONE)
+ if (context == XCLIB_XCOUT_NONE) {
break;
+ }
}
while (!restore_events.empty()) {
@@ -2221,10 +2241,12 @@ char *GHOST_SystemX11::getClipboard(bool selection) const
memcpy(tmp_data, (char *)sel_buf, sel_len);
tmp_data[sel_len] = '\0';
- if (sseln == m_atom.STRING)
+ if (sseln == m_atom.STRING) {
XFree(sel_buf);
- else
+ }
+ else {
free(sel_buf);
+ }
return tmp_data;
}
@@ -2244,8 +2266,9 @@ void GHOST_SystemX11::putClipboard(const char *buffer, bool selection) const
if (selection == False) {
XSetSelectionOwner(m_display, m_atom.CLIPBOARD, m_window, CurrentTime);
owner = XGetSelectionOwner(m_display, m_atom.CLIPBOARD);
- if (txt_cut_buffer)
+ if (txt_cut_buffer) {
free((void *)txt_cut_buffer);
+ }
txt_cut_buffer = (char *)malloc(strlen(buffer) + 1);
strcpy(txt_cut_buffer, buffer);
@@ -2253,15 +2276,17 @@ void GHOST_SystemX11::putClipboard(const char *buffer, bool selection) const
else {
XSetSelectionOwner(m_display, m_atom.PRIMARY, m_window, CurrentTime);
owner = XGetSelectionOwner(m_display, m_atom.PRIMARY);
- if (txt_select_buffer)
+ if (txt_select_buffer) {
free((void *)txt_select_buffer);
+ }
txt_select_buffer = (char *)malloc(strlen(buffer) + 1);
strcpy(txt_select_buffer, buffer);
}
- if (owner != m_window)
+ if (owner != m_window) {
fprintf(stderr, "failed to own primary\n");
+ }
}
}
@@ -2374,7 +2399,7 @@ GHOST_TSuccess GHOST_SystemX11::showMessageBox(const char *title,
const char *help_label,
const char *continue_label,
const char *link,
- GHOST_DialogOptions) const
+ GHOST_DialogOptions /*dialog_options*/) const
{
char **text_splitted = nullptr;
int textLines = 0;
@@ -2557,18 +2582,23 @@ static bool match_token(const char *haystack, const char *needle)
{
const char *h, *n;
for (h = haystack; *h;) {
- while (*h && is_filler_char(*h))
+ while (*h && is_filler_char(*h)) {
h++;
- if (!*h)
+ }
+ if (!*h) {
break;
+ }
- for (n = needle; *n && *h && tolower(*h) == tolower(*n); n++)
+ for (n = needle; *n && *h && tolower(*h) == tolower(*n); n++) {
h++;
- if (!*n && (is_filler_char(*h) || !*h))
+ }
+ if (!*n && (is_filler_char(*h) || !*h)) {
return true;
+ }
- while (*h && !is_filler_char(*h))
+ while (*h && !is_filler_char(*h)) {
h++;
+ }
}
return false;
}
diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp
index de7c5422d3f..3f093840d0c 100644
--- a/intern/ghost/intern/GHOST_Window.cpp
+++ b/intern/ghost/intern/GHOST_Window.cpp
@@ -164,7 +164,8 @@ GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect &bounds)
void GHOST_Window::getCursorGrabState(GHOST_TGrabCursorMode &mode,
GHOST_TAxisFlag &wrap_axis,
- GHOST_Rect &bounds)
+ GHOST_Rect &bounds,
+ bool &use_software_cursor)
{
mode = m_cursorGrab;
if (m_cursorGrab == GHOST_kGrabWrap) {
@@ -178,6 +179,14 @@ void GHOST_Window::getCursorGrabState(GHOST_TGrabCursorMode &mode,
bounds.m_b = -1;
wrap_axis = GHOST_kGrabAxisNone;
}
+ use_software_cursor = (m_cursorGrab != GHOST_kGrabDisable) ? getCursorGrabUseSoftwareDisplay() :
+ false;
+}
+
+bool GHOST_Window::getCursorGrabUseSoftwareDisplay()
+{
+ /* Sub-classes may override, by default don't use software cursor. */
+ return false;
}
GHOST_TSuccess GHOST_Window::setCursorShape(GHOST_TStandardCursor cursorShape)
@@ -199,6 +208,12 @@ GHOST_TSuccess GHOST_Window::setCustomCursorShape(
return GHOST_kFailure;
}
+GHOST_TSuccess GHOST_Window::getCursorBitmap(GHOST_CursorBitmapRef * /*bitmap*/)
+{
+ /* Sub-classes may override. */
+ return GHOST_kFailure;
+}
+
void GHOST_Window::setAcceptDragOperation(bool canAccept)
{
m_canAcceptDragOperation = canAccept;
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index adbc29eb84e..5ff91c05b16 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -117,6 +117,8 @@ class GHOST_Window : public GHOST_IWindow {
int hotY,
bool canInvertColor);
+ GHOST_TSuccess getCursorBitmap(GHOST_CursorBitmapRef *bitmap);
+
/**
* Returns the visibility state of the cursor.
* \return The visibility state of the cursor.
@@ -154,7 +156,12 @@ class GHOST_Window : public GHOST_IWindow {
void getCursorGrabState(GHOST_TGrabCursorMode &mode,
GHOST_TAxisFlag &axis_flag,
- GHOST_Rect &bounds);
+ GHOST_Rect &bounds,
+ bool &use_software_cursor);
+ /**
+ * Return true when a software cursor should be used.
+ */
+ bool getCursorGrabUseSoftwareDisplay();
/**
* Sets the progress bar value displayed in the window/application icon
diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp
index 21e3793d3b1..941e08ff035 100644
--- a/intern/ghost/intern/GHOST_WindowWayland.cpp
+++ b/intern/ghost/intern/GHOST_WindowWayland.cpp
@@ -492,12 +492,22 @@ GHOST_TSuccess GHOST_WindowWayland::setWindowCursorShape(GHOST_TStandardCursor s
return ok;
}
+bool GHOST_WindowWayland::getCursorGrabUseSoftwareDisplay()
+{
+ return m_system->getCursorGrabUseSoftwareDisplay(m_cursorGrab);
+}
+
GHOST_TSuccess GHOST_WindowWayland::setWindowCustomCursorShape(
uint8_t *bitmap, uint8_t *mask, int sizex, int sizey, int hotX, int hotY, bool canInvertColor)
{
return m_system->setCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, canInvertColor);
}
+GHOST_TSuccess GHOST_WindowWayland::getCursorBitmap(GHOST_CursorBitmapRef *bitmap)
+{
+ return m_system->getCursorBitmap(bitmap);
+}
+
void GHOST_WindowWayland::setTitle(const char *title)
{
xdg_toplevel_set_title(w->xdg_toplevel, title);
diff --git a/intern/ghost/intern/GHOST_WindowWayland.h b/intern/ghost/intern/GHOST_WindowWayland.h
index b6d9fa04079..89354c54c0f 100644
--- a/intern/ghost/intern/GHOST_WindowWayland.h
+++ b/intern/ghost/intern/GHOST_WindowWayland.h
@@ -10,7 +10,6 @@
#include "GHOST_Window.h"
-#include <unordered_set>
#include <vector>
class GHOST_SystemWayland;
@@ -52,6 +51,9 @@ class GHOST_WindowWayland : public GHOST_Window {
int hotX,
int hotY,
bool canInvertColor) override;
+ bool getCursorGrabUseSoftwareDisplay() override;
+
+ GHOST_TSuccess getCursorBitmap(GHOST_CursorBitmapRef *bitmap) override;
void setTitle(const char *title) override;
diff --git a/intern/ghost/intern/GHOST_XrAction.cpp b/intern/ghost/intern/GHOST_XrAction.cpp
index 587b1124848..0e725bf4075 100644
--- a/intern/ghost/intern/GHOST_XrAction.cpp
+++ b/intern/ghost/intern/GHOST_XrAction.cpp
@@ -332,23 +332,26 @@ void GHOST_XrAction::updateState(XrSession session,
break;
}
case GHOST_kXrActionTypePoseInput: {
- XrActionStatePose state{XR_TYPE_ACTION_STATE_POSE};
- CHECK_XR(
- xrGetActionStatePose(session, &state_info, &state),
- (std::string("Failed to get state for pose action \"") + action_name + "\".").data());
- if (state.isActive) {
- XrSpace pose_space = ((subaction != nullptr) && (subaction->space != nullptr)) ?
- subaction->space->getSpace() :
- XR_NULL_HANDLE;
- if (pose_space != XR_NULL_HANDLE) {
- XrSpaceLocation space_location{XR_TYPE_SPACE_LOCATION};
- CHECK_XR(
- xrLocateSpace(
- pose_space, reference_space, predicted_display_time, &space_location),
- (std::string("Failed to query pose space for action \"") + action_name + "\".")
- .data());
- copy_openxr_pose_to_ghost_pose(space_location.pose,
- ((GHOST_XrPose *)m_states)[subaction_idx]);
+ /* Check for valid display time to avoid an error in #xrLocateSpace(). */
+ if (predicted_display_time > 0) {
+ XrActionStatePose state{XR_TYPE_ACTION_STATE_POSE};
+ CHECK_XR(xrGetActionStatePose(session, &state_info, &state),
+ (std::string("Failed to get state for pose action \"") + action_name + "\".")
+ .data());
+ if (state.isActive) {
+ XrSpace pose_space = ((subaction != nullptr) && (subaction->space != nullptr)) ?
+ subaction->space->getSpace() :
+ XR_NULL_HANDLE;
+ if (pose_space != XR_NULL_HANDLE) {
+ XrSpaceLocation space_location{XR_TYPE_SPACE_LOCATION};
+ CHECK_XR(
+ xrLocateSpace(
+ pose_space, reference_space, predicted_display_time, &space_location),
+ (std::string("Failed to query pose space for action \"") + action_name + "\".")
+ .data());
+ copy_openxr_pose_to_ghost_pose(space_location.pose,
+ ((GHOST_XrPose *)m_states)[subaction_idx]);
+ }
}
}
break;
diff --git a/intern/ghost/test/gears/GHOST_C-Test.c b/intern/ghost/test/gears/GHOST_C-Test.c
index 71f3a6f43b4..46c8fda0665 100644
--- a/intern/ghost/test/gears/GHOST_C-Test.c
+++ b/intern/ghost/test/gears/GHOST_C-Test.c
@@ -31,7 +31,7 @@
#endif /* defined(WIN32) || defined(__APPLE__) */
static void gearsTimerProc(GHOST_TimerTaskHandle task, uint64_t time);
-int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData);
+bool processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData);
static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
static GLfloat fAngle = 0.0;
@@ -269,9 +269,9 @@ static void setViewPortGL(GHOST_WindowHandle hWindow)
GHOST_DisposeRectangle(hRect);
}
-int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
+bool processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
{
- int handled = 1;
+ bool handled = true;
int cursor;
int visibility;
GHOST_TEventKeyData *keyData = NULL;
@@ -389,10 +389,10 @@ int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
} break;
case GHOST_kEventWindowActivate:
- handled = 0;
+ handled = false;
break;
case GHOST_kEventWindowDeactivate:
- handled = 0;
+ handled = false;
break;
case GHOST_kEventWindowUpdate: {
GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent);
@@ -404,7 +404,7 @@ int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
} break;
default:
- handled = 0;
+ handled = false;
break;
}
return handled;
diff --git a/intern/ghost/test/multitest/MultiTest.c b/intern/ghost/test/multitest/MultiTest.c
index 35b1de65171..157e4f1b0f2 100644
--- a/intern/ghost/test/multitest/MultiTest.c
+++ b/intern/ghost/test/multitest/MultiTest.c
@@ -812,7 +812,7 @@ struct _MultiTestApp {
int exit;
};
-static int multitest_event_handler(GHOST_EventHandle evt, GHOST_TUserDataPtr data)
+static bool multitest_event_handler(GHOST_EventHandle evt, GHOST_TUserDataPtr data)
{
MultiTestApp *app = data;
GHOST_WindowHandle win;
@@ -820,7 +820,7 @@ static int multitest_event_handler(GHOST_EventHandle evt, GHOST_TUserDataPtr dat
win = GHOST_GetEventWindow(evt);
if (win && !GHOST_ValidWindow(app->sys, win)) {
loggerwindow_log(app->logger, "WARNING: bad event, non-valid window\n");
- return 1;
+ return true;
}
if (win) {
@@ -845,7 +845,7 @@ static int multitest_event_handler(GHOST_EventHandle evt, GHOST_TUserDataPtr dat
}
}
- return 1;
+ return true;
}
/**/
diff --git a/release/datafiles/locale b/release/datafiles/locale
-Subproject 915744ad8e255d1723d77671a6c6b074773c219
+Subproject 9a85b13795157560b319235c63f5a13b0107ba4
diff --git a/release/scripts/addons b/release/scripts/addons
-Subproject c51e0bb1793c44c7a1b7435593dd5022cf7c8ee
+Subproject bdf75cb276dfd3b5266c909de4c099c00c68a65
diff --git a/release/scripts/modules/rna_manual_reference.py b/release/scripts/modules/rna_manual_reference.py
index 9896bd3e281..cfce84f84e3 100644
--- a/release/scripts/modules/rna_manual_reference.py
+++ b/release/scripts/modules/rna_manual_reference.py
@@ -189,6 +189,7 @@ url_manual_mapping = (
("bpy.types.rendersettings_simplify_gpencil_view_fill*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-view-fill"),
("bpy.types.sequencertoolsettings.snap_to_hold_offset*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-snap-to-hold-offset"),
("bpy.types.toolsettings.use_mesh_automerge_and_split*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-mesh-automerge-and-split"),
+ ("bpy.ops.scene.view_layer_remove_unused_lightgroups*", "render/layers/passes.html#bpy-ops-scene-view-layer-remove-unused-lightgroups"),
("bpy.types.animvizmotionpaths.show_keyframe_numbers*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-keyframe-numbers"),
("bpy.types.brush.cloth_constraint_softbody_strength*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-constraint-softbody-strength"),
("bpy.types.brush.elastic_deform_volume_preservation*", "sculpt_paint/sculpting/tools/elastic_deform.html#bpy-types-brush-elastic-deform-volume-preservation"),
@@ -302,11 +303,13 @@ url_manual_mapping = (
("bpy.types.rigidbodyconstraint.breaking_threshold*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-breaking-threshold"),
("bpy.types.spaceclipeditor.use_manual_calibration*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-manual-calibration"),
("bpy.types.spacedopesheeteditor.show_pose_markers*", "animation/markers.html#bpy-types-spacedopesheeteditor-show-pose-markers"),
+ ("bpy.types.spaceimageoverlay.show_grid_background*", "editors/uv/overlays.html#bpy-types-spaceimageoverlay-show-grid-background"),
+ ("bpy.types.spacenodeoverlay.show_named_attributes*", "modeling/geometry_nodes/inspection.html#bpy-types-spacenodeoverlay-show-named-attributes"),
("bpy.types.spaceoutliner.use_filter_object_camera*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-camera"),
("bpy.types.spaceoutliner.use_filter_object_others*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-others"),
("bpy.types.spacesequenceeditor.overlay_frame_type*", "editors/video_sequencer/preview/sidebar.html#bpy-types-spacesequenceeditor-overlay-frame-type"),
("bpy.types.spacesequenceeditor.show_strip_overlay*", "editors/video_sequencer/sequencer/display.html#bpy-types-spacesequenceeditor-show-strip-overlay"),
- ("bpy.types.spaceuveditor.custom_grid_subdivisions*", "editors/uv/sidebar.html#bpy-types-spaceuveditor-custom-grid-subdivisions"),
+ ("bpy.types.spaceuveditor.custom_grid_subdivisions*", "editors/uv/overlays.html#bpy-types-spaceuveditor-custom-grid-subdivisions"),
("bpy.types.toolsettings.proportional_edit_falloff*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-proportional-edit-falloff"),
("bpy.types.toolsettings.use_edge_path_live_unwrap*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-edge-path-live-unwrap"),
("bpy.types.toolsettings.use_gpencil_draw_additive*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-additive"),
@@ -388,6 +391,7 @@ url_manual_mapping = (
("bpy.types.geometrynodecurvehandletypeselection*", "modeling/geometry_nodes/curve/handle_type_selection.html#bpy-types-geometrynodecurvehandletypeselection"),
("bpy.types.geometrynodeinputmeshvertexneighbors*", "modeling/geometry_nodes/mesh/vertex_neighbors.html#bpy-types-geometrynodeinputmeshvertexneighbors"),
("bpy.types.greasepencil.curve_edit_corner_angle*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-corner-angle"),
+ ("bpy.types.imageformatsettings.color_management*", "render/output/properties/output.html#bpy-types-imageformatsettings-color-management"),
("bpy.types.lineartgpencilmodifier.source_camera*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-source-camera"),
("bpy.types.lineartgpencilmodifier.use_face_mark*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-face-mark"),
("bpy.types.linestylegeometrymodifier_tipremover*", "render/freestyle/view_layer/line_style/modifiers/geometry/tip_remover.html#bpy-types-linestylegeometrymodifier-tipremover"),
@@ -404,6 +408,7 @@ url_manual_mapping = (
("bpy.types.viewlayer.use_pass_cryptomatte_asset*", "render/layers/passes.html#bpy-types-viewlayer-use-pass-cryptomatte-asset"),
("bpy.ops.outliner.collection_indirect_only_set*", "render/layers/introduction.html#bpy-ops-outliner-collection-indirect-only-set"),
("bpy.ops.scene.freestyle_geometry_modifier_add*", "render/freestyle/view_layer/line_style/geometry.html#bpy-ops-scene-freestyle-geometry-modifier-add"),
+ ("bpy.ops.scene.view_layer_add_used_lightgroups*", "render/layers/passes.html#bpy-ops-scene-view-layer-add-used-lightgroups"),
("bpy.ops.sequencer.deinterlace_selected_movies*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-deinterlace-selected-movies"),
("bpy.types.bakesettings.use_selected_to_active*", "render/cycles/baking.html#bpy-types-bakesettings-use-selected-to-active"),
("bpy.types.brush.surface_smooth_current_vertex*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-current-vertex"),
@@ -420,6 +425,7 @@ url_manual_mapping = (
("bpy.types.cyclesworldsettings.sampling_method*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-sampling-method"),
("bpy.types.cyclesworldsettings.volume_sampling*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-volume-sampling"),
("bpy.types.editbone.bbone_handle_use_scale_end*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-use-scale-end"),
+ ("bpy.types.ffmpegsettings.constant_rate_factor*", "render/output/properties/output.html#bpy-types-ffmpegsettings-constant-rate-factor"),
("bpy.types.fluiddomainsettings.adapt_threshold*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-adapt-threshold"),
("bpy.types.fluiddomainsettings.cache_directory*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-directory"),
("bpy.types.fluiddomainsettings.cache_frame_end*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-frame-end"),
@@ -510,12 +516,14 @@ url_manual_mapping = (
("bpy.types.spaceclipeditor.show_green_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-green-channel"),
("bpy.types.spacenodeoverlay.show_context_path*", "interface/controls/nodes/introduction.html#bpy-types-spacenodeoverlay-show-context-path"),
("bpy.types.spaceoutliner.show_restrict_column*", "editors/outliner/interface.html#bpy-types-spaceoutliner-show-restrict-column"),
+ ("bpy.types.spacesequenceeditor.use_clamp_view*", "editors/video_sequencer/sequencer/navigating.html#bpy-types-spacesequenceeditor-use-clamp-view"),
("bpy.types.spacespreadsheet.object_eval_state*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-object-eval-state"),
("bpy.types.spaceuveditor.display_stretch_type*", "editors/uv/overlays.html#bpy-types-spaceuveditor-display-stretch-type"),
("bpy.types.toolsettings.transform_pivot_point*", "editors/3dview/controls/pivot_point/index.html#bpy-types-toolsettings-transform-pivot-point"),
("bpy.types.toolsettings.use_proportional_edit*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-edit"),
("bpy.types.toolsettings.uv_sticky_select_mode*", "editors/uv/selecting.html#bpy-types-toolsettings-uv-sticky-select-mode"),
("bpy.types.volumedisplay.interpolation_method*", "modeling/volumes/properties.html#bpy-types-volumedisplay-interpolation-method"),
+ ("bpy.ops.geometry.color_attribute_render_set*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-render-set"),
("bpy.types.brushgpencilsettings.angle_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle-factor"),
("bpy.types.brushgpencilsettings.pen_strength*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-pen-strength"),
("bpy.types.clothsettings.use_pressure_volume*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-use-pressure-volume"),
@@ -538,6 +546,7 @@ url_manual_mapping = (
("bpy.types.freestylelinestyle.use_length_max*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-length-max"),
("bpy.types.freestylelinestyle.use_length_min*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-length-min"),
("bpy.types.geometrynodeinputmeshedgevertices*", "modeling/geometry_nodes/mesh/edge_vertices.html#bpy-types-geometrynodeinputmeshedgevertices"),
+ ("bpy.types.geometrynodeinputmeshfaceisplanar*", "modeling/geometry_nodes/mesh/face_is_planar.html#bpy-types-geometrynodeinputmeshfaceisplanar"),
("bpy.types.geometrynodeinputsplineresolution*", "modeling/geometry_nodes/curve/spline_resolution.html#bpy-types-geometrynodeinputsplineresolution"),
("bpy.types.greasepencil.curve_edit_threshold*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-threshold"),
("bpy.types.materialgpencilstyle.stroke_style*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-stroke-style"),
@@ -561,11 +570,14 @@ url_manual_mapping = (
("bpy.types.toolsettings.use_snap_peel_object*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-peel-object"),
("bpy.types.view3doverlay.fade_inactive_alpha*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-fade-inactive-alpha"),
("bpy.types.view3doverlay.wireframe_threshold*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-wireframe-threshold"),
+ ("bpy.types.viewlayer.active_lightgroup_index*", "render/layers/passes.html#bpy-types-viewlayer-active-lightgroup-index"),
+ ("bpy.ops.ed.lib_id_override_editable_toggle*", "editors/outliner/interface.html#bpy-ops-ed-lib-id-override-editable-toggle"),
("bpy.ops.object.constraint_add_with_targets*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-constraint-add-with-targets"),
("bpy.ops.object.material_slot_remove_unused*", "scene_layout/object/editing/cleanup.html#bpy-ops-object-material-slot-remove-unused"),
("bpy.ops.outliner.collection_disable_render*", "editors/outliner/editing.html#bpy-ops-outliner-collection-disable-render"),
("bpy.ops.scene.freestyle_alpha_modifier_add*", "render/freestyle/view_layer/line_style/alpha.html#bpy-ops-scene-freestyle-alpha-modifier-add"),
("bpy.ops.scene.freestyle_color_modifier_add*", "render/freestyle/view_layer/line_style/color.html#bpy-ops-scene-freestyle-color-modifier-add"),
+ ("bpy.ops.scene.view_layer_remove_lightgroup*", "render/layers/passes.html#bpy-ops-scene-view-layer-remove-lightgroup"),
("bpy.types.brush.cloth_simulation_area_type*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-simulation-area-type"),
("bpy.types.brushgpencilsettings.eraser_mode*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-eraser-mode"),
("bpy.types.brushgpencilsettings.fill_factor*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-factor"),
@@ -599,6 +611,7 @@ url_manual_mapping = (
("bpy.types.freestylesettings.use_smoothness*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-smoothness"),
("bpy.types.geometrynodecurveprimitivecircle*", "modeling/geometry_nodes/curve_primitives/curve_circle.html#bpy-types-geometrynodecurveprimitivecircle"),
("bpy.types.geometrynodecurvequadraticbezier*", "modeling/geometry_nodes/curve_primitives/quadratic_bezier.html#bpy-types-geometrynodecurvequadraticbezier"),
+ ("bpy.types.geometrynoderemovenamedattribute*", "modeling/geometry_nodes/attribute/remove_named_attribute.html#bpy-types-geometrynoderemovenamedattribute"),
("bpy.types.gpencillayer.use_viewlayer_masks*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-viewlayer-masks"),
("bpy.types.greasepencil.onion_keyframe_type*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-onion-keyframe-type"),
("bpy.types.lineartgpencilmodifier.use_cache*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-cache"),
@@ -642,6 +655,7 @@ url_manual_mapping = (
("bpy.types.cyclesrendersettings.time_limit*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-time-limit"),
("bpy.types.cyclesvisibilitysettings.camera*", "render/cycles/world_settings.html#bpy-types-cyclesvisibilitysettings-camera"),
("bpy.types.cyclesworldsettings.max_bounces*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-max-bounces"),
+ ("bpy.types.ffmpegsettings.use_max_b_frames*", "render/output/properties/output.html#bpy-types-ffmpegsettings-use-max-b-frames"),
("bpy.types.fluiddomainsettings.domain_type*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-domain-type"),
("bpy.types.fluiddomainsettings.flame_smoke*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flame-smoke"),
("bpy.types.fluiddomainsettings.fluid_group*", "physics/fluid/type/domain/collections.html#bpy-types-fluiddomainsettings-fluid-group"),
@@ -657,6 +671,7 @@ url_manual_mapping = (
("bpy.types.freestylesettings.sphere_radius*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-sphere-radius"),
("bpy.types.geometrynodeattributedomainsize*", "modeling/geometry_nodes/attribute/domain_size.html#bpy-types-geometrynodeattributedomainsize"),
("bpy.types.geometrynodesetsplineresolution*", "modeling/geometry_nodes/curve/set_spline_resolution.html#bpy-types-geometrynodesetsplineresolution"),
+ ("bpy.types.geometrynodestorenamedattribute*", "modeling/geometry_nodes/attribute/store_named_attribute.html#bpy-types-geometrynodestorenamedattribute"),
("bpy.types.gpencillayer.annotation_opacity*", "interface/annotate_tool.html#bpy-types-gpencillayer-annotation-opacity"),
("bpy.types.gpencillayer.use_onion_skinning*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-onion-skinning"),
("bpy.types.gpencilsculptguide.use_snapping*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide-use-snapping"),
@@ -747,6 +762,8 @@ url_manual_mapping = (
("bpy.types.linestyle*modifier_alongstroke*", "render/freestyle/view_layer/line_style/modifiers/color/along_stroke.html#bpy-types-linestyle-modifier-alongstroke"),
("bpy.types.linestyle*modifier_creaseangle*", "render/freestyle/view_layer/line_style/modifiers/color/crease_angle.html#bpy-types-linestyle-modifier-creaseangle"),
("bpy.types.linestylecolormodifier_tangent*", "render/freestyle/view_layer/line_style/modifiers/color/tangent.html#bpy-types-linestylecolormodifier-tangent"),
+ ("bpy.types.material.show_transparent_back*", "render/eevee/materials/settings.html#bpy-types-material-show-transparent-back"),
+ ("bpy.types.material.use_screen_refraction*", "render/eevee/materials/settings.html#bpy-types-material-use-screen-refraction"),
("bpy.types.materialgpencilstyle.mix_color*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-mix-color"),
("bpy.types.materialgpencilstyle.show_fill*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-show-fill"),
("bpy.types.mesh.use_customdata_edge_bevel*", "modeling/meshes/properties/custom_data.html#bpy-types-mesh-use-customdata-edge-bevel"),
@@ -774,6 +791,7 @@ url_manual_mapping = (
("bpy.types.volumedisplay.wireframe_detail*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-detail"),
("bpy.types.windowmanager.asset_path_dummy*", "editors/asset_browser.html#bpy-types-windowmanager-asset-path-dummy"),
("bpy.ops.armature.rigify_add_bone_groups*", "addons/rigging/rigify/metarigs.html#bpy-ops-armature-rigify-add-bone-groups"),
+ ("bpy.ops.geometry.color_attribute_remove*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-remove"),
("bpy.ops.object.assign_property_defaults*", "animation/armatures/posing/editing/apply.html#bpy-ops-object-assign-property-defaults"),
("bpy.ops.object.vertex_group_limit_total*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-limit-total"),
("bpy.ops.object.vertex_group_remove_from*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-remove-from"),
@@ -783,6 +801,7 @@ url_manual_mapping = (
("bpy.ops.outliner.collection_show_inside*", "editors/outliner/editing.html#bpy-ops-outliner-collection-show-inside"),
("bpy.ops.poselib.restore_previous_action*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-restore-previous-action"),
("bpy.ops.preferences.reset_default_theme*", "editors/preferences/themes.html#bpy-ops-preferences-reset-default-theme"),
+ ("bpy.ops.scene.view_layer_add_lightgroup*", "render/layers/passes.html#bpy-ops-scene-view-layer-add-lightgroup"),
("bpy.ops.sequencer.strip_transform_clear*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-strip-transform-clear"),
("bpy.ops.spreadsheet.add_row_filter_rule*", "editors/spreadsheet.html#bpy-ops-spreadsheet-add-row-filter-rule"),
("bpy.types.animdata.action_extrapolation*", "editors/nla/sidebar.html#bpy-types-animdata-action-extrapolation"),
@@ -800,6 +819,7 @@ url_manual_mapping = (
("bpy.types.cyclesrendersettings.caustics*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-caustics"),
("bpy.types.cyclesrendersettings.denoiser*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-denoiser"),
("bpy.types.editbone.use_inherit_rotation*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-use-inherit-rotation"),
+ ("bpy.types.ffmpegsettings.audio_channels*", "render/output/properties/output.html#bpy-types-ffmpegsettings-audio-channels"),
("bpy.types.fileselectparams.display_size*", "editors/file_browser.html#bpy-types-fileselectparams-display-size"),
("bpy.types.fileselectparams.display_type*", "editors/file_browser.html#bpy-types-fileselectparams-display-type"),
("bpy.types.fluiddomainsettings.use_guide*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-use-guide"),
@@ -818,12 +838,14 @@ url_manual_mapping = (
("bpy.types.freestylelinestyle.split_dash*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-split-dash"),
("bpy.types.freestylesettings.use_culling*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-culling"),
("bpy.types.geometrynodeattributetransfer*", "modeling/geometry_nodes/attribute/transfer_attribute.html#bpy-types-geometrynodeattributetransfer"),
+ ("bpy.types.geometrynodeduplicateelements*", "modeling/geometry_nodes/geometry/duplicate_elements.html#bpy-types-geometrynodeduplicateelements"),
("bpy.types.geometrynodeinputmeshfacearea*", "modeling/geometry_nodes/mesh/face_area.html#bpy-types-geometrynodeinputmeshfacearea"),
("bpy.types.geometrynodeinputsplinecyclic*", "modeling/geometry_nodes/curve/is_spline_cyclic.html#bpy-types-geometrynodeinputsplinecyclic"),
("bpy.types.geometrynodeinstancestopoints*", "modeling/geometry_nodes/instances/instances_to_points.html#bpy-types-geometrynodeinstancestopoints"),
("bpy.types.gpencillayer.viewlayer_render*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-viewlayer-render"),
("bpy.types.layercollection.hide_viewport*", "editors/outliner/interface.html#bpy-types-layercollection-hide-viewport"),
("bpy.types.layercollection.indirect_only*", "editors/outliner/interface.html#bpy-types-layercollection-indirect-only"),
+ ("bpy.types.material.use_backface_culling*", "render/eevee/materials/settings.html#bpy-types-material-use-backface-culling"),
("bpy.types.material.use_sss_translucency*", "render/eevee/materials/settings.html#bpy-types-material-use-sss-translucency"),
("bpy.types.materiallineart.mat_occlusion*", "render/materials/line_art.html#bpy-types-materiallineart-mat-occlusion"),
("bpy.types.movietrackingcamera.principal*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-principal"),
@@ -841,7 +863,8 @@ url_manual_mapping = (
("bpy.types.spacetexteditor.margin_column*", "editors/text_editor.html#bpy-types-spacetexteditor-margin-column"),
("bpy.types.spacetexteditor.use_find_wrap*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-wrap"),
("bpy.types.spaceuveditor.pixel_snap_mode*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-pixel-snap-mode"),
- ("bpy.types.spaceuveditor.use_custom_grid*", "editors/uv/sidebar.html#bpy-types-spaceuveditor-use-custom-grid"),
+ ("bpy.types.spaceuveditor.tile_grid_shape*", "editors/uv/overlays.html#bpy-types-spaceuveditor-tile-grid-shape"),
+ ("bpy.types.spaceuveditor.use_custom_grid*", "editors/uv/overlays.html#bpy-types-spaceuveditor-use-custom-grid"),
("bpy.types.spaceuveditor.use_live_unwrap*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-use-live-unwrap"),
("bpy.types.toolsettings.double_threshold*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-double-threshold"),
("bpy.types.toolsettings.lock_object_mode*", "interface/window_system/topbar.html#bpy-types-toolsettings-lock-object-mode"),
@@ -870,6 +893,11 @@ url_manual_mapping = (
("bpy.types.compositornodedoubleedgemask*", "compositing/types/matte/double_edge_mask.html#bpy-types-compositornodedoubleedgemask"),
("bpy.types.cyclesrendersettings.samples*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-samples"),
("bpy.types.dopesheet.show_only_selected*", "editors/dope_sheet/introduction.html#bpy-types-dopesheet-show-only-selected"),
+ ("bpy.types.ffmpegsettings.audio_bitrate*", "render/output/properties/output.html#bpy-types-ffmpegsettings-audio-bitrate"),
+ ("bpy.types.ffmpegsettings.audio_mixrate*", "render/output/properties/output.html#bpy-types-ffmpegsettings-audio-mixrate"),
+ ("bpy.types.ffmpegsettings.ffmpeg_preset*", "render/output/properties/output.html#bpy-types-ffmpegsettings-ffmpeg-preset"),
+ ("bpy.types.ffmpegsettings.use_autosplit*", "render/output/properties/output.html#bpy-types-ffmpegsettings-use-autosplit"),
+ ("bpy.types.ffmpegsettings.video_bitrate*", "render/output/properties/output.html#bpy-types-ffmpegsettings-video-bitrate"),
("bpy.types.fileselectparams.show_hidden*", "editors/file_browser.html#bpy-types-fileselectparams-show-hidden"),
("bpy.types.fileselectparams.sort_method*", "editors/file_browser.html#bpy-types-fileselectparams-sort-method"),
("bpy.types.fluiddomainsettings.clipping*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-clipping"),
@@ -898,10 +926,14 @@ url_manual_mapping = (
("bpy.types.rendersettings.use_sequencer*", "render/output/properties/post_processing.html#bpy-types-rendersettings-use-sequencer"),
("bpy.types.sceneeevee.volumetric_shadow*", "render/eevee/render_settings/volumetrics.html#bpy-types-sceneeevee-volumetric-shadow"),
("bpy.types.sequenceeditor.overlay_frame*", "editors/video_sequencer/preview/sidebar.html#bpy-types-sequenceeditor-overlay-frame"),
+ ("bpy.types.sequencetimelinechannel.lock*", "editors/video_sequencer/sequencer/channels.html#bpy-types-sequencetimelinechannel-lock"),
+ ("bpy.types.sequencetimelinechannel.mute*", "editors/video_sequencer/sequencer/channels.html#bpy-types-sequencetimelinechannel-mute"),
+ ("bpy.types.sequencetimelinechannel.name*", "editors/video_sequencer/sequencer/channels.html#bpy-types-sequencetimelinechannel-name"),
("bpy.types.shadernodebsdfhairprincipled*", "render/shader_nodes/shader/hair_principled.html#bpy-types-shadernodebsdfhairprincipled"),
("bpy.types.shadernodevectordisplacement*", "render/shader_nodes/vector/vector_displacement.html#bpy-types-shadernodevectordisplacement"),
("bpy.types.spacegrapheditor.show_cursor*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-show-cursor"),
("bpy.types.spaceimageeditor.show_repeat*", "editors/image/sidebar.html#bpy-types-spaceimageeditor-show-repeat"),
+ ("bpy.types.spacenodeoverlay.show_timing*", "modeling/geometry_nodes/inspection.html#bpy-types-spacenodeoverlay-show-timing"),
("bpy.types.spaceoutliner.use_sort_alpha*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-sort-alpha"),
("bpy.types.spacepreferences.filter_text*", "editors/preferences/keymap.html#bpy-types-spacepreferences-filter-text"),
("bpy.types.spacepreferences.filter_type*", "editors/preferences/keymap.html#bpy-types-spacepreferences-filter-type"),
@@ -934,6 +966,7 @@ url_manual_mapping = (
("bpy.types.bakesettings.cage_extrusion*", "render/cycles/baking.html#bpy-types-bakesettings-cage-extrusion"),
("bpy.types.bakesettings.use_pass_color*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-color"),
("bpy.types.brush.boundary_falloff_type*", "sculpt_paint/sculpting/tools/boundary.html#bpy-types-brush-boundary-falloff-type"),
+ ("bpy.types.brush.cursor_color_subtract*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-color-subtract"),
("bpy.types.brush.texture_overlay_alpha*", "sculpt_paint/brush/cursor.html#bpy-types-brush-texture-overlay-alpha"),
("bpy.types.brushgpencilsettings.aspect*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-aspect"),
("bpy.types.brushgpencilsettings.dilate*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-dilate"),
@@ -947,6 +980,8 @@ url_manual_mapping = (
("bpy.types.compositornodesetalpha.mode*", "compositing/types/converter/set_alpha.html#bpy-types-compositornodesetalpha-mode"),
("bpy.types.dopesheet.use_filter_invert*", "editors/graph_editor/channels.html#bpy-types-dopesheet-use-filter-invert"),
("bpy.types.editbone.use_local_location*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-use-local-location"),
+ ("bpy.types.ffmpegsettings.audio_volume*", "render/output/properties/output.html#bpy-types-ffmpegsettings-audio-volume"),
+ ("bpy.types.ffmpegsettings.max_b_frames*", "render/output/properties/output.html#bpy-types-ffmpegsettings-max-b-frames"),
("bpy.types.fileselectparams.use_filter*", "editors/file_browser.html#bpy-types-fileselectparams-use-filter"),
("bpy.types.fluiddomainsettings.gravity*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-gravity"),
("bpy.types.fluidflowsettings.flow_type*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-flow-type"),
@@ -1001,6 +1036,7 @@ url_manual_mapping = (
("bpy.ops.anim.channels_fcurves_enable*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-fcurves-enable"),
("bpy.ops.anim.channels_setting_toggle*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-setting-toggle"),
("bpy.ops.clip.set_viewport_background*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-set-viewport-background"),
+ ("bpy.ops.geometry.color_attribute_add*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-add"),
("bpy.ops.gpencil.interpolate_sequence*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-interpolate-sequence"),
("bpy.ops.mesh.normals_make_consistent*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-normals-make-consistent"),
("bpy.ops.mesh.offset_edge_loops_slide*", "modeling/meshes/editing/edge/offset_edge_slide.html#bpy-ops-mesh-offset-edge-loops-slide"),
@@ -1031,6 +1067,7 @@ url_manual_mapping = (
("bpy.types.compositornodecolorbalance*", "compositing/types/color/color_balance.html#bpy-types-compositornodecolorbalance"),
("bpy.types.compositornodekeyingscreen*", "compositing/types/matte/keying_screen.html#bpy-types-compositornodekeyingscreen"),
("bpy.types.dynamicpaintcanvassettings*", "physics/dynamic_paint/canvas.html#bpy-types-dynamicpaintcanvassettings"),
+ ("bpy.types.ffmpegsettings.audio_codec*", "render/output/properties/output.html#bpy-types-ffmpegsettings-audio-codec"),
("bpy.types.fileselectparams.directory*", "editors/file_browser.html#bpy-types-fileselectparams-directory"),
("bpy.types.fluidflowsettings.use_flow*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-flow"),
("bpy.types.fmodifierfunctiongenerator*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierfunctiongenerator"),
@@ -1038,6 +1075,7 @@ url_manual_mapping = (
("bpy.types.geometrynodedeletegeometry*", "modeling/geometry_nodes/geometry/delete_geometry.html#bpy-types-geometrynodedeletegeometry"),
("bpy.types.geometrynodeinputcurvetilt*", "modeling/geometry_nodes/curve/curve_tilt.html#bpy-types-geometrynodeinputcurvetilt"),
("bpy.types.geometrynodeinputscenetime*", "modeling/geometry_nodes/input/scene_time.html#bpy-types-geometrynodeinputscenetime"),
+ ("bpy.types.geometrynodenamedattribute*", "modeling/geometry_nodes/input/named_attribute.html#bpy-types-geometrynodenamedattribute"),
("bpy.types.geometrynodepointstovolume*", "modeling/geometry_nodes/point/points_to_volume.html#bpy-types-geometrynodepointstovolume"),
("bpy.types.geometrynodescaleinstances*", "modeling/geometry_nodes/instances/scale_instances.html#bpy-types-geometrynodescaleinstances"),
("bpy.types.geometrynodesetcurveradius*", "modeling/geometry_nodes/curve/set_curve_radius.html#bpy-types-geometrynodesetcurveradius"),
@@ -1067,6 +1105,7 @@ url_manual_mapping = (
("bpy.types.spaceuveditor.show_stretch*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-stretch"),
("bpy.types.toolsettings.keyframe_type*", "editors/timeline.html#bpy-types-toolsettings-keyframe-type"),
("bpy.types.toolsettings.snap_elements*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-snap-elements"),
+ ("bpy.types.toolsettings.use_snap_node*", "interface/controls/nodes/arranging.html#bpy-types-toolsettings-use-snap-node"),
("bpy.types.toolsettings.use_snap_self*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-self"),
("bpy.types.viewlayer.active_aov_index*", "render/layers/passes.html#bpy-types-viewlayer-active-aov-index"),
("bpy.ops.anim.channels_enable_toggle*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-enable-toggle"),
@@ -1086,6 +1125,7 @@ url_manual_mapping = (
("bpy.ops.object.material_slot_assign*", "render/materials/assignment.html#bpy-ops-object-material-slot-assign"),
("bpy.ops.object.material_slot_select*", "render/materials/assignment.html#bpy-ops-object-material-slot-select"),
("bpy.ops.object.multires_unsubdivide*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-unsubdivide"),
+ ("bpy.ops.object.parent_inverse_apply*", "scene_layout/object/editing/apply.html#bpy-ops-object-parent-inverse-apply"),
("bpy.ops.object.paths_update_visible*", "animation/motion_paths.html#bpy-ops-object-paths-update-visible"),
("bpy.ops.object.transforms_to_deltas*", "scene_layout/object/editing/apply.html#bpy-ops-object-transforms-to-deltas"),
("bpy.ops.outliner.collection_disable*", "editors/outliner/editing.html#bpy-ops-outliner-collection-disable"),
@@ -1116,6 +1156,8 @@ url_manual_mapping = (
("bpy.types.cyclesrendersettings.seed*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-seed"),
("bpy.types.dynamicpaintbrushsettings*", "physics/dynamic_paint/brush.html#bpy-types-dynamicpaintbrushsettings"),
("bpy.types.editbone.use_scale_easing*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-use-scale-easing"),
+ ("bpy.types.ffmpegsettings.buffersize*", "render/output/properties/output.html#bpy-types-ffmpegsettings-buffersize"),
+ ("bpy.types.ffmpegsettings.packetsize*", "render/output/properties/output.html#bpy-types-ffmpegsettings-packetsize"),
("bpy.types.fileselectparams.filename*", "editors/file_browser.html#bpy-types-fileselectparams-filename"),
("bpy.types.fluiddomainsettings.alpha*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-alpha"),
("bpy.types.fluidflowsettings.density*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-density"),
@@ -1135,6 +1177,7 @@ url_manual_mapping = (
("bpy.types.greasepencil.pixel_factor*", "grease_pencil/properties/strokes.html#bpy-types-greasepencil-pixel-factor"),
("bpy.types.keyframe.handle_left_type*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-handle-left-type"),
("bpy.types.light.use_custom_distance*", "render/eevee/lighting.html#bpy-types-light-use-custom-distance"),
+ ("bpy.types.material.refraction_depth*", "render/eevee/materials/settings.html#bpy-types-material-refraction-depth"),
("bpy.types.materialgpencilstyle.flip*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-flip"),
("bpy.types.materialgpencilstyle.mode*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-mode"),
("bpy.types.meshsequencecachemodifier*", "modeling/modifiers/modify/mesh_sequence_cache.html#bpy-types-meshsequencecachemodifier"),
@@ -1197,6 +1240,7 @@ url_manual_mapping = (
("bpy.ops.sequencer.export_subtitles*", "editors/video_sequencer/preview/header.html#bpy-ops-sequencer-export-subtitles"),
("bpy.ops.transform.edge_bevelweight*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-transform-edge-bevelweight"),
("bpy.ops.wm.previews_batch_generate*", "files/blend/previews.html#bpy-ops-wm-previews-batch-generate"),
+ ("bpy.types.animvizmotionpaths.range*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-range"),
("bpy.types.assetmetadata.active_tag*", "editors/asset_browser.html#bpy-types-assetmetadata-active-tag"),
("bpy.types.bakesettings.cage_object*", "render/cycles/baking.html#bpy-types-bakesettings-cage-object"),
("bpy.types.bakesettings.margin_type*", "render/cycles/baking.html#bpy-types-bakesettings-margin-type"),
@@ -1243,6 +1287,7 @@ url_manual_mapping = (
("bpy.types.imagepaint.interpolation*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-types-imagepaint-interpolation"),
("bpy.types.linestyle*modifier_noise*", "render/freestyle/view_layer/line_style/modifiers/color/noise.html#bpy-types-linestyle-modifier-noise"),
("bpy.types.maintainvolumeconstraint*", "animation/constraints/transform/maintain_volume.html#bpy-types-maintainvolumeconstraint"),
+ ("bpy.types.material.alpha_threshold*", "render/eevee/materials/settings.html#bpy-types-material-alpha-threshold"),
("bpy.types.mesh.use_mirror_topology*", "modeling/meshes/tools/tool_settings.html#bpy-types-mesh-use-mirror-topology"),
("bpy.types.movieclip.display_aspect*", "editors/clip/display/clip_display.html#bpy-types-movieclip-display-aspect"),
("bpy.types.nodesocketinterface.name*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-name"),
@@ -1251,6 +1296,7 @@ url_manual_mapping = (
("bpy.types.rendersettings.hair_type*", "render/eevee/render_settings/hair.html#bpy-types-rendersettings-hair-type"),
("bpy.types.rendersettings.tile_size*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-tile-size"),
("bpy.types.sequencertimelineoverlay*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay"),
+ ("bpy.types.sequencetransform.filter*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencetransform-filter"),
("bpy.types.sequencetransform.offset*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencetransform-offset"),
("bpy.types.shadernodebrightcontrast*", "render/shader_nodes/color/bright_contrast.html#bpy-types-shadernodebrightcontrast"),
("bpy.types.shadernodebsdfprincipled*", "render/shader_nodes/shader/principled.html#bpy-types-shadernodebsdfprincipled"),
@@ -1368,6 +1414,7 @@ url_manual_mapping = (
("bpy.types.rigidbodyobject.enabled*", "physics/rigid_body/properties/settings.html#bpy-types-rigidbodyobject-enabled"),
("bpy.types.sceneeevee.use_overscan*", "render/eevee/render_settings/film.html#bpy-types-sceneeevee-use-overscan"),
("bpy.types.sequencerpreviewoverlay*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay"),
+ ("bpy.types.sequencetimelinechannel*", "editors/video_sequencer/sequencer/channels.html#bpy-types-sequencetimelinechannel"),
("bpy.types.sequencetransform.scale*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencetransform-scale"),
("bpy.types.shadernodeeeveespecular*", "render/shader_nodes/shader/specular_bsdf.html#bpy-types-shadernodeeeveespecular"),
("bpy.types.shadernodehuesaturation*", "render/shader_nodes/color/hue_saturation.html#bpy-types-shadernodehuesaturation"),
@@ -1453,6 +1500,10 @@ url_manual_mapping = (
("bpy.types.editbone.bbone_rollout*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-rollout"),
("bpy.types.editbone.bbone_scalein*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-scalein"),
("bpy.types.editbone.inherit_scale*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-inherit-scale"),
+ ("bpy.types.ffmpegsettings.gopsize*", "render/output/properties/output.html#bpy-types-ffmpegsettings-gopsize"),
+ ("bpy.types.ffmpegsettings.maxrate*", "render/output/properties/output.html#bpy-types-ffmpegsettings-maxrate"),
+ ("bpy.types.ffmpegsettings.minrate*", "render/output/properties/output.html#bpy-types-ffmpegsettings-minrate"),
+ ("bpy.types.ffmpegsettings.muxrate*", "render/output/properties/output.html#bpy-types-ffmpegsettings-muxrate"),
("bpy.types.freestylelinestyle.gap*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-gap"),
("bpy.types.freestylesettings.mode*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-mode"),
("bpy.types.functionnodefloattoint*", "modeling/geometry_nodes/utilities/float_to_integer.html#bpy-types-functionnodefloattoint"),
@@ -1472,7 +1523,9 @@ url_manual_mapping = (
("bpy.types.keyframe.interpolation*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-interpolation"),
("bpy.types.latticegpencilmodifier*", "grease_pencil/modifiers/deform/lattice.html#bpy-types-latticegpencilmodifier"),
("bpy.types.lineartgpencilmodifier*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier"),
+ ("bpy.types.material.diffuse_color*", "render/materials/settings.html#bpy-types-material-diffuse-color"),
("bpy.types.material.line_priority*", "render/freestyle/material.html#bpy-types-material-line-priority"),
+ ("bpy.types.material.shadow_method*", "render/eevee/materials/settings.html#bpy-types-material-shadow-method"),
("bpy.types.mesh.auto_smooth_angle*", "modeling/meshes/structure.html#bpy-types-mesh-auto-smooth-angle"),
("bpy.types.modifier.show_viewport*", "modeling/modifiers/introduction.html#bpy-types-modifier-show-viewport"),
("bpy.types.motionpath.frame_start*", "animation/motion_paths.html#bpy-types-motionpath-frame-start"),
@@ -1516,6 +1569,7 @@ url_manual_mapping = (
("bpy.ops.graph.snap_cursor_value*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-snap-cursor-value"),
("bpy.ops.image.save_all_modified*", "editors/image/editing.html#bpy-ops-image-save-all-modified"),
("bpy.ops.marker.make_links_scene*", "animation/markers.html#bpy-ops-marker-make-links-scene"),
+ ("bpy.ops.marker.select_leftright*", "animation/markers.html#bpy-ops-marker-select-leftright"),
("bpy.ops.mesh.extrude_edges_move*", "modeling/meshes/editing/edge/extrude_edges.html#bpy-ops-mesh-extrude-edges-move"),
("bpy.ops.mesh.extrude_faces_move*", "modeling/meshes/editing/face/extrude_individual_faces.html#bpy-ops-mesh-extrude-faces-move"),
("bpy.ops.mesh.faces_shade_smooth*", "modeling/meshes/editing/face/shading.html#bpy-ops-mesh-faces-shade-smooth"),
@@ -1551,6 +1605,7 @@ url_manual_mapping = (
("bpy.ops.transform.rotate_normal*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-transform-rotate-normal"),
("bpy.ops.transform.shrink_fatten*", "modeling/meshes/editing/mesh/transform/shrink-fatten.html#bpy-ops-transform-shrink-fatten"),
("bpy.ops.transform.vertex_random*", "modeling/meshes/editing/mesh/transform/randomize.html#bpy-ops-transform-vertex-random"),
+ ("bpy.ops.ui.reset_default_button*", "interface/controls/buttons/menus.html#bpy-ops-ui-reset-default-button"),
("bpy.ops.uv.shortest_path_select*", "editors/uv/selecting.html#bpy-ops-uv-shortest-path-select"),
("bpy.ops.wm.operator_cheat_sheet*", "advanced/operators.html#bpy-ops-wm-operator-cheat-sheet"),
("bpy.ops.wm.previews_batch_clear*", "files/blend/previews.html#bpy-ops-wm-previews-batch-clear"),
@@ -1583,6 +1638,7 @@ url_manual_mapping = (
("bpy.types.editbone.bbone_easein*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-easein"),
("bpy.types.editbone.bbone_rollin*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-rollin"),
("bpy.types.fcurve.auto_smoothing*", "editors/graph_editor/fcurves/properties.html#bpy-types-fcurve-auto-smoothing"),
+ ("bpy.types.ffmpegsettings.format*", "render/output/properties/output.html#bpy-types-ffmpegsettings-format"),
("bpy.types.fluideffectorsettings*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings"),
("bpy.types.followtrackconstraint*", "animation/constraints/motion_tracking/follow_track.html#bpy-types-followtrackconstraint"),
("bpy.types.functionnodeinputbool*", "modeling/geometry_nodes/input/boolean.html#bpy-types-functionnodeinputbool"),
@@ -1639,6 +1695,7 @@ url_manual_mapping = (
("bpy.ops.geometry.attribute_add*", "modeling/geometry_nodes/attributes_reference.html#bpy-ops-geometry-attribute-add"),
("bpy.ops.gpencil.duplicate_move*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-duplicate-move"),
("bpy.ops.gpencil.stroke_arrange*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-arrange"),
+ ("bpy.ops.graph.blend_to_default*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-blend-to-default"),
("bpy.ops.graph.equalize_handles*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-equalize-handles"),
("bpy.ops.mesh.bridge-edge-loops*", "modeling/meshes/editing/edge/bridge_edge_loops.html#bpy-ops-mesh-bridge-edge-loops"),
("bpy.ops.mesh.intersect_boolean*", "modeling/meshes/editing/face/intersect_boolean.html#bpy-ops-mesh-intersect-boolean"),
@@ -1683,7 +1740,7 @@ url_manual_mapping = (
("bpy.types.datatransfermodifier*", "modeling/modifiers/modify/data_transfer.html#bpy-types-datatransfermodifier"),
("bpy.types.dynamicpaintmodifier*", "physics/dynamic_paint/index.html#bpy-types-dynamicpaintmodifier"),
("bpy.types.editbone.use_connect*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-use-connect"),
- ("bpy.types.ffmpegsettings.audio*", "render/output/properties/output.html#bpy-types-ffmpegsettings-audio"),
+ ("bpy.types.ffmpegsettings.codec*", "render/output/properties/output.html#bpy-types-ffmpegsettings-codec"),
("bpy.types.followpathconstraint*", "animation/constraints/relationship/follow_path.html#bpy-types-followpathconstraint"),
("bpy.types.functionnodeinputint*", "modeling/geometry_nodes/input/integer.html#bpy-types-functionnodeinputint"),
("bpy.types.gaussianblursequence*", "video_editing/edit/montage/strips/effects/blur.html#bpy-types-gaussianblursequence"),
@@ -1823,6 +1880,7 @@ url_manual_mapping = (
("bpy.types.imageformatsettings*", "files/media/image_formats.html#bpy-types-imageformatsettings"),
("bpy.types.kinematicconstraint*", "animation/constraints/tracking/ik_solver.html#bpy-types-kinematicconstraint"),
("bpy.types.material.line_color*", "render/freestyle/material.html#bpy-types-material-line-color"),
+ ("bpy.types.material.pass_index*", "render/materials/settings.html#bpy-types-material-pass-index"),
("bpy.types.mesh.use_paint_mask*", "sculpt_paint/brush/introduction.html#bpy-types-mesh-use-paint-mask"),
("bpy.types.movietrackingcamera*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera"),
("bpy.types.object.display_type*", "scene_layout/object/properties/display.html#bpy-types-object-display-type"),
@@ -1916,6 +1974,7 @@ url_manual_mapping = (
("bpy.ops.transform.edge_slide*", "modeling/meshes/editing/edge/edge_slide.html#bpy-ops-transform-edge-slide"),
("bpy.ops.transform.vert_slide*", "modeling/meshes/editing/vertex/slide_vertices.html#bpy-ops-transform-vert-slide"),
("bpy.ops.uv.project_from_view*", "modeling/meshes/editing/uv.html#bpy-ops-uv-project-from-view"),
+ ("bpy.ops.view3d.view_selected*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-view-selected"),
("bpy.ops.wm.memory_statistics*", "advanced/operators.html#bpy-ops-wm-memory-statistics"),
("bpy.ops.wm.recover_auto_save*", "files/blend/open_save.html#bpy-ops-wm-recover-auto-save"),
("bpy.types.adjustmentsequence*", "video_editing/edit/montage/strips/adjustment.html#bpy-types-adjustmentsequence"),
@@ -1924,7 +1983,7 @@ url_manual_mapping = (
("bpy.types.armature.show_axes*", "animation/armatures/properties/display.html#bpy-types-armature-show-axes"),
("bpy.types.armatureconstraint*", "animation/constraints/relationship/armature.html#bpy-types-armatureconstraint"),
("bpy.types.compositornodeblur*", "compositing/types/filter/blur_node.html#bpy-types-compositornodeblur"),
- ("bpy.types.compositornodecomb*", "editors/texture_node/types/color/combine_separate.html#bpy-types-compositornodecomb"),
+ ("bpy.types.compositornodecomb*", "compositing/types/converter/combine_separate.html#bpy-types-compositornodecomb"),
("bpy.types.compositornodecrop*", "compositing/types/distort/crop.html#bpy-types-compositornodecrop"),
("bpy.types.compositornodeflip*", "compositing/types/distort/flip.html#bpy-types-compositornodeflip"),
("bpy.types.compositornodemask*", "compositing/types/input/mask.html#bpy-types-compositornodemask"),
@@ -1949,6 +2008,7 @@ url_manual_mapping = (
("bpy.types.huecorrectmodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-huecorrectmodifier"),
("bpy.types.image.is_multiview*", "editors/image/image_settings.html#bpy-types-image-is-multiview"),
("bpy.types.imagepaint.stencil*", "sculpt_paint/texture_paint/tool_settings/mask.html#bpy-types-imagepaint-stencil"),
+ ("bpy.types.material.roughness*", "render/materials/settings.html#bpy-types-material-roughness"),
("bpy.types.meshdeformmodifier*", "modeling/modifiers/deform/mesh_deform.html#bpy-types-meshdeformmodifier"),
("bpy.types.movietrackingtrack*", "movie_clip/tracking/clip/sidebar/track/index.html#bpy-types-movietrackingtrack"),
("bpy.types.nodeoutputfileslot*", "compositing/types/output/file.html#bpy-types-nodeoutputfileslot"),
@@ -2056,7 +2116,7 @@ url_manual_mapping = (
("bpy.types.collisionmodifier*", "physics/collision.html#bpy-types-collisionmodifier"),
("bpy.types.collisionsettings*", "physics/collision.html#bpy-types-collisionsettings"),
("bpy.types.compositornodergb*", "compositing/types/input/rgb.html#bpy-types-compositornodergb"),
- ("bpy.types.compositornodesep*", "editors/texture_node/types/color/combine_separate.html#bpy-types-compositornodesep"),
+ ("bpy.types.compositornodesep*", "compositing/types/converter/combine_separate.html#bpy-types-compositornodesep"),
("bpy.types.curve.bevel_depth*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-depth"),
("bpy.types.curve.use_stretch*", "modeling/curves/properties/shape.html#bpy-types-curve-use-stretch"),
("bpy.types.edgesplitmodifier*", "modeling/modifiers/generate/edge_split.html#bpy-types-edgesplitmodifier"),
@@ -2069,6 +2129,7 @@ url_manual_mapping = (
("bpy.types.gpencillayer.hide*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-hide"),
("bpy.types.gpencillayer.lock*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-lock"),
("bpy.types.imagepaint.dither*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-dither"),
+ ("bpy.types.material.metallic*", "render/materials/settings.html#bpy-types-material-metallic"),
("bpy.types.materialslot.link*", "render/materials/assignment.html#bpy-types-materialslot-link"),
("bpy.types.mesh.texture_mesh*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-types-mesh-texture-mesh"),
("bpy.types.mesh.use_mirror_x*", "modeling/meshes/tools/tool_settings.html#bpy-types-mesh-use-mirror-x"),
@@ -2078,6 +2139,7 @@ url_manual_mapping = (
("bpy.types.movieclipsequence*", "video_editing/edit/montage/strips/clip.html#bpy-types-movieclipsequence"),
("bpy.types.object.dimensions*", "scene_layout/object/properties/transforms.html#bpy-types-object-dimensions"),
("bpy.types.object.is_holdout*", "scene_layout/object/properties/visibility.html#bpy-types-object-is-holdout"),
+ ("bpy.types.object.lightgroup*", "render/cycles/object_settings/object_data.html#bpy-types-object-lightgroup"),
("bpy.types.object.pass_index*", "scene_layout/object/properties/relations.html#bpy-types-object-pass-index"),
("bpy.types.object.track_axis*", "scene_layout/object/properties/relations.html#bpy-types-object-track-axis"),
("bpy.types.pose.use_mirror_x*", "animation/armatures/posing/tool_settings.html#bpy-types-pose-use-mirror-x"),
@@ -2151,12 +2213,13 @@ url_manual_mapping = (
("bpy.ops.sculpt.mask_filter*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-mask-filter"),
("bpy.ops.transform.tosphere*", "modeling/meshes/editing/mesh/transform/to_sphere.html#bpy-ops-transform-tosphere"),
("bpy.ops.view3d.clip_border*", "editors/3dview/navigate/regions.html#bpy-ops-view3d-clip-border"),
+ ("bpy.ops.view3d.zoom_border*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-zoom-border"),
("bpy.ops.wm.previews_ensure*", "files/blend/previews.html#bpy-ops-wm-previews-ensure"),
("bpy.ops.wm.properties_edit*", "files/data_blocks.html#bpy-ops-wm-properties-edit"),
("bpy.ops.wm.search_operator*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search-operator"),
("bpy.types.actionconstraint*", "animation/constraints/relationship/action.html#bpy-types-actionconstraint"),
("bpy.types.addonpreferences*", "editors/preferences/addons.html#bpy-types-addonpreferences"),
- ("bpy.types.arealight.spread*", "render/lights/light_object.html#bpy-types-arealight-spread"),
+ ("bpy.types.arealight.spread*", "render/cycles/light_settings.html#bpy-types-arealight-spread"),
("bpy.types.armaturemodifier*", "modeling/modifiers/deform/armature.html#bpy-types-armaturemodifier"),
("bpy.types.bone.head_radius*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-head-radius"),
("bpy.types.bone.tail_radius*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-tail-radius"),
@@ -2220,7 +2283,7 @@ url_manual_mapping = (
("bpy.types.texturenodegroup*", "editors/texture_node/types/groups.html#bpy-types-texturenodegroup"),
("bpy.types.texturenodeimage*", "editors/texture_node/types/input/image.html#bpy-types-texturenodeimage"),
("bpy.types.texturenodescale*", "editors/texture_node/types/distort/scale.html#bpy-types-texturenodescale"),
- ("bpy.types.viewlayer.use_ao*", "render/layers/introduction.html#bpy-types-viewlayer-use-ao"),
+ ("bpy.types.world.lightgroup*", "render/cycles/world_settings.html#bpy-types-world-lightgroup"),
("bpy.ops.armature.dissolve*", "animation/armatures/bones/editing/delete.html#bpy-ops-armature-dissolve"),
("bpy.ops.armature.separate*", "animation/armatures/bones/editing/separate_bones.html#bpy-ops-armature-separate"),
("bpy.ops.clip.clean_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-clean-tracks"),
@@ -2237,6 +2300,7 @@ url_manual_mapping = (
("bpy.ops.gpencil.reproject*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-reproject"),
("bpy.ops.graph.easing_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-easing-type"),
("bpy.ops.graph.handle_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-handle-type"),
+ ("bpy.ops.marker.select_all*", "animation/markers.html#bpy-ops-marker-select-all"),
("bpy.ops.mask.parent_clear*", "movie_clip/masking/editing.html#bpy-ops-mask-parent-clear"),
("bpy.ops.mask.select_lasso*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-lasso"),
("bpy.ops.mesh.bevel.vertex*", "modeling/meshes/editing/vertex/bevel_vertices.html#bpy-ops-mesh-bevel-vertex"),
@@ -2296,6 +2360,7 @@ url_manual_mapping = (
("bpy.types.preferencesview*", "editors/preferences/interface.html#bpy-types-preferencesview"),
("bpy.types.rigidbodyobject*", "physics/rigid_body/index.html#bpy-types-rigidbodyobject"),
("bpy.types.scene.frame_end*", "render/output/properties/frame_range.html#bpy-types-scene-frame-end"),
+ ("bpy.types.scene.sync_mode*", "editors/timeline.html#bpy-types-scene-sync-mode"),
("bpy.types.sceneeevee.gtao*", "render/eevee/render_settings/ambient_occlusion.html#bpy-types-sceneeevee-gtao"),
("bpy.types.screen.use_play*", "editors/timeline.html#bpy-types-screen-use-play"),
("bpy.types.shadernodebevel*", "render/shader_nodes/input/bevel.html#bpy-types-shadernodebevel"),
@@ -2351,6 +2416,7 @@ url_manual_mapping = (
("bpy.ops.uv.snap_selected*", "modeling/meshes/uv/editing.html#bpy-ops-uv-snap-selected"),
("bpy.ops.view3d.localview*", "editors/3dview/navigate/local_view.html#bpy-ops-view3d-localview"),
("bpy.ops.view3d.view_axis*", "editors/3dview/navigate/viewpoint.html#bpy-ops-view3d-view-axis"),
+ ("bpy.ops.view3d.view_roll*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-view-roll"),
("bpy.ops.wm.open_mainfile*", "files/blend/open_save.html#bpy-ops-wm-open-mainfile"),
("bpy.ops.wm.owner_disable*", "interface/window_system/workspaces.html#bpy-ops-wm-owner-disable"),
("bpy.ops.wm.save_mainfile*", "files/blend/open_save.html#bpy-ops-wm-save-mainfile"),
@@ -2430,6 +2496,7 @@ url_manual_mapping = (
("bpy.ops.uv.cube_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-cube-project"),
("bpy.ops.uv.pack_islands*", "modeling/meshes/uv/editing.html#bpy-ops-uv-pack-islands"),
("bpy.ops.uv.select_split*", "modeling/meshes/uv/editing.html#bpy-ops-uv-select-split"),
+ ("bpy.ops.view3d.view_all*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-view-all"),
("bpy.ops.view3d.view_pan*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-view-pan"),
("bpy.ops.wm.app_template*", "advanced/app_templates.html#bpy-ops-wm-app-template"),
("bpy.ops.wm.batch_rename*", "files/blend/rename.html#bpy-ops-wm-batch-rename"),
@@ -2523,6 +2590,7 @@ url_manual_mapping = (
("bpy.ops.sequencer.swap*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-swap"),
("bpy.ops.transform.bend*", "modeling/meshes/editing/mesh/transform/bend.html#bpy-ops-transform-bend"),
("bpy.ops.transform.tilt*", "modeling/curves/editing/control_points.html#bpy-ops-transform-tilt"),
+ ("bpy.ops.uv.select_mode*", "editors/uv/selecting.html#bpy-ops-uv-select-mode"),
("bpy.ops.uv.snap_cursor*", "modeling/meshes/uv/editing.html#bpy-ops-uv-snap-cursor"),
("bpy.ops.wm.search_menu*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search-menu"),
("bpy.types.bakesettings*", "render/cycles/baking.html#bpy-types-bakesettings"),
@@ -2575,7 +2643,6 @@ url_manual_mapping = (
("bpy.ops.image.replace*", "editors/image/editing.html#bpy-ops-image-replace"),
("bpy.ops.image.save_as*", "editors/image/editing.html#bpy-ops-image-save-as"),
("bpy.ops.marker.delete*", "animation/markers.html#bpy-ops-marker-delete"),
- ("bpy.ops.marker.rename*", "animation/markers.html#bpy-ops-marker-rename"),
("bpy.ops.marker.select*", "animation/markers.html#bpy-ops-marker-select"),
("bpy.ops.material.copy*", "render/materials/assignment.html#bpy-ops-material-copy"),
("bpy.ops.mesh.decimate*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-decimate"),
@@ -2594,6 +2661,7 @@ url_manual_mapping = (
("bpy.ops.view3d.select*", "editors/3dview/selecting.html#bpy-ops-view3d-select"),
("bpy.ops.wm.debug_menu*", "advanced/operators.html#bpy-ops-wm-debug-menu"),
("bpy.ops.wm.obj_export*", "files/import_export/obj.html#bpy-ops-wm-obj-export"),
+ ("bpy.ops.wm.obj_import*", "files/import_export/obj.html#bpy-ops-wm-obj-import"),
("bpy.ops.wm.properties*", "files/data_blocks.html#bpy-ops-wm-properties"),
("bpy.ops.wm.usd_export*", "files/import_export/usd.html#bpy-ops-wm-usd-export"),
("bpy.types.addsequence*", "video_editing/edit/montage/strips/effects/add.html#bpy-types-addsequence"),
@@ -2642,6 +2710,7 @@ url_manual_mapping = (
("bpy.ops.object.quick*", "physics/introduction.html#bpy-ops-object-quick"),
("bpy.ops.text.replace*", "editors/text_editor.html#bpy-ops-text-replace"),
("bpy.ops.uv.mark_seam*", "modeling/meshes/uv/unwrapping/seams.html#bpy-ops-uv-mark-seam"),
+ ("bpy.ops.view3d.dolly*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-dolly"),
("bpy.ops.view3d.ruler*", "editors/3dview/toolbar/measure.html#bpy-ops-view3d-ruler"),
("bpy.types.areaspaces*", "interface/window_system/areas.html#bpy-types-areaspaces"),
("bpy.types.bonegroups*", "animation/armatures/properties/bone_groups.html#bpy-types-bonegroups"),
@@ -2738,6 +2807,7 @@ url_manual_mapping = (
("bpy.types.facemaps*", "modeling/meshes/properties/object_data.html#bpy-types-facemaps"),
("bpy.types.keyframe*", "animation/keyframes/index.html#bpy-types-keyframe"),
("bpy.types.linesets*", "render/freestyle/view_layer/line_set.html#bpy-types-linesets"),
+ ("bpy.types.material*", "render/materials/index.html#bpy-types-material"),
("bpy.types.metaball*", "modeling/metas/index.html#bpy-types-metaball"),
("bpy.types.modifier*", "modeling/modifiers/index.html#bpy-types-modifier"),
("bpy.types.nlastrip*", "editors/nla/strips.html#bpy-types-nlastrip"),
@@ -2751,6 +2821,7 @@ url_manual_mapping = (
("bpy.types.spacenla*", "editors/nla/index.html#bpy-types-spacenla"),
("bpy.types.sunlight*", "render/lights/light_object.html#bpy-types-sunlight"),
("bpy.ops.clip.open*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-open"),
+ ("bpy.ops.curve.pen*", "modeling/curves/tools/pen.html#bpy-ops-curve-pen"),
("bpy.ops.file.next*", "editors/file_browser.html#bpy-ops-file-next"),
("bpy.ops.image.new*", "editors/image/editing.html#bpy-ops-image-new"),
("bpy.ops.mesh.fill*", "modeling/meshes/editing/face/fill.html#bpy-ops-mesh-fill"),
@@ -2776,7 +2847,7 @@ url_manual_mapping = (
("bpy.ops.armature*", "animation/armatures/index.html#bpy-ops-armature"),
("bpy.ops.geometry*", "modeling/index.html#bpy-ops-geometry"),
("bpy.ops.material*", "render/materials/index.html#bpy-ops-material"),
- ("bpy.ops.nla.bake*", "animation/actions.html#bpy-ops-nla-bake"),
+ ("bpy.ops.nla.bake*", "editors/nla/editing.html#bpy-ops-nla-bake"),
("bpy.ops.nla.snap*", "editors/nla/editing.html#bpy-ops-nla-snap"),
("bpy.ops.nla.swap*", "editors/nla/editing.html#bpy-ops-nla-swap"),
("bpy.ops.outliner*", "editors/outliner/index.html#bpy-ops-outliner"),
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 7d0929ef28f..1239f49473c 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -1265,6 +1265,7 @@ def km_uv_editor(params):
{"properties": [("deselect", True)]}),
("uv.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
("uv.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
+ ("uv.select_similar", {"type": 'G', "value": 'PRESS', "shift": True}, None),
*_template_items_select_actions(params, "uv.select_all"),
*_template_items_hide_reveal_actions("uv.hide", "uv.reveal"),
("uv.select_pinned", {"type": 'P', "value": 'PRESS', "shift": True}, None),
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 0eaada7249b..50fc6bad720 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -1352,7 +1352,7 @@ class WM_OT_properties_edit(Operator):
items=rna_custom_property_type_items,
)
is_overridable_library: BoolProperty(
- name="Is Library Overridable",
+ name="Library Overridable",
description="Allow the property to be overridden when the data-block is linked",
default=False,
)
@@ -1363,7 +1363,7 @@ class WM_OT_properties_edit(Operator):
# Shared for integer and string properties.
use_soft_limits: BoolProperty(
- name="Use Soft Limits",
+ name="Soft Limits",
description=(
"Limits the Property Value slider to a range, "
"values outside the range must be inputted numerically"
diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
index 8e5050be07e..8c43186313f 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -234,6 +234,11 @@ class GPENCIL_MT_move_to_layer(Menu):
layout = self.layout
gpd = context.gpencil_data
if gpd:
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.operator("gpencil.move_to_layer", text="New Layer", icon='ADD').layer = -1
+
+ layout.separator()
+
gpl_active = context.active_gpencil_layer
tot_layers = len(gpd.layers)
i = tot_layers - 1
@@ -246,11 +251,6 @@ class GPENCIL_MT_move_to_layer(Menu):
layout.operator("gpencil.move_to_layer", text=gpl.info, icon=icon, translate=False).layer = i
i -= 1
- layout.separator()
-
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("gpencil.move_to_layer", text="New Layer", icon='ADD').layer = -1
-
class GPENCIL_MT_layer_active(Menu):
bl_label = "Change Active Layer"
@@ -261,6 +261,10 @@ class GPENCIL_MT_layer_active(Menu):
gpd = context.gpencil_data
if gpd:
+ layout.operator("gpencil.layer_add", text="New Layer", icon='ADD')
+
+ layout.separator()
+
gpl_active = context.active_gpencil_layer
tot_layers = len(gpd.layers)
i = tot_layers - 1
@@ -273,10 +277,6 @@ class GPENCIL_MT_layer_active(Menu):
layout.operator("gpencil.layer_active", text=gpl.info, icon=icon).layer = i
i -= 1
- layout.separator()
-
- layout.operator("gpencil.layer_add", text="New Layer", icon='ADD')
-
class GPENCIL_MT_material_active(Menu):
bl_label = "Change Active Material"
diff --git a/release/scripts/startup/bl_ui/properties_mask_common.py b/release/scripts/startup/bl_ui/properties_mask_common.py
index 3131833454b..47a25db20b1 100644
--- a/release/scripts/startup/bl_ui/properties_mask_common.py
+++ b/release/scripts/startup/bl_ui/properties_mask_common.py
@@ -239,6 +239,9 @@ class MASK_PT_display:
sub = row.row()
sub.active = space_data.show_mask_overlay
sub.prop(space_data, "mask_overlay_mode", text="")
+ row = layout.row()
+ row.active = (space_data.mask_overlay_mode in ['COMBINED'] and space_data.show_mask_overlay)
+ row.prop(space_data, "blend_factor", text="Blending Factor")
class MASK_PT_transforms:
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 1f02e0f64d4..5d25d02d98e 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -159,6 +159,7 @@ class IMAGE_MT_select(Menu):
layout.operator("uv.select_pinned")
layout.menu("IMAGE_MT_select_linked")
+ layout.operator("uv.select_similar")
layout.separator()
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index fec3447ca6c..a8184b1d84b 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -714,6 +714,7 @@ geometry_node_categories = [
NodeItem("ShaderNodeVectorRotate"),
]),
GeometryNodeCategory("GEO_VOLUME", "Volume", items=[
+ NodeItem("GeometryNodeVolumeCube"),
NodeItem("GeometryNodeVolumeToMesh"),
]),
GeometryNodeCategory("GEO_GROUP", "Group", items=node_group_items),
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index e5e2b1711b1..78c8612f7f5 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -14,6 +14,15 @@
extern "C" {
#endif
+/* Name of subfolder inside BLENDER_DATAFILES that contains font files. */
+#define BLF_DATAFILES_FONTS_DIR "fonts"
+
+/* File name of the default variable-width font. */
+#define BLF_DEFAULT_PROPORTIONAL_FONT "droidsans.ttf"
+
+/* File name of the default fixed-pitch font. */
+#define BLF_DEFAULT_MONOSPACED_FONT "bmonofont-i18n.ttf"
+
/* enable this only if needed (unused circa 2016) */
#define BLF_BLUR_ENABLE 0
@@ -37,12 +46,14 @@ void BLF_cache_flush_set_fn(void (*cache_flush_fn)(void));
*/
int BLF_load(const char *name) ATTR_NONNULL();
int BLF_load_mem(const char *name, const unsigned char *mem, int mem_size) ATTR_NONNULL();
+bool BLF_is_loaded(const char *name) ATTR_NONNULL();
int BLF_load_unique(const char *name) ATTR_NONNULL();
int BLF_load_mem_unique(const char *name, const unsigned char *mem, int mem_size) ATTR_NONNULL();
void BLF_unload(const char *name) ATTR_NONNULL();
void BLF_unload_id(int fontid);
+void BLF_unload_all(void);
char *BLF_display_name_from_file(const char *filepath);
@@ -312,6 +323,7 @@ int BLF_set_default(void);
int BLF_load_default(bool unique);
int BLF_load_mono_default(bool unique);
+void BLF_load_font_stack(void);
#ifdef DEBUG
void BLF_state_print(int fontid);
@@ -331,6 +343,9 @@ void BLF_state_print(int fontid);
#define BLF_HINTING_FULL (1 << 10)
#define BLF_BOLD (1 << 11)
#define BLF_ITALIC (1 << 12)
+#define BLF_MONOSPACED (1 << 13) /* Intended USE is monospaced, regardless of font type. */
+#define BLF_DEFAULT (1 << 14) /* A font within the default stack of fonts. */
+#define BLF_LAST_RESORT (1 << 15) /* Must only be used as last font in the stack. */
#define BLF_DRAW_STR_DUMMY_MAX 1024
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index a944ab332bd..a1fcc17ca3f 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -34,13 +34,6 @@
#include "blf_internal.h"
#include "blf_internal_types.h"
-/* Max number of font in memory.
- * Take care that now every font have a glyph cache per size/dpi,
- * so we don't need load the same font with different size, just
- * load one and call BLF_size.
- */
-#define BLF_MAX_FONT 16
-
#define BLF_RESULT_CHECK_INIT(r_info) \
if (r_info) { \
memset(r_info, 0, sizeof(*(r_info))); \
@@ -48,7 +41,7 @@
((void)0)
/* Font array. */
-static FontBLF *global_font[BLF_MAX_FONT] = {NULL};
+FontBLF *global_font[BLF_MAX_FONT] = {NULL};
/* XXX: should these be made into global_font_'s too? */
@@ -134,6 +127,11 @@ bool BLF_has_glyph(int fontid, unsigned int unicode)
return false;
}
+bool BLF_is_loaded(const char *name)
+{
+ return blf_search(name) >= 0;
+}
+
int BLF_load(const char *name)
{
/* check if we already load this font. */
@@ -255,6 +253,20 @@ void BLF_unload_id(int fontid)
}
}
+void BLF_unload_all(void)
+{
+ for (int i = 0; i < BLF_MAX_FONT; i++) {
+ FontBLF *font = global_font[i];
+ if (font) {
+ blf_font_free(font);
+ global_font[i] = NULL;
+ }
+ }
+ blf_mono_font = -1;
+ blf_mono_font_render = -1;
+ BLF_default_set(-1);
+}
+
void BLF_enable(int fontid, int option)
{
FontBLF *font = blf_get(fontid);
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index a170f27d247..26a72fcb95a 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -18,6 +18,7 @@
#include FT_FREETYPE_H
#include FT_GLYPH_H
+#include FT_TRUETYPE_TABLES_H /* For TT_OS2 */
#include "MEM_guardedalloc.h"
@@ -1288,6 +1289,25 @@ FontBLF *blf_font_new(const char *name, const char *filepath)
font->filepath = BLI_strdup(filepath);
blf_font_fill(font);
+ /* Save TrueType table with bits to quickly test most unicode block coverage. */
+ TT_OS2 *os2_table = (TT_OS2 *)FT_Get_Sfnt_Table(font->face, FT_SFNT_OS2);
+ if (os2_table) {
+ font->UnicodeRanges[0] = (uint)os2_table->ulUnicodeRange1;
+ font->UnicodeRanges[1] = (uint)os2_table->ulUnicodeRange2;
+ font->UnicodeRanges[2] = (uint)os2_table->ulUnicodeRange3;
+ font->UnicodeRanges[3] = (uint)os2_table->ulUnicodeRange4;
+ }
+
+ /* Detect "Last resort" fonts. They have everything. Usually except last 5 bits. */
+ if (font->UnicodeRanges[0] == 0xffffffffU && font->UnicodeRanges[1] == 0xffffffffU &&
+ font->UnicodeRanges[2] == 0xffffffffU && font->UnicodeRanges[3] >= 0x7FFFFFFU) {
+ font->flags |= BLF_LAST_RESORT;
+ }
+
+ if (FT_IS_FIXED_WIDTH(font->face)) {
+ font->flags |= BLF_MONOSPACED;
+ }
+
if (FT_HAS_KERNING(font->face)) {
/* Create kerning cache table and fill with value indicating "unset". */
font->kerning_cache = MEM_mallocN(sizeof(KerningCacheBLF), __func__);
diff --git a/source/blender/blenfont/intern/blf_font_default.c b/source/blender/blenfont/intern/blf_font_default.c
index 3a68423e64e..1bde25b5776 100644
--- a/source/blender/blenfont/intern/blf_font_default.c
+++ b/source/blender/blenfont/intern/blf_font_default.c
@@ -11,13 +11,14 @@
#include "BLF_api.h"
+#include "BLI_fileops.h"
#include "BLI_path_util.h"
#include "BKE_appdir.h"
static int blf_load_font_default(const char *filename, const bool unique)
{
- const char *dir = BKE_appdir_folder_id(BLENDER_DATAFILES, "fonts");
+ const char *dir = BKE_appdir_folder_id(BLENDER_DATAFILES, BLF_DATAFILES_FONTS_DIR);
if (dir == NULL) {
fprintf(stderr,
"%s: 'fonts' data path not found for '%s', will not be able to display text\n",
@@ -34,10 +35,46 @@ static int blf_load_font_default(const char *filename, const bool unique)
int BLF_load_default(const bool unique)
{
- return blf_load_font_default("droidsans.ttf", unique);
+ int font_id = blf_load_font_default(BLF_DEFAULT_PROPORTIONAL_FONT, unique);
+ BLF_enable(font_id, BLF_DEFAULT);
+ return font_id;
}
int BLF_load_mono_default(const bool unique)
{
- return blf_load_font_default("bmonofont-i18n.ttf", unique);
+ int font_id = blf_load_font_default(BLF_DEFAULT_MONOSPACED_FONT, unique);
+ BLF_enable(font_id, BLF_MONOSPACED | BLF_DEFAULT);
+ return font_id;
+}
+
+void BLF_load_font_stack()
+{
+ /* Load these if not already, might have been replaced by user custom. */
+ BLF_load_default(false);
+ BLF_load_mono_default(false);
+
+ const char *path = BKE_appdir_folder_id(BLENDER_DATAFILES, BLF_DATAFILES_FONTS_DIR SEP_STR);
+ if (path && BLI_exists(path)) {
+ struct direntry *dir;
+ uint num_files = BLI_filelist_dir_contents(path, &dir);
+ for (int f = 0; f < num_files; f++) {
+ if (!FILENAME_IS_CURRPAR(dir[f].relname) && !BLI_is_dir(dir[f].path)) {
+ if (!BLF_is_loaded(dir[f].path)) {
+ int font_id = BLF_load(dir[f].path);
+ if (font_id == -1) {
+ fprintf(stderr, "Unable to load font: %s\n", dir[f].path);
+ }
+ else {
+ BLF_enable(font_id, BLF_DEFAULT);
+ /* TODO: FontBLF will later load FT_Face on demand. When this is in
+ * place we can drop this face now since we have all needed data. */
+ }
+ }
+ }
+ }
+ BLI_filelist_free(dir, num_files);
+ }
+ else {
+ fprintf(stderr, "Fonts not found at %s\n", path);
+ }
}
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 2694b179a11..ed30cca4da2 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -39,6 +39,7 @@
#include "BLI_math_vector.h"
#include "BLI_strict_flags.h"
+#include "BLI_string_utf8.h"
/* -------------------------------------------------------------------- */
/** \name Internal Utilities
@@ -222,6 +223,335 @@ static GlyphBLF *blf_glyph_cache_add_glyph(
return g;
}
+/* This table can be used to find a coverage bit based on a charcode. later we can get default
+ * language and script from codepoint. */
+
+typedef struct eUnicodeBlock {
+ unsigned int first;
+ unsigned int last;
+ int coverage_bit; /* 0-122. -1 is N/A. */
+ /* Later we add primary script and language for Harfbuzz, data from
+ * https://en.wikipedia.org/wiki/Unicode_block */
+} eUnicodeBlock;
+
+static eUnicodeBlock unicode_blocks[] = {
+ /* Must be in ascending order by start of range. */
+ {0x0, 0x7F, 0}, /* Basic Latin. */
+ {0x80, 0xFF, 1}, /* Latin-1 Supplement. */
+ {0x100, 0x17F, 2}, /* Latin Extended-A. */
+ {0x180, 0x24F, 3}, /* Latin Extended-B. */
+ {0x250, 0x2AF, 4}, /* IPA Extensions. */
+ {0x2B0, 0x2FF, 5}, /* Spacing Modifier Letters. */
+ {0x300, 0x36F, 6}, /* Combining Diacritical Marks. */
+ {0x370, 0x3FF, 7}, /* Greek. */
+ {0x400, 0x52F, 9}, /* Cyrillic. */
+ {0x530, 0x58F, 10}, /* Armenian. */
+ {0x590, 0x5FF, 11}, /* Hebrew. */
+ {0x600, 0x6FF, 13}, /* Arabic. */
+ {0x700, 0x74F, 71}, /* Syriac. */
+ {0x750, 0x77F, 13}, /* Arabic Supplement. */
+ {0x780, 0x7BF, 72}, /* Thaana. */
+ {0x7C0, 0x7FF, 14}, /* NKo. */
+ {0x800, 0x83F, -1}, /* Samaritan. */
+ {0x840, 0x85F, -1}, /* Mandaic. */
+ {0x900, 0x97F, 15}, /* Devanagari. */
+ {0x980, 0x9FF, 16}, /* Bengali. */
+ {0xA00, 0xA7F, 17}, /* Gurmukhi. */
+ {0xA80, 0xAFF, 18}, /* Gujarati. */
+ {0xB00, 0xB7F, 19}, /* Oriya. */
+ {0xB80, 0xBFF, 20}, /* Tamil. */
+ {0xC00, 0xC7F, 21}, /* Telugu. */
+ {0xC80, 0xCFF, 22}, /* Kannada. */
+ {0xD00, 0xD7F, 23}, /* Malayalam. */
+ {0xD80, 0xDFF, 73}, /* Sinhala. */
+ {0xE00, 0xE7F, 24}, /* Thai. */
+ {0xE80, 0xEFF, 25}, /* Lao. */
+ {0xF00, 0xFFF, 70}, /* Tibetan. */
+ {0x1000, 0x109F, 74}, /* Myanmar. */
+ {0x10A0, 0x10FF, 26}, /* Georgian. */
+ {0x1100, 0x11FF, 28}, /* Hangul Jamo. */
+ {0x1200, 0x139F, 75}, /* Ethiopic. */
+ {0x13A0, 0x13FF, 76}, /* Cherokee. */
+ {0x1400, 0x167F, 77}, /* Canadian Aboriginal. */
+ {0x1680, 0x169F, 78}, /* Ogham. */
+ {0x16A0, 0x16FF, 79}, /* unic. */
+ {0x1700, 0x171F, 84}, /* Tagalog. */
+ {0x1720, 0x173F, 84}, /* Hanunoo. */
+ {0x1740, 0x175F, 84}, /* Buhid. */
+ {0x1760, 0x177F, 84}, /* Tagbanwa. */
+ {0x1780, 0x17FF, 80}, /* Khmer. */
+ {0x1800, 0x18AF, 81}, /* Mongolian. */
+ {0x1900, 0x194F, 93}, /* Limbu. */
+ {0x1950, 0x197F, 94}, /* Tai Le. */
+ {0x1980, 0x19DF, 95}, /* New Tai Lue". */
+ {0x19E0, 0x19FF, 80}, /* Khmer. */
+ {0x1A00, 0x1A1F, 96}, /* Buginese. */
+ {0x1A20, 0x1AAF, -1}, /* Tai Tham. */
+ {0x1B00, 0x1B7F, 27}, /* Balinese. */
+ {0x1B80, 0x1BBF, 112}, /* Sundanese. */
+ {0x1BC0, 0x1BFF, -1}, /* Batak. */
+ {0x1C00, 0x1C4F, 113}, /* Lepcha. */
+ {0x1C50, 0x1C7F, 114}, /* Ol Chiki. */
+ {0x1D00, 0x1DBF, 4}, /* IPA Extensions. */
+ {0x1DC0, 0x1DFF, 6}, /* Combining Diacritical Marks. */
+ {0x1E00, 0x1EFF, 29}, /* Latin Extended Additional. */
+ {0x1F00, 0x1FFF, 30}, /* Greek Extended. */
+ {0x2000, 0x206F, 31}, /* General Punctuation. */
+ {0x2070, 0x209F, 32}, /* Superscripts And Subscripts. */
+ {0x20A0, 0x20CF, 33}, /* Currency Symbols. */
+ {0x20D0, 0x20FF, 34}, /* Combining Diacritical Marks For Symbols. */
+ {0x2100, 0x214F, 35}, /* Letterlike Symbols. */
+ {0x2150, 0x218F, 36}, /* Number Forms. */
+ {0x2190, 0x21FF, 37}, /* Arrows. */
+ {0x2200, 0x22FF, 38}, /* Mathematical Operators. */
+ {0x2300, 0x23FF, 39}, /* Miscellaneous Technical. */
+ {0x2400, 0x243F, 40}, /* Control Pictures. */
+ {0x2440, 0x245F, 41}, /* Optical Character Recognition. */
+ {0x2460, 0x24FF, 42}, /* Enclosed Alphanumerics. */
+ {0x2500, 0x257F, 43}, /* Box Drawing. */
+ {0x2580, 0x259F, 44}, /* Block Elements. */
+ {0x25A0, 0x25FF, 45}, /* Geometric Shapes. */
+ {0x2600, 0x26FF, 46}, /* Miscellaneous Symbols. */
+ {0x2700, 0x27BF, 47}, /* Dingbats. */
+ {0x27C0, 0x27EF, 38}, /* Mathematical Operators. */
+ {0x27F0, 0x27FF, 37}, /* Arrows. */
+ {0x2800, 0x28FF, 82}, /* Braille. */
+ {0x2900, 0x297F, 37}, /* Arrows. */
+ {0x2980, 0x2AFF, 38}, /* Mathematical Operators. */
+ {0x2B00, 0x2BFF, 37}, /* Arrows. */
+ {0x2C00, 0x2C5F, 97}, /* Glagolitic. */
+ {0x2C60, 0x2C7F, 29}, /* Latin Extended Additional. */
+ {0x2C80, 0x2CFF, 8}, /* Coptic. */
+ {0x2D00, 0x2D2F, 26}, /* Georgian. */
+ {0x2D30, 0x2D7F, 98}, /* Tifinagh. */
+ {0x2D80, 0x2DDF, 75}, /* Ethiopic. */
+ {0x2DE0, 0x2DFF, 9}, /* Cyrillic. */
+ {0x2E00, 0x2E7F, 31}, /* General Punctuation. */
+ {0x2E80, 0x2FFF, 59}, /* CJK Unified Ideographs. */
+ {0x3000, 0x303F, 48}, /* CJK Symbols And Punctuation. */
+ {0x3040, 0x309F, 49}, /* Hiragana. */
+ {0x30A0, 0x30FF, 50}, /* Katakana. */
+ {0x3100, 0x312F, 51}, /* Bopomofo. */
+ {0x3130, 0x318F, 52}, /* Hangul Compatibility Jamo. */
+ {0x3190, 0x319F, 59}, /* CJK Unified Ideographs. */
+ {0x31A0, 0x31BF, 51}, /* Bopomofo. */
+ {0x31C0, 0x31EF, 59}, /* CJK Unified Ideographs. */
+ {0x31F0, 0x31FF, 50}, /* Katakana. */
+ {0x3200, 0x32FF, 54}, /* Enclosed CJK Letters And Months. */
+ {0x3300, 0x33FF, 55}, /* CJK Compatibility. */
+ {0x3400, 0x4DBF, 59}, /* CJK Unified Ideographs. */
+ {0x4DC0, 0x4DFF, 99}, /* Yijing. */
+ {0x4E00, 0x9FFF, 59}, /* CJK Unified Ideographs. */
+ {0xA000, 0xA4CF, 83}, /* Yi. */
+ {0xA4D0, 0xA4FF, -1}, /* Lisu. */
+ {0xA500, 0xA63F, 12}, /* Vai. */
+ {0xA640, 0xA69F, 9}, /* Cyrillic. */
+ {0xA6A0, 0xA6FF, -1}, /* Bamum. */
+ {0xA700, 0xA71F, 5}, /* Spacing Modifier Letters. */
+ {0xA720, 0xA7FF, 29}, /* Latin Extended Additional. */
+ {0xA800, 0xA82F, 100}, /* Syloti Nagri. */
+ {0xA840, 0xA87F, 53}, /* Phags-pa. */
+ {0xA880, 0xA8DF, 115}, /* Saurashtra. */
+ {0xA900, 0xA92F, 116}, /* Kayah Li. */
+ {0xA930, 0xA95F, 117}, /* Rejang. */
+ {0xA960, 0xA97F, 56}, /* Hangul Syllables. */
+ {0xA980, 0xA9DF, -1}, /* Javanese. */
+ {0xA9E0, 0xA9FF, 74}, /* Myanmar. */
+ {0xAA00, 0xAA5F, 118}, /* Cham. */
+ {0xAA60, 0xAA7F, 74}, /* Myanmar. */
+ {0xAA80, 0xAADF, -1}, /* Tai Viet. */
+ {0xAAE0, 0xAAFF, -1}, /* Meetei Mayek. */
+ {0xAB00, 0xAB2F, 75}, /* Ethiopic. */
+ {0xAB70, 0xABBF, 76}, /* Cherokee. */
+ {0xABC0, 0xABFF, -1}, /* Meetei Mayek. */
+ {0xAC00, 0xD7AF, 56}, /* Hangul Syllables. */
+ {0xD800, 0xDFFF, 57}, /* Non-Plane 0. */
+ {0xE000, 0xF6FF, 60}, /* Private Use Area. */
+ {0xE700, 0xEFFF, -1}, /* MS Wingdings. */
+ {0xF000, 0xF8FF, -1}, /* MS Symbols. */
+ {0xF900, 0xFAFF, 61}, /* CJK Compatibility Ideographs. */
+ {0xFB00, 0xFB4F, 62}, /* Alphabetic Presentation Forms. */
+ {0xFB50, 0xFDFF, 63}, /* Arabic Presentation Forms-A. */
+ {0xFE00, 0xFE0F, 91}, /* Variation Selectors. */
+ {0xFE10, 0xFE1F, 65}, /* CJK Compatibility Forms. */
+ {0xFE20, 0xFE2F, 64}, /* Combining Half Marks. */
+ {0xFE30, 0xFE4F, 65}, /* CJK Compatibility Forms. */
+ {0xFE50, 0xFE6F, 66}, /* Small Form Variants. */
+ {0xFE70, 0xFEFF, 67}, /* Arabic Presentation Forms-B. */
+ {0xFF00, 0xFFEF, 68}, /* Halfwidth And Fullwidth Forms. */
+ {0xFFF0, 0xFFFF, 69}, /* Specials. */
+ {0x10000, 0x1013F, 101}, /* Linear B. */
+ {0x10140, 0x1018F, 102}, /* Ancient Greek Numbers. */
+ {0x10190, 0x101CF, 119}, /* Ancient Symbols. */
+ {0x101D0, 0x101FF, 120}, /* Phaistos Disc. */
+ {0x10280, 0x1029F, 121}, /* Lycian. */
+ {0x102A0, 0x102DF, 121}, /* Carian. */
+ {0x10300, 0x1032F, 85}, /* Old Italic. */
+ {0x10330, 0x1034F, 86}, /* Gothic. */
+ {0x10350, 0x1037F, -1}, /* Old Permic. */
+ {0x10380, 0x1039F, 103}, /* Ugaritic. */
+ {0x103A0, 0x103DF, 104}, /* Old Persian. */
+ {0x10400, 0x1044F, 87}, /* Deseret. */
+ {0x10450, 0x1047F, 105}, /* Shavian. */
+ {0x10480, 0x104AF, 106}, /* Osmanya. */
+ {0x104B0, 0x104FF, -1}, /* Osage. */
+ {0x10500, 0x1052F, -1}, /* Elbasan. */
+ {0x10530, 0x1056F, -1}, /* Caucasian Albanian. */
+ {0x10570, 0x105BF, -1}, /* Vithkuqi. */
+ {0x10600, 0x1077F, -1}, /* Linear A. */
+ {0x10780, 0x107BF, 3}, /* Latin Extended-B. */
+ {0x10800, 0x1083F, 107}, /* Cypriot Syllabary. */
+ {0x10840, 0x1085F, -1}, /* Imperial Aramaic. */
+ {0x10860, 0x1087F, -1}, /* Palmyrene. */
+ {0x10880, 0x108AF, -1}, /* Nabataean. */
+ {0x108E0, 0x108FF, -1}, /* Hatran. */
+ {0x10900, 0x1091F, 58}, /* Phoenician. */
+ {0x10920, 0x1093F, 121}, /* Lydian. */
+ {0x10980, 0x1099F, -1}, /* Meroitic Hieroglyphs. */
+ {0x109A0, 0x109FF, -1}, /* Meroitic Cursive. */
+ {0x10A00, 0x10A5F, 108}, /* Kharoshthi. */
+ {0x10A60, 0x10A7F, -1}, /* Old South Arabian. */
+ {0x10A80, 0x10A9F, -1}, /* Old North Arabian. */
+ {0x10AC0, 0x10AFF, -1}, /* Manichaean. */
+ {0x10B00, 0x10B3F, -1}, /* Avestan. */
+ {0x10B40, 0x10B5F, -1}, /* Inscriptional Parthian. */
+ {0x10B60, 0x10B7F, -1}, /* Inscriptional Pahlavi. */
+ {0x10B80, 0x10BAF, -1}, /* Psalter Pahlavi. */
+ {0x10C00, 0x10C4F, -1}, /* Old Turkic. */
+ {0x10C80, 0x10CFF, -1}, /* Old Hungarian. */
+ {0x10D00, 0x10D3F, -1}, /* Hanifi Rohingya. */
+ {0x108E0, 0x10E7F, -1}, /* Rumi Numeral Symbols. */
+ {0x10E80, 0x10EBF, -1}, /* Yezidi. */
+ {0x10F00, 0x10F2F, -1}, /* Old Sogdian. */
+ {0x10F30, 0x10F6F, -1}, /* Sogdian. */
+ {0x10F70, 0x10FAF, -1}, /* Old Uyghur. */
+ {0x10FB0, 0x10FDF, -1}, /* Chorasmian. */
+ {0x10FE0, 0x10FFF, -1}, /* Elymaic. */
+ {0x11000, 0x1107F, -1}, /* Brahmi. */
+ {0x11080, 0x110CF, -1}, /* Kaithi. */
+ {0x110D0, 0x110FF, -1}, /* Sora Sompeng. */
+ {0x11100, 0x1114F, -1}, /* Chakma. */
+ {0x11150, 0x1117F, -1}, /* Mahajani. */
+ {0x11180, 0x111DF, -1}, /* Sharada. */
+ {0x111E0, 0x111FF, -1}, /* Sinhala Archaic Numbers. */
+ {0x11200, 0x1124F, -1}, /* Khojki. */
+ {0x11280, 0x112AF, -1}, /* Multani. */
+ {0x112B0, 0x112FF, -1}, /* Khudawadi. */
+ {0x11300, 0x1137F, -1}, /* Grantha. */
+ {0x11400, 0x1147F, -1}, /* Newa. */
+ {0x11480, 0x114DF, -1}, /* Tirhuta. */
+ {0x11580, 0x115FF, -1}, /* Siddham. */
+ {0x11600, 0x1165F, -1}, /* Modi. */
+ {0x11660, 0x1167F, 81}, /* Mongolian. */
+ {0x11680, 0x116CF, -1}, /* Takri. */
+ {0x11700, 0x1174F, -1}, /* Ahom. */
+ {0x11800, 0x1184F, -1}, /* Dogra. */
+ {0x118A0, 0x118FF, -1}, /* Warang Citi. */
+ {0x11900, 0x1195F, -1}, /* Dives Akuru. */
+ {0x119A0, 0x119FF, -1}, /* Nandinagari. */
+ {0x11A00, 0x11A4F, -1}, /* Zanabazar Square. */
+ {0x11A50, 0x11AAF, -1}, /* Soyombo. */
+ {0x11AB0, 0x11ABF, 77}, /* Canadian Aboriginal Syllabics. */
+ {0x11AC0, 0x11AFF, -1}, /* Pau Cin Hau. */
+ {0x11C00, 0x11C6F, -1}, /* Bhaiksuki. */
+ {0x11C70, 0x11CBF, -1}, /* Marchen. */
+ {0x11D00, 0x11D5F, -1}, /* Masaram Gondi. */
+ {0x11D60, 0x11DAF, -1}, /* Gunjala Gondi. */
+ {0x11EE0, 0x11EFF, -1}, /* Makasar. */
+ {0x11FB0, 0x11FBF, -1}, /* Lisu. */
+ {0x11FC0, 0x11FFF, 20}, /* Tamil. */
+ {0x12000, 0x1254F, 110}, /* Cuneiform. */
+ {0x12F90, 0x12FFF, -1}, /* Cypro-Minoan. */
+ {0x13000, 0x1343F, -1}, /* Egyptian Hieroglyphs. */
+ {0x14400, 0x1467F, -1}, /* Anatolian Hieroglyphs. */
+ {0x16800, 0x16A3F, -1}, /* Bamum. */
+ {0x16A40, 0x16A6F, -1}, /* Mro. */
+ {0x16A70, 0x16ACF, -1}, /* Tangsa. */
+ {0x16AD0, 0x16AFF, -1}, /* Bassa Vah. */
+ {0x16B00, 0x16B8F, -1}, /* Pahawh Hmong. */
+ {0x16E40, 0x16E9F, -1}, /* Medefaidrin. */
+ {0x16F00, 0x16F9F, -1}, /* Miao. */
+ {0x16FE0, 0x16FFF, -1}, /* Ideographic Symbols. */
+ {0x17000, 0x18AFF, -1}, /* Tangut. */
+ {0x1B170, 0x1B2FF, -1}, /* Nushu. */
+ {0x1BC00, 0x1BC9F, -1}, /* Duployan. */
+ {0x1D000, 0x1D24F, 88}, /* Musical Symbols. */
+ {0x1D2E0, 0x1D2FF, -1}, /* Mayan Numerals. */
+ {0x1D300, 0x1D35F, 109}, /* Tai Xuan Jing. */
+ {0x1D360, 0x1D37F, 111}, /* Counting Rod Numerals. */
+ {0x1D400, 0x1D7FF, 89}, /* Mathematical Alphanumeric Symbols. */
+ {0x1E2C0, 0x1E2FF, -1}, /* Wancho. */
+ {0x1E800, 0x1E8DF, -1}, /* Mende Kikakui. */
+ {0x1E900, 0x1E95F, -1}, /* Adlam. */
+ {0x1EC70, 0x1ECBF, -1}, /* Indic Siyaq Numbers. */
+ {0x1F000, 0x1F02F, 122}, /* Mahjong Tiles. */
+ {0x1F030, 0x1F09F, 122}, /* Domino Tiles. */
+ {0x1F600, 0x1F64F, -1}, /* Emoticons. */
+ {0x20000, 0x2A6DF, 59}, /* CJK Unified Ideographs. */
+ {0x2F800, 0x2FA1F, 61}, /* CJK Compatibility Ideographs. */
+ {0xE0000, 0xE007F, 92}, /* Tags. */
+ {0xE0100, 0xE01EF, 91}, /* Variation Selectors. */
+ {0xF0000, 0x10FFFD, 90}}; /* Private Use Supplementary. */
+
+/* Find a unicode block that a charcode belongs to. */
+static eUnicodeBlock *blf_charcode_to_unicode_block(uint charcode)
+{
+ if (charcode < 0x80) {
+ /* Shortcut to Basic Latin. */
+ return &unicode_blocks[0];
+ }
+
+ /* Binary search for other blocks. */
+
+ int min = 0;
+ int max = ARRAY_SIZE(unicode_blocks) - 1;
+ int mid;
+
+ if (charcode < unicode_blocks[0].first || charcode > unicode_blocks[max].last) {
+ return NULL;
+ }
+
+ while (max >= min) {
+ mid = (min + max) / 2;
+ if (charcode > unicode_blocks[mid].last) {
+ min = mid + 1;
+ }
+ else if (charcode < unicode_blocks[mid].first) {
+ max = mid - 1;
+ }
+ else {
+ return &unicode_blocks[mid];
+ }
+ }
+
+ return NULL;
+}
+
+static int blf_charcode_to_coverage_bit(uint charcode)
+{
+ int coverage_bit = -1;
+ eUnicodeBlock *block = blf_charcode_to_unicode_block(charcode);
+ if (block) {
+ coverage_bit = block->coverage_bit;
+ }
+
+ if (coverage_bit < 0 && charcode > 0xFFFF) {
+ /* No coverage bit, but OpenType specs v.1.3+ says bit 57 implies that there
+ * are codepoints supported beyond the BMP, so only check fonts with this set. */
+ coverage_bit = 57;
+ }
+
+ return coverage_bit;
+}
+
+static bool blf_font_has_coverage_bit(FontBLF *font, int coverage_bit)
+{
+ if (coverage_bit < 0) {
+ return false;
+ }
+ return (font->UnicodeRanges[(uint)coverage_bit >> 5] & (1u << ((uint)coverage_bit % 32)));
+}
+
/**
* Return a glyph index from `charcode`. Not found returns zero, which is a valid
* printable character (`.notdef` or `tofu`). Font is allowed to change here.
@@ -229,8 +559,42 @@ static GlyphBLF *blf_glyph_cache_add_glyph(
static FT_UInt blf_glyph_index_from_charcode(FontBLF **font, const uint charcode)
{
FT_UInt glyph_index = FT_Get_Char_Index((*font)->face, charcode);
- /* TODO: If not found in this font, check others, update font pointer. */
- return glyph_index;
+ if (glyph_index) {
+ return glyph_index;
+ }
+
+ /* Not found in main font, so look in the others. */
+ FontBLF *last_resort = NULL;
+ int coverage_bit = blf_charcode_to_coverage_bit(charcode);
+ for (int i = 0; i < BLF_MAX_FONT; i++) {
+ FontBLF *f = global_font[i];
+ if (!f || f == *font || !(f->flags & BLF_DEFAULT)) {
+ continue;
+ }
+
+ if (f->flags & BLF_LAST_RESORT) {
+ last_resort = f;
+ continue;
+ }
+ if (coverage_bit < 0 || blf_font_has_coverage_bit(f, coverage_bit)) {
+ glyph_index = FT_Get_Char_Index(f->face, charcode);
+ if (glyph_index) {
+ *font = f;
+ return glyph_index;
+ }
+ }
+ }
+
+ /* Not found in the stack, return from Last Resort if there is one. */
+ if (last_resort) {
+ glyph_index = FT_Get_Char_Index(last_resort->face, charcode);
+ if (glyph_index) {
+ *font = last_resort;
+ return glyph_index;
+ }
+ }
+
+ return 0;
}
/**
@@ -377,24 +741,24 @@ static bool UNUSED_FUNCTION(blf_glyph_transform_width)(FT_GlyphSlot glyph, float
/**
* Transform glyph to fit nicely within a fixed column width.
*/
-static bool UNUSED_FUNCTION(blf_glyph_transform_monospace)(FT_GlyphSlot glyph, int width)
+static bool blf_glyph_transform_monospace(FT_GlyphSlot glyph, int width)
{
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
- int gwidth = (int)(glyph->linearHoriAdvance >> 16);
- if (gwidth > width) {
- float scale = (float)width / (float)gwidth;
+ FT_Fixed current = glyph->linearHoriAdvance;
+ FT_Fixed target = width << 16; /* Do math in 16.16 values. */
+ if (target < current) {
+ const FT_Pos embolden = (FT_Pos)((current - target) >> 13);
+ /* Horizontally widen strokes to counteract narrowing. */
+ FT_Outline_EmboldenXY(&glyph->outline, embolden, 0);
+ const float scale = (float)(target - (embolden << 9)) / (float)current;
FT_Matrix matrix = {to_16dot16(scale), 0, 0, to_16dot16(1)};
- /* Narrowing all points also thins vertical strokes. */
FT_Outline_Transform(&glyph->outline, &matrix);
- const FT_Pos extra_x = (int)((float)(gwidth - width) * 5.65f);
- /* Horizontally widen strokes to counteract narrowing. */
- FT_Outline_EmboldenXY(&glyph->outline, extra_x, 0);
}
- else if (gwidth < width) {
- /* Narrow glyphs only need to be centered. */
- int nudge = (width - gwidth) / 2;
- FT_Outline_Translate(&glyph->outline, (FT_Pos)nudge * 64, 0);
+ else if (target > current) {
+ /* Center narrow glyphs. */
+ FT_Outline_Translate(&glyph->outline, (FT_Pos)((target - current) >> 11), 0);
}
+ glyph->advance.x = width << 6;
return true;
}
return false;
@@ -411,7 +775,9 @@ static bool UNUSED_FUNCTION(blf_glyph_transform_monospace)(FT_GlyphSlot glyph, i
*/
static FT_GlyphSlot blf_glyph_render(FontBLF *settings_font,
FontBLF *glyph_font,
- FT_UInt glyph_index)
+ FT_UInt glyph_index,
+ uint charcode,
+ int fixed_width)
{
if (glyph_font != settings_font) {
FT_Set_Char_Size(glyph_font->face,
@@ -428,6 +794,10 @@ static FT_GlyphSlot blf_glyph_render(FontBLF *settings_font,
return NULL;
}
+ if ((settings_font->flags & BLF_MONOSPACED) && (settings_font != glyph_font)) {
+ blf_glyph_transform_monospace(glyph, BLI_wcwidth((char32_t)charcode) * fixed_width);
+ }
+
if ((settings_font->flags & BLF_ITALIC) != 0) {
/* 37.5% of maximum rightward slant results in 6 degree slope, matching italic
* version (`DejaVuSans-Oblique.ttf`) of our current font. But a nice median when
@@ -466,7 +836,8 @@ GlyphBLF *blf_glyph_ensure(FontBLF *font, GlyphCacheBLF *gc, uint charcode)
* renderer uses a shared buffer internally. */
BLI_spin_lock(font_with_glyph->ft_lib_mutex);
- FT_GlyphSlot glyph = blf_glyph_render(font, font_with_glyph, glyph_index);
+ FT_GlyphSlot glyph = blf_glyph_render(
+ font, font_with_glyph, glyph_index, charcode, gc->fixed_width);
if (glyph) {
/* Save this glyph in the initial font's cache. */
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index 7754f960043..84037ff4bd0 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -14,6 +14,12 @@ struct ResultBLF;
struct rctf;
struct rcti;
+/* Max number of fonts in memory. Take care that every font has a glyph cache per size/dpi,
+ * so we don't need load the same font with different size, just load one and call BLF_size. */
+#define BLF_MAX_FONT 32
+
+extern struct FontBLF *global_font[BLF_MAX_FONT];
+
void blf_batch_draw_begin(struct FontBLF *font);
void blf_batch_draw(void);
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index 9dfcb1a4ad6..998093dae70 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -226,6 +226,11 @@ typedef struct FontBLF {
/** File-path or NULL. */
char *filepath;
+ /* Copied from the SFNT OS/2 table. Bit flags for unicode blocks and ranges
+ * considered "functional". Cached here because face might not always exist.
+ * See: https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur */
+ uint UnicodeRanges[4];
+
/* aspect ratio or scale. */
float aspect[3];
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 2cd753da9d3..20eb33c5d15 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -25,7 +25,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 1
+#define BLENDER_FILE_SUBVERSION 2
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index 59b22f7759b..2c444f42c46 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -77,8 +77,16 @@ typedef struct MainIDRelationsEntry {
typedef enum eMainIDRelationsEntryTags {
/* Generic tag marking the entry as to be processed. */
MAINIDRELATIONS_ENTRY_TAGS_DOIT = 1 << 0,
+
+ /* Generic tag marking the entry as processed in the `to` direction (i.e. we processed the IDs
+ * used by this item). */
+ MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_TO = 1 << 1,
+ /* Generic tag marking the entry as processed in the `from` direction (i.e. we processed the IDs
+ * using by this item). */
+ MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_FROM = 1 << 2,
/* Generic tag marking the entry as processed. */
- MAINIDRELATIONS_ENTRY_TAGS_PROCESSED = 1 << 1,
+ MAINIDRELATIONS_ENTRY_TAGS_PROCESSED = MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_TO |
+ MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_FROM,
} eMainIDRelationsEntryTags;
typedef struct MainIDRelations {
diff --git a/source/blender/blenkernel/BKE_mesh_boolean_convert.hh b/source/blender/blenkernel/BKE_mesh_boolean_convert.hh
index abaf2ab0178..441783d46a1 100644
--- a/source/blender/blenkernel/BKE_mesh_boolean_convert.hh
+++ b/source/blender/blenkernel/BKE_mesh_boolean_convert.hh
@@ -23,6 +23,8 @@ namespace blender::meshintersect {
* \param material_remaps: An array of maps from material slot numbers in the corresponding mesh
* to the material slot in the first mesh. It is OK for material_remaps or any of its constituent
* arrays to be empty.
+ * \param r_intersecting_edges: Array to store indices of edges on the resulting mesh in. These
+ * 'new' edges are the result of the intersections.
*/
Mesh *direct_mesh_boolean(Span<const Mesh *> meshes,
Span<const float4x4 *> transforms,
@@ -30,6 +32,7 @@ Mesh *direct_mesh_boolean(Span<const Mesh *> meshes,
Span<Array<short>> material_remaps,
bool use_self,
bool hole_tolerant,
- int boolean_mode);
+ int boolean_mode,
+ Vector<int> *r_intersecting_edges);
} // namespace blender::meshintersect
diff --git a/source/blender/blenkernel/BKE_mesh_remap.h b/source/blender/blenkernel/BKE_mesh_remap.h
index e2b16a7681d..ee0179c7a77 100644
--- a/source/blender/blenkernel/BKE_mesh_remap.h
+++ b/source/blender/blenkernel/BKE_mesh_remap.h
@@ -42,7 +42,7 @@ void BKE_mesh_remap_free(MeshPairRemap *map);
void BKE_mesh_remap_item_define_invalid(MeshPairRemap *map, int index);
/* TODO:
- * Add other 'from/to' mapping sources, like e.g. using an UVMap, etc.
+ * Add other 'from/to' mapping sources, like e.g. using a UVMap, etc.
* https://blenderartists.org/t/619105
*
* We could also use similar topology mappings inside a same mesh
diff --git a/source/blender/blenkernel/BKE_mesh_sample.hh b/source/blender/blenkernel/BKE_mesh_sample.hh
index 37c2ad7d3cb..cbbd0249f4f 100644
--- a/source/blender/blenkernel/BKE_mesh_sample.hh
+++ b/source/blender/blenkernel/BKE_mesh_sample.hh
@@ -6,12 +6,20 @@
* \ingroup bke
*/
+#include "BLI_function_ref.hh"
#include "BLI_generic_virtual_array.hh"
#include "BLI_math_vec_types.hh"
+#include "DNA_meshdata_types.h"
+
#include "BKE_attribute.h"
struct Mesh;
+struct BVHTreeFromMesh;
+
+namespace blender {
+class RandomNumberGenerator;
+}
namespace blender::bke {
struct ReadAttributeLookup;
@@ -82,4 +90,55 @@ class MeshAttributeInterpolator {
Span<float3> ensure_nearest_weights();
};
+/**
+ * Find randomly distributed points on the surface of a mesh within a 3D sphere. This does not
+ * sample an exact number of points because it comes with extra overhead to avoid bias that is only
+ * required in some cases. If an exact number of points is required, that has to be implemented at
+ * a higher level.
+ *
+ * \param approximate_density: Roughly the number of points per unit of area.
+ * \return The number of added points.
+ */
+int sample_surface_points_spherical(RandomNumberGenerator &rng,
+ const Mesh &mesh,
+ Span<int> looptri_indices_to_sample,
+ const float3 &sample_pos,
+ float sample_radius,
+ float approximate_density,
+ Vector<float3> &r_bary_coords,
+ Vector<int> &r_looptri_indices,
+ Vector<float3> &r_positions);
+
+/**
+ * Find randomly distributed points on the surface of a mesh within a circle that is projected on
+ * the mesh. This does not result in an exact number of points because that would come with extra
+ * overhead and is not always possible. If an exact number of points is required, that has to be
+ * implemented at a higher level.
+ *
+ * \param region_position_to_ray: Function that converts a 2D position into a 3D ray that is used
+ * to find positions on the mesh.
+ * \param mesh_bvhtree: BVH tree of the triangles in the mesh. Passed in so that it does not have
+ * to be retrieved again.
+ * \param tries_num: Number of 2d positions that are sampled. The maximum
+ * number of new samples.
+ * \return The number of added points.
+ */
+int sample_surface_points_projected(
+ RandomNumberGenerator &rng,
+ const Mesh &mesh,
+ BVHTreeFromMesh &mesh_bvhtree,
+ const float2 &sample_pos_re,
+ float sample_radius_re,
+ FunctionRef<void(const float2 &pos_re, float3 &r_start, float3 &r_end)> region_position_to_ray,
+ bool front_face_only,
+ int tries_num,
+ int max_points,
+ Vector<float3> &r_bary_coords,
+ Vector<int> &r_looptri_indices,
+ Vector<float3> &r_positions);
+
+float3 compute_bary_coord_in_triangle(const Mesh &mesh,
+ const MLoopTri &looptri,
+ const float3 &position);
+
} // namespace blender::bke::mesh_surface_sample
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 7ec8000b6f9..59a1599e7ae 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1495,6 +1495,7 @@ struct TexResult;
#define GEO_NODE_REMOVE_ATTRIBUTE 1158
#define GEO_NODE_INPUT_INSTANCE_ROTATION 1159
#define GEO_NODE_INPUT_INSTANCE_SCALE 1160
+#define GEO_NODE_VOLUME_CUBE 1161
/** \} */
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 6ffb3299869..aa09541c043 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -949,30 +949,9 @@ static void default_get_tarmat_full_bbone(struct Depsgraph *UNUSED(depsgraph),
} \
(void)0
-static void custom_space_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
+static bool is_custom_space_needed(bConstraint *con)
{
- func(con, (ID **)&con->space_object, false, userdata);
-}
-
-static int get_space_tar(bConstraint *con, ListBase *list)
-{
- if (!con || !list ||
- (con->ownspace != CONSTRAINT_SPACE_CUSTOM && con->tarspace != CONSTRAINT_SPACE_CUSTOM)) {
- return 0;
- }
- bConstraintTarget *ct;
- SINGLETARGET_GET_TARS(con, con->space_object, con->space_subtarget, ct, list);
- return 1;
-}
-
-static void flush_space_tar(bConstraint *con, ListBase *list, bool no_copy)
-{
- if (!con || !list ||
- (con->ownspace != CONSTRAINT_SPACE_CUSTOM && con->tarspace != CONSTRAINT_SPACE_CUSTOM)) {
- return;
- }
- bConstraintTarget *ct = (bConstraintTarget *)list->last;
- SINGLETARGET_FLUSH_TARS(con, con->space_object, con->space_subtarget, ct, list, no_copy);
+ return con->ownspace == CONSTRAINT_SPACE_CUSTOM || con->tarspace == CONSTRAINT_SPACE_CUSTOM;
}
/* --------- ChildOf Constraint ------------ */
@@ -1161,8 +1140,6 @@ static void trackto_id_looper(bConstraint *con, ConstraintIDFunc func, void *use
/* target only */
func(con, (ID **)&data->tar, false, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int trackto_get_tars(bConstraint *con, ListBase *list)
@@ -1174,7 +1151,7 @@ static int trackto_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -1188,7 +1165,6 @@ static void trackto_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -1661,11 +1637,11 @@ static bConstraintTypeInfo CTI_LOCLIMIT = {
"Limit Location", /* name */
"bLocLimitConstraint", /* struct name */
NULL, /* free data */
- custom_space_id_looper, /* id looper */
+ NULL, /* id looper */
NULL, /* copy data */
NULL, /* new data */
- get_space_tar, /* get constraint targets */
- flush_space_tar, /* flush constraint targets */
+ NULL, /* get constraint targets */
+ NULL, /* flush constraint targets */
NULL, /* get target matrix */
loclimit_evaluate, /* evaluate */
};
@@ -1742,11 +1718,11 @@ static bConstraintTypeInfo CTI_ROTLIMIT = {
"Limit Rotation", /* name */
"bRotLimitConstraint", /* struct name */
NULL, /* free data */
- custom_space_id_looper, /* id looper */
+ NULL, /* id looper */
NULL, /* copy data */
NULL, /* new data */
- get_space_tar, /* get constraint targets */
- flush_space_tar, /* flush constraint targets */
+ NULL, /* get constraint targets */
+ NULL, /* flush constraint targets */
NULL, /* get target matrix */
rotlimit_evaluate, /* evaluate */
};
@@ -1809,11 +1785,11 @@ static bConstraintTypeInfo CTI_SIZELIMIT = {
"Limit Scale", /* name */
"bSizeLimitConstraint", /* struct name */
NULL, /* free data */
- custom_space_id_looper, /* id looper */
+ NULL, /* id looper */
NULL, /* copy data */
NULL, /* new data */
- get_space_tar, /* get constraint targets */
- flush_space_tar, /* flush constraint targets */
+ NULL, /* get constraint targets */
+ NULL, /* flush constraint targets */
NULL, /* get target matrix */
sizelimit_evaluate, /* evaluate */
};
@@ -1833,8 +1809,6 @@ static void loclike_id_looper(bConstraint *con, ConstraintIDFunc func, void *use
/* target only */
func(con, (ID **)&data->tar, false, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int loclike_get_tars(bConstraint *con, ListBase *list)
@@ -1846,7 +1820,7 @@ static int loclike_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -1860,7 +1834,6 @@ static void loclike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -1933,8 +1906,6 @@ static void rotlike_id_looper(bConstraint *con, ConstraintIDFunc func, void *use
/* target only */
func(con, (ID **)&data->tar, false, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int rotlike_get_tars(bConstraint *con, ListBase *list)
@@ -1946,7 +1917,7 @@ static int rotlike_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -1960,7 +1931,6 @@ static void rotlike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -2114,8 +2084,6 @@ static void sizelike_id_looper(bConstraint *con, ConstraintIDFunc func, void *us
/* target only */
func(con, (ID **)&data->tar, false, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int sizelike_get_tars(bConstraint *con, ListBase *list)
@@ -2127,7 +2095,7 @@ static int sizelike_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -2141,7 +2109,6 @@ static void sizelike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -2239,8 +2206,6 @@ static void translike_id_looper(bConstraint *con, ConstraintIDFunc func, void *u
/* target only */
func(con, (ID **)&data->tar, false, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int translike_get_tars(bConstraint *con, ListBase *list)
@@ -2252,7 +2217,7 @@ static int translike_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -2266,7 +2231,6 @@ static void translike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -2400,11 +2364,11 @@ static bConstraintTypeInfo CTI_SAMEVOL = {
"Maintain Volume", /* name */
"bSameVolumeConstraint", /* struct name */
NULL, /* free data */
- custom_space_id_looper, /* id looper */
+ NULL, /* id looper */
NULL, /* copy data */
samevolume_new_data, /* new data */
- get_space_tar, /* get constraint targets */
- flush_space_tar, /* flush constraint targets */
+ NULL, /* get constraint targets */
+ NULL, /* flush constraint targets */
NULL, /* get target matrix */
samevolume_evaluate, /* evaluate */
};
@@ -2810,8 +2774,6 @@ static void actcon_id_looper(bConstraint *con, ConstraintIDFunc func, void *user
/* action */
func(con, (ID **)&data->act, true, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int actcon_get_tars(bConstraint *con, ListBase *list)
@@ -2823,7 +2785,7 @@ static int actcon_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -2837,7 +2799,6 @@ static void actcon_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -3338,8 +3299,6 @@ static void distlimit_id_looper(bConstraint *con, ConstraintIDFunc func, void *u
/* target only */
func(con, (ID **)&data->tar, false, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int distlimit_get_tars(bConstraint *con, ListBase *list)
@@ -3351,7 +3310,7 @@ static int distlimit_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -3365,7 +3324,6 @@ static void distlimit_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -3694,8 +3652,6 @@ static void minmax_id_looper(bConstraint *con, ConstraintIDFunc func, void *user
/* target only */
func(con, (ID **)&data->tar, false, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int minmax_get_tars(bConstraint *con, ListBase *list)
@@ -3707,7 +3663,7 @@ static int minmax_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -3721,7 +3677,6 @@ static void minmax_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -4019,8 +3974,6 @@ static void transform_id_looper(bConstraint *con, ConstraintIDFunc func, void *u
/* target only */
func(con, (ID **)&data->tar, false, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int transform_get_tars(bConstraint *con, ListBase *list)
@@ -4032,7 +3985,7 @@ static int transform_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -4046,7 +3999,6 @@ static void transform_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -5582,6 +5534,19 @@ static void con_unlink_refs_cb(bConstraint *UNUSED(con),
}
}
+/** Helper function to invoke the id_looper callback, including custom space. */
+static void con_invoke_id_looper(const bConstraintTypeInfo *cti,
+ bConstraint *con,
+ ConstraintIDFunc func,
+ void *userdata)
+{
+ if (cti->id_looper) {
+ cti->id_looper(con, func, userdata);
+ }
+
+ func(con, (ID **)&con->space_object, false, userdata);
+}
+
void BKE_constraint_free_data_ex(bConstraint *con, bool do_id_user)
{
if (con->data) {
@@ -5594,8 +5559,8 @@ void BKE_constraint_free_data_ex(bConstraint *con, bool do_id_user)
}
/* unlink the referenced resources it uses */
- if (do_id_user && cti->id_looper) {
- cti->id_looper(con, con_unlink_refs_cb, NULL);
+ if (do_id_user) {
+ con_invoke_id_looper(cti, con, con_unlink_refs_cb, NULL);
}
}
@@ -5913,9 +5878,7 @@ void BKE_constraints_id_loop(ListBase *conlist, ConstraintIDFunc func, void *use
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
if (cti) {
- if (cti->id_looper) {
- cti->id_looper(con, func, userdata);
- }
+ con_invoke_id_looper(cti, con, func, userdata);
}
}
}
@@ -5967,16 +5930,14 @@ static void constraint_copy_data_ex(bConstraint *dst,
}
/* Fix usercounts for all referenced data that need it. */
- if (cti->id_looper && (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
- cti->id_looper(dst, con_fix_copied_refs_cb, NULL);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ con_invoke_id_looper(cti, dst, con_fix_copied_refs_cb, NULL);
}
/* for proxies we don't want to make extern */
if (do_extern) {
/* go over used ID-links for this constraint to ensure that they are valid for proxies */
- if (cti->id_looper) {
- cti->id_looper(dst, con_extern_cb, NULL);
- }
+ con_invoke_id_looper(cti, dst, con_extern_cb, NULL);
}
}
}
@@ -6208,6 +6169,15 @@ int BKE_constraint_targets_get(struct bConstraint *con, struct ListBase *r_targe
count = cti->get_constraint_targets(con, r_targets);
}
+ /* Add the custom target. */
+ if (is_custom_space_needed(con)) {
+ bConstraintTarget *ct;
+ SINGLETARGET_GET_TARS(con, con->space_object, con->space_subtarget, ct, r_targets);
+ ct->space = CONSTRAINT_SPACE_WORLD;
+ ct->flag |= CONSTRAINT_TAR_CUSTOM_SPACE;
+ count++;
+ }
+
return count;
}
@@ -6219,6 +6189,20 @@ void BKE_constraint_targets_flush(struct bConstraint *con, struct ListBase *targ
return;
}
+ /* Remove the custom target. */
+ bConstraintTarget *ct = (bConstraintTarget *)targets->last;
+
+ if (ct && (ct->flag & CONSTRAINT_TAR_CUSTOM_SPACE)) {
+ BLI_assert(is_custom_space_needed(con));
+
+ if (!no_copy) {
+ con->space_object = ct->tar;
+ BLI_strncpy(con->space_subtarget, ct->subtarget, sizeof(con->space_subtarget));
+ }
+
+ BLI_freelinkN(targets, ct);
+ }
+
/* Release the constraint-specific targets. */
if (cti->flush_constraint_targets) {
cti->flush_constraint_targets(con, targets, no_copy);
diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc
index 1c3715aaf69..b58781ce806 100644
--- a/source/blender/blenkernel/intern/curves_geometry.cc
+++ b/source/blender/blenkernel/intern/curves_geometry.cc
@@ -1370,6 +1370,7 @@ void CurvesGeometry::remove_curves(const IndexMask curves_to_delete)
}
if (curves_to_delete.size() == this->curves_num()) {
*this = {};
+ return;
}
*this = copy_with_removed_curves(*this, curves_to_delete);
}
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index f2915a97746..7722c2fa004 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -868,8 +868,6 @@ static void do_texture_effector(EffectorCache *eff,
return;
}
- result[0].nor = result[1].nor = result[2].nor = result[3].nor = NULL;
-
strength = eff->pd->f_strength * efd->falloff;
copy_v3_v3(tex_co, point->loc);
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 06d32d5bfd4..5cd5a699dec 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -1942,7 +1942,6 @@ static void sample_mesh(FluidFlowSettings *ffs,
tex_co[1] = tex_co[1] * 2.0f - 1.0f;
tex_co[2] = ffs->texture_offset;
}
- texres.nor = NULL;
BKE_texture_get_value(NULL, ffs->noise_texture, tex_co, &texres, false);
emission_strength *= texres.tin;
}
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index 5ef4d231807..0bf5418ea8f 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -678,7 +678,7 @@ static void copy_frame_to_eval_cb(bGPDlayer *gpl,
static void gpencil_copy_visible_frames_to_eval(Depsgraph *depsgraph, Scene *scene, Object *ob)
{
- /* Remap layers'active frame with time modifiers applied. */
+ /* Remap layers active frame with time modifiers applied. */
bGPdata *gpd_eval = ob->data;
LISTBASE_FOREACH (bGPDlayer *, gpl_eval, &gpd_eval->layers) {
bGPDframe *gpf_eval = gpl_eval->actframe;
diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc
index b9bb536d173..0c1f01c3796 100644
--- a/source/blender/blenkernel/intern/image.cc
+++ b/source/blender/blenkernel/intern/image.cc
@@ -1730,7 +1730,7 @@ static void stampdata_from_template(StampData *stamp_data,
stamp_data->file[0] = '\0';
}
if (scene->r.stamp & R_STAMP_NOTE) {
- SNPRINTF(stamp_data->note, "%s", stamp_data_template->note);
+ STRNCPY(stamp_data->note, stamp_data_template->note);
}
else {
stamp_data->note[0] = '\0';
diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc
index 22012662180..0b91a1e2866 100644
--- a/source/blender/blenkernel/intern/lib_override.cc
+++ b/source/blender/blenkernel/intern/lib_override.cc
@@ -687,6 +687,51 @@ static void lib_override_group_tag_data_clear(LibOverrideGroupTagData *data)
memset(data, 0, sizeof(*data));
}
+static void lib_override_hierarchy_dependencies_recursive_tag_from(LibOverrideGroupTagData *data)
+{
+ Main *bmain = data->bmain;
+ ID *id = data->id_root;
+ const bool is_override = data->is_override;
+
+ if ((*(uint *)&id->tag & data->tag) == 0) {
+ /* This ID is not tagged, no reason to proceed further to its parents. */
+ return;
+ }
+
+ MainIDRelationsEntry *entry = static_cast<MainIDRelationsEntry *>(
+ BLI_ghash_lookup(bmain->relations->relations_from_pointers, id));
+ BLI_assert(entry != nullptr);
+
+ if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_FROM) {
+ /* This ID has already been processed. */
+ return;
+ }
+ /* This way we won't process again that ID, should we encounter it again through another
+ * relationship hierarchy. */
+ entry->tags |= MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_FROM;
+
+ for (MainIDRelationsEntryItem *from_id_entry = entry->from_ids; from_id_entry != nullptr;
+ from_id_entry = from_id_entry->next) {
+ if ((from_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) {
+ /* Never consider non-overridable relationships ('from', 'parents', 'owner' etc. pointers)
+ * as actual dependencies. */
+ continue;
+ }
+ /* We only consider IDs from the same library. */
+ ID *from_id = from_id_entry->id_pointer.from;
+ if (from_id == nullptr || from_id->lib != id->lib ||
+ (is_override && !ID_IS_OVERRIDE_LIBRARY(from_id))) {
+ /* IDs from different libraries, or non-override IDs in case we are processing overrides,
+ * are both barriers of dependency. */
+ continue;
+ }
+ from_id->tag |= data->tag;
+ LibOverrideGroupTagData sub_data = *data;
+ sub_data.id_root = from_id;
+ lib_override_hierarchy_dependencies_recursive_tag_from(&sub_data);
+ }
+}
+
/* Tag all IDs in dependency relationships within an override hierarchy/group.
*
* Requires existing `Main.relations`.
@@ -703,13 +748,13 @@ static bool lib_override_hierarchy_dependencies_recursive_tag(LibOverrideGroupTa
BLI_ghash_lookup(bmain->relations->relations_from_pointers, id));
BLI_assert(entry != nullptr);
- if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED) {
+ if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_TO) {
/* This ID has already been processed. */
return (*(uint *)&id->tag & data->tag) != 0;
}
/* This way we won't process again that ID, should we encounter it again through another
* relationship hierarchy. */
- entry->tags |= MAINIDRELATIONS_ENTRY_TAGS_PROCESSED;
+ entry->tags |= MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_TO;
for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != nullptr;
to_id_entry = to_id_entry->next) {
@@ -733,6 +778,15 @@ static bool lib_override_hierarchy_dependencies_recursive_tag(LibOverrideGroupTa
}
}
+ /* If the current ID is/has been tagged for override above, then check its reversed dependencies
+ * (i.e. IDs that depend on the current one).
+ *
+ * This will cover e.g. the case where user override an armature, and would expect the mesh
+ * object deformed by that armature to also be overridden. */
+ if ((*(uint *)&id->tag & data->tag) != 0) {
+ lib_override_hierarchy_dependencies_recursive_tag_from(data);
+ }
+
return (*(uint *)&id->tag & data->tag) != 0;
}
diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc
index 14bd6aa5b2f..a1ef2d2e6b5 100644
--- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc
@@ -791,7 +791,8 @@ Mesh *direct_mesh_boolean(Span<const Mesh *> meshes,
Span<Array<short>> material_remaps,
const bool use_self,
const bool hole_tolerant,
- const int boolean_mode)
+ const int boolean_mode,
+ Vector<int> *r_intersecting_edges)
{
#ifdef WITH_GMP
BLI_assert(meshes.size() == transforms.size());
@@ -828,7 +829,23 @@ Mesh *direct_mesh_boolean(Span<const Mesh *> meshes,
write_obj_mesh(m_out, "m_out");
}
- return imesh_to_mesh(&m_out, mim);
+ Mesh *result = imesh_to_mesh(&m_out, mim);
+
+ /* Store intersecting edge indices. */
+ if (r_intersecting_edges != nullptr) {
+ for (int fi : m_out.face_index_range()) {
+ const Face &face = *m_out.face(fi);
+ const MPoly &poly = result->mpoly[fi];
+ for (int corner_i : face.index_range()) {
+ if (face.is_intersect[corner_i]) {
+ int e_index = result->mloop[poly.loopstart + corner_i].e;
+ r_intersecting_edges->append(e_index);
+ }
+ }
+ }
+ }
+
+ return result;
#else // WITH_GMP
UNUSED_VARS(meshes,
transforms,
@@ -836,7 +853,8 @@ Mesh *direct_mesh_boolean(Span<const Mesh *> meshes,
target_transform,
use_self,
hole_tolerant,
- boolean_mode);
+ boolean_mode,
+ r_intersecting_edges);
return nullptr;
#endif // WITH_GMP
}
diff --git a/source/blender/blenkernel/intern/mesh_sample.cc b/source/blender/blenkernel/intern/mesh_sample.cc
index 7595c08a208..106c4c610ba 100644
--- a/source/blender/blenkernel/intern/mesh_sample.cc
+++ b/source/blender/blenkernel/intern/mesh_sample.cc
@@ -2,12 +2,15 @@
#include "BKE_attribute_access.hh"
#include "BKE_attribute_math.hh"
+#include "BKE_bvhutils.h"
#include "BKE_mesh_runtime.h"
#include "BKE_mesh_sample.hh"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "BLI_rand.hh"
+
namespace blender::bke::mesh_surface_sample {
template<typename T>
@@ -259,4 +262,173 @@ void MeshAttributeInterpolator::sample_attribute(const ReadAttributeLookup &src_
}
}
+int sample_surface_points_spherical(RandomNumberGenerator &rng,
+ const Mesh &mesh,
+ const Span<int> looptri_indices_to_sample,
+ const float3 &sample_pos,
+ const float sample_radius,
+ const float approximate_density,
+ Vector<float3> &r_bary_coords,
+ Vector<int> &r_looptri_indices,
+ Vector<float3> &r_positions)
+{
+ const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
+ BKE_mesh_runtime_looptri_len(&mesh)};
+
+ const float sample_radius_sq = pow2f(sample_radius);
+ const float sample_plane_area = M_PI * sample_radius_sq;
+ /* Used for switching between two triangle sampling strategies. */
+ const float area_threshold = sample_plane_area;
+
+ const int old_num = r_bary_coords.size();
+
+ for (const int looptri_index : looptri_indices_to_sample) {
+ const MLoopTri &looptri = looptris[looptri_index];
+
+ const float3 &v0 = mesh.mvert[mesh.mloop[looptri.tri[0]].v].co;
+ const float3 &v1 = mesh.mvert[mesh.mloop[looptri.tri[1]].v].co;
+ const float3 &v2 = mesh.mvert[mesh.mloop[looptri.tri[2]].v].co;
+
+ const float looptri_area = area_tri_v3(v0, v1, v2);
+
+ if (looptri_area < area_threshold) {
+ /* The triangle is small compared to the sample radius. Sample by generating random
+ * barycentric coordinates. */
+ const int amount = rng.round_probabilistic(approximate_density * looptri_area);
+ for ([[maybe_unused]] const int i : IndexRange(amount)) {
+ const float3 bary_coord = rng.get_barycentric_coordinates();
+ const float3 point_pos = attribute_math::mix3(bary_coord, v0, v1, v2);
+ const float dist_to_sample_sq = math::distance_squared(point_pos, sample_pos);
+ if (dist_to_sample_sq > sample_radius_sq) {
+ continue;
+ }
+
+ r_bary_coords.append(bary_coord);
+ r_looptri_indices.append(looptri_index);
+ r_positions.append(point_pos);
+ }
+ }
+ else {
+ /* The triangle is large compared to the sample radius. Sample by generating random points
+ * on the triangle plane within the sample radius. */
+ float3 normal;
+ normal_tri_v3(normal, v0, v1, v2);
+
+ float3 sample_pos_proj = sample_pos;
+ project_v3_plane(sample_pos_proj, normal, v0);
+
+ const float proj_distance_sq = math::distance_squared(sample_pos_proj, sample_pos);
+ const float sample_radius_factor_sq = 1.0f -
+ std::min(1.0f, proj_distance_sq / sample_radius_sq);
+ const float radius_proj_sq = sample_radius_sq * sample_radius_factor_sq;
+ const float radius_proj = std::sqrt(radius_proj_sq);
+ const float circle_area = M_PI * radius_proj;
+
+ const int amount = rng.round_probabilistic(approximate_density * circle_area);
+
+ const float3 axis_1 = math::normalize(v1 - v0) * radius_proj;
+ const float3 axis_2 = math::normalize(math::cross(axis_1, math::cross(axis_1, v2 - v0))) *
+ radius_proj;
+
+ for ([[maybe_unused]] const int i : IndexRange(amount)) {
+ const float r = std::sqrt(rng.get_float());
+ const float angle = rng.get_float() * 2.0f * M_PI;
+ const float x = r * std::cos(angle);
+ const float y = r * std::sin(angle);
+ const float3 point_pos = sample_pos_proj + axis_1 * x + axis_2 * y;
+ if (!isect_point_tri_prism_v3(point_pos, v0, v1, v2)) {
+ /* Sampled point is not in the triangle. */
+ continue;
+ }
+
+ float3 bary_coord;
+ interp_weights_tri_v3(bary_coord, v0, v1, v2, point_pos);
+
+ r_bary_coords.append(bary_coord);
+ r_looptri_indices.append(looptri_index);
+ r_positions.append(point_pos);
+ }
+ }
+ }
+ return r_bary_coords.size() - old_num;
+}
+
+int sample_surface_points_projected(
+ RandomNumberGenerator &rng,
+ const Mesh &mesh,
+ BVHTreeFromMesh &mesh_bvhtree,
+ const float2 &sample_pos_re,
+ const float sample_radius_re,
+ const FunctionRef<void(const float2 &pos_re, float3 &r_start, float3 &r_end)>
+ region_position_to_ray,
+ const bool front_face_only,
+ const int tries_num,
+ const int max_points,
+ Vector<float3> &r_bary_coords,
+ Vector<int> &r_looptri_indices,
+ Vector<float3> &r_positions)
+{
+ const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
+ BKE_mesh_runtime_looptri_len(&mesh)};
+
+ int point_count = 0;
+ for ([[maybe_unused]] const int _ : IndexRange(tries_num)) {
+ if (point_count == max_points) {
+ break;
+ }
+
+ const float r = sample_radius_re * std::sqrt(rng.get_float());
+ const float angle = rng.get_float() * 2.0f * M_PI;
+ float3 ray_start, ray_end;
+ const float2 pos_re = sample_pos_re + r * float2(std::cos(angle), std::sin(angle));
+ region_position_to_ray(pos_re, ray_start, ray_end);
+ const float3 ray_direction = math::normalize(ray_end - ray_start);
+
+ BVHTreeRayHit ray_hit;
+ ray_hit.dist = FLT_MAX;
+ ray_hit.index = -1;
+ BLI_bvhtree_ray_cast(mesh_bvhtree.tree,
+ ray_start,
+ ray_direction,
+ 0.0f,
+ &ray_hit,
+ mesh_bvhtree.raycast_callback,
+ &mesh_bvhtree);
+
+ if (ray_hit.index == -1) {
+ continue;
+ }
+
+ if (front_face_only) {
+ const float3 normal = ray_hit.no;
+ if (math::dot(ray_direction, normal) >= 0.0f) {
+ continue;
+ }
+ }
+
+ const int looptri_index = ray_hit.index;
+ const float3 pos = ray_hit.co;
+
+ const float3 bary_coords = compute_bary_coord_in_triangle(mesh, looptris[looptri_index], pos);
+
+ r_positions.append(pos);
+ r_bary_coords.append(bary_coords);
+ r_looptri_indices.append(looptri_index);
+ point_count++;
+ }
+ return point_count;
+}
+
+float3 compute_bary_coord_in_triangle(const Mesh &mesh,
+ const MLoopTri &looptri,
+ const float3 &position)
+{
+ const float3 &v0 = mesh.mvert[mesh.mloop[looptri.tri[0]].v].co;
+ const float3 &v1 = mesh.mvert[mesh.mloop[looptri.tri[1]].v].co;
+ const float3 &v2 = mesh.mvert[mesh.mloop[looptri.tri[2]].v].co;
+ float3 bary_coords;
+ interp_weights_tri_v3(bary_coords, v0, v1, v2, position);
+ return bary_coords;
+}
+
} // namespace blender::bke::mesh_surface_sample
diff --git a/source/blender/blenkernel/intern/mesh_tangent.c b/source/blender/blenkernel/intern/mesh_tangent.c
index c0b2b33c47c..a677a0d6ebb 100644
--- a/source/blender/blenkernel/intern/mesh_tangent.c
+++ b/source/blender/blenkernel/intern/mesh_tangent.c
@@ -167,7 +167,7 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh,
if (!loopuvs) {
BKE_reportf(reports,
RPT_ERROR,
- "Tangent space computation needs an UVMap, \"%s\" not found, aborting",
+ "Tangent space computation needs a UV Map, \"%s\" not found, aborting",
uvmap);
return;
}
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 8f54d71108a..10abb8f20df 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -252,12 +252,15 @@ static NlaStrip *find_active_strip_from_listbase(const NlaStrip *active_strip,
const ListBase /* NlaStrip */ *strips_source,
const ListBase /* NlaStrip */ *strips_dest)
{
+ BLI_assert_msg(BLI_listbase_count(strips_source) == BLI_listbase_count(strips_dest),
+ "Expecting the same number of source and destination strips");
+
NlaStrip *strip_dest = strips_dest->first;
LISTBASE_FOREACH (const NlaStrip *, strip_source, strips_source) {
if (strip_dest == NULL) {
- /* The tracks are assumed to have an equal number of strips, but this is not the case when
- * dragging multiple strips. The transform system merges the selected strips into one
- * meta-strip, reducing the number of strips in `track_dest`. */
+ /* The tracks are assumed to have an equal number of strips, but this is
+ * not the case. Not sure when this might happen, but it's better to not
+ * crash. */
break;
}
if (strip_source == active_strip) {
@@ -282,7 +285,9 @@ static NlaStrip *find_active_strip_from_listbase(const NlaStrip *active_strip,
return NULL;
}
-/* Set adt_dest->actstrip to the strip with the same index as adt_source->actstrip. */
+/* Set adt_dest->actstrip to the strip with the same index as
+ * adt_source->actstrip. Note that this always sets `adt_dest->actstrip`; sets
+ * to NULL when `adt_source->actstrip` cannot be found. */
static void update_active_strip(AnimData *adt_dest,
NlaTrack *track_dest,
const AnimData *adt_source,
@@ -298,6 +303,12 @@ static void update_active_strip(AnimData *adt_dest,
/* Set adt_dest->act_track to the track with the same index as adt_source->act_track. */
static void update_active_track(AnimData *adt_dest, const AnimData *adt_source)
{
+ adt_dest->act_track = NULL;
+ adt_dest->actstrip = NULL;
+ if (adt_source->act_track == NULL && adt_source->actstrip == NULL) {
+ return;
+ }
+
BLI_assert(BLI_listbase_count(&adt_source->nla_tracks) ==
BLI_listbase_count(&adt_dest->nla_tracks));
@@ -306,7 +317,11 @@ static void update_active_track(AnimData *adt_dest, const AnimData *adt_source)
if (track_source == adt_source->act_track) {
adt_dest->act_track = track_dest;
}
- update_active_strip(adt_dest, track_dest, adt_source, track_source);
+
+ /* Only search for the active strip if it hasn't been found yet. */
+ if (adt_dest->actstrip == NULL && adt_source->actstrip != NULL) {
+ update_active_strip(adt_dest, track_dest, adt_source, track_source);
+ }
track_dest = track_dest->next;
}
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 1ffc4a56a0e..e02d3b6486c 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -4836,6 +4836,7 @@ static void registerGeometryNodes()
register_node_type_geo_translate_instances();
register_node_type_geo_triangulate();
register_node_type_geo_viewer();
+ register_node_type_geo_volume_cube();
register_node_type_geo_volume_to_mesh();
}
diff --git a/source/blender/blenlib/BLI_generic_virtual_array.hh b/source/blender/blenlib/BLI_generic_virtual_array.hh
index 3fce2947d0d..985d914f4a4 100644
--- a/source/blender/blenlib/BLI_generic_virtual_array.hh
+++ b/source/blender/blenlib/BLI_generic_virtual_array.hh
@@ -934,15 +934,15 @@ template<typename T> inline GVArray::GVArray(const VArray<T> &varray)
if (varray.try_assign_GVArray(*this)) {
return;
}
- /* Need to check this before the span/single special cases, because otherwise we might loose
- * ownership to the referenced data when #varray goes out of scope. */
- if (varray.may_have_ownership()) {
- *this = GVArray::For<GVArrayImpl_For_VArray<T>>(varray);
- }
- else if (varray.is_single()) {
+ if (varray.is_single()) {
T value = varray.get_internal_single();
*this = GVArray::ForSingle(CPPType::get<T>(), varray.size(), &value);
}
+ /* Need to check this before the span special case, because otherwise we might loose
+ * ownership to the referenced data when #varray goes out of scope. */
+ else if (varray.may_have_ownership()) {
+ *this = GVArray::For<GVArrayImpl_For_VArray<T>>(varray);
+ }
else if (varray.is_span()) {
Span<T> data = varray.get_internal_span();
*this = GVArray::ForSpan(data);
@@ -962,14 +962,14 @@ template<typename T> inline VArray<T> GVArray::typed() const
if (this->try_assign_VArray(varray)) {
return varray;
}
- if (this->may_have_ownership()) {
- return VArray<T>::template For<VArrayImpl_For_GVArray<T>>(*this);
- }
if (this->is_single()) {
T value;
this->get_internal_single(&value);
return VArray<T>::ForSingle(value, this->size());
}
+ if (this->may_have_ownership()) {
+ return VArray<T>::template For<VArrayImpl_For_GVArray<T>>(*this);
+ }
if (this->is_span()) {
const Span<T> span = this->get_internal_span().typed<T>();
return VArray<T>::ForSpan(span);
diff --git a/source/blender/blenlib/BLI_math_base.hh b/source/blender/blenlib/BLI_math_base.hh
index 3057e30dc03..b15179f75b6 100644
--- a/source/blender/blenlib/BLI_math_base.hh
+++ b/source/blender/blenlib/BLI_math_base.hh
@@ -44,6 +44,16 @@ template<typename T> inline T max(const T &a, const T &b)
return std::max(a, b);
}
+template<typename T> inline void max_inplace(T &a, const T &b)
+{
+ a = math::max(a, b);
+}
+
+template<typename T> inline void min_inplace(T &a, const T &b)
+{
+ a = math::min(a, b);
+}
+
template<typename T> inline T clamp(const T &a, const T &min, const T &max)
{
return std::clamp(a, min, max);
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 109230ebfa7..95b4987596e 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -445,6 +445,7 @@ if(WITH_GTESTS)
tests/BLI_index_range_test.cc
tests/BLI_inplace_priority_queue_test.cc
tests/BLI_kdopbvh_test.cc
+ tests/BLI_kdtree_test.cc
tests/BLI_length_parameterize_test.cc
tests/BLI_linear_allocator_test.cc
tests/BLI_linklist_lockfree_test.cc
diff --git a/source/blender/blenlib/intern/kdtree_impl.h b/source/blender/blenlib/intern/kdtree_impl.h
index d9ae826093c..6614f1bf964 100644
--- a/source/blender/blenlib/intern/kdtree_impl.h
+++ b/source/blender/blenlib/intern/kdtree_impl.h
@@ -927,6 +927,14 @@ int BLI_kdtree_nd_(calc_duplicates_fast)(const KDTree *tree,
/** \name BLI_kdtree_3d_deduplicate
* \{ */
+static int kdtree_cmp_bool(const bool a, const bool b)
+{
+ if (a == b) {
+ return 0;
+ }
+ return b ? -1 : 1;
+}
+
static int kdtree_node_cmp_deduplicate(const void *n0_p, const void *n1_p)
{
const KDTreeNode *n0 = n0_p;
@@ -939,17 +947,16 @@ static int kdtree_node_cmp_deduplicate(const void *n0_p, const void *n1_p)
return 1;
}
}
- /* Sort by pointer so the first added will be used.
- * assignment below ignores const correctness,
- * however the values aren't used for sorting and are to be discarded. */
- if (n0 < n1) {
- ((KDTreeNode *)n1)->d = KD_DIMS; /* tag invalid */
- return -1;
- }
- else {
- ((KDTreeNode *)n0)->d = KD_DIMS; /* tag invalid */
- return 1;
+
+ if (n0->d != KD_DIMS && n1->d != KD_DIMS) {
+ /* Two nodes share identical `co`
+ * Both are still valid.
+ * Cast away `const` and tag one of them as invalid. */
+ ((KDTreeNode *)n1)->d = KD_DIMS;
}
+
+ /* Keep sorting until each unique value has one and only one valid node. */
+ return kdtree_cmp_bool(n0->d == KD_DIMS, n1->d == KD_DIMS);
}
/**
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index 94efb0dd9e7..0cbf62cce03 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -363,6 +363,10 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w,
int BLI_wcwidth(char32_t ucs)
{
+ /* Treat private use areas (icon fonts), symbols, and emoticons as double-width. */
+ if (ucs >= 0xf0000 || (ucs >= 0xe000 && ucs < 0xf8ff) || (ucs >= 0x1f300 && ucs < 0x1fbff)) {
+ return 2;
+ }
return mk_wcwidth(ucs);
}
diff --git a/source/blender/blenlib/tests/BLI_kdtree_test.cc b/source/blender/blenlib/tests/BLI_kdtree_test.cc
new file mode 100644
index 00000000000..f8675ef332d
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_kdtree_test.cc
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#include "testing/testing.h"
+
+#include "BLI_kdtree.h"
+
+#include <math.h>
+
+/* -------------------------------------------------------------------- */
+/* Tests */
+
+static void standard_test()
+{
+ for (int tree_size = 30; tree_size < 500; tree_size++) {
+ int tree_index = 0;
+ KDTree_1d *tree = BLI_kdtree_1d_new(tree_size);
+ int mask = tree_size & 31;
+ bool occupied[32] = {false};
+
+ for (int i = 0; i < tree_size; i++) {
+ int index = i & mask;
+ occupied[index] = true;
+ float value = fmodf(index * 7.121f, 0.6037f); /* Co-prime. */
+ float key[1] = {value};
+ BLI_kdtree_1d_insert(tree, tree_index++, key);
+ }
+ int expected = 0;
+ for (int j = 0; j < 32; j++) {
+ if (occupied[j]) {
+ expected++;
+ }
+ }
+
+ int dedup_count = BLI_kdtree_1d_deduplicate(tree);
+ EXPECT_EQ(dedup_count, expected);
+ BLI_kdtree_1d_free(tree);
+ }
+}
+
+static void deduplicate_test()
+{
+ for (int tree_size = 1; tree_size < 40; tree_size++) {
+ int tree_index = 0;
+ KDTree_1d *tree = BLI_kdtree_1d_new(tree_size);
+ for (int i = 0; i < tree_size; i++) {
+ float key[1] = {1.0f};
+ BLI_kdtree_1d_insert(tree, tree_index++, key);
+ }
+ int dedup_count = BLI_kdtree_1d_deduplicate(tree);
+ EXPECT_EQ(dedup_count, 1);
+ BLI_kdtree_1d_free(tree);
+ }
+}
+
+TEST(kdtree, Standard)
+{
+ standard_test();
+}
+
+TEST(kdtree, Deduplicate)
+{
+ deduplicate_test();
+}
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index eafb27f9758..e542bc46a28 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -4102,7 +4102,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
if (md->type == eModifierType_DataTransfer) {
- /* Now datatransfer's mix factor is multiplied with weights when any,
+ /* Now data-transfer's mix factor is multiplied with weights when any,
* instead of being ignored,
* we need to take care of that to keep 'old' files compatible. */
DataTransferModifierData *dtmd = (DataTransferModifierData *)md;
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index 97b414d4b4a..5af42f9f1f6 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -3084,6 +3084,18 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
FOREACH_NODETREE_END;
}
+ if (!MAIN_VERSION_ATLEAST(bmain, 303, 2)) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ if (sl->spacetype == SPACE_CLIP) {
+ ((SpaceClip *)sl)->mask_info.blend_factor = 1.0;
+ }
+ }
+ }
+ }
+ }
+
/**
* Versioning code until next subversion bump goes here.
*
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index f65976ee55f..91b2f509a7f 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -184,6 +184,7 @@ static void blo_update_defaults_screen(bScreen *screen,
else if (area->spacetype == SPACE_CLIP) {
SpaceClip *sclip = area->spacedata.first;
sclip->around = V3D_AROUND_CENTER_MEDIAN;
+ sclip->mask_info.blend_factor = 0.7f;
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_bloom.c b/source/blender/draw/engines/eevee/eevee_bloom.c
index d12ce7213f9..4528027a9ea 100644
--- a/source/blender/draw/engines/eevee/eevee_bloom.c
+++ b/source/blender/draw/engines/eevee/eevee_bloom.c
@@ -125,7 +125,8 @@ static DRWShadingGroup *eevee_create_bloom_pass(const char *name,
struct GPUShader *sh,
DRWPass **pass,
bool upsample,
- bool resolve)
+ bool resolve,
+ bool resolve_add_base)
{
struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
@@ -141,7 +142,7 @@ static DRWShadingGroup *eevee_create_bloom_pass(const char *name,
}
if (resolve) {
DRW_shgroup_uniform_vec3(grp, "bloomColor", effects->bloom_color, 1);
- DRW_shgroup_uniform_bool_copy(grp, "bloomAddBase", true);
+ DRW_shgroup_uniform_bool_copy(grp, "bloomAddBase", resolve_add_base);
}
return grp;
@@ -193,18 +194,21 @@ void EEVEE_bloom_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *ved
EEVEE_shaders_bloom_downsample_get(use_antiflicker),
&psl->bloom_downsample_first,
false,
+ false,
false);
eevee_create_bloom_pass("Bloom Downsample",
effects,
EEVEE_shaders_bloom_downsample_get(false),
&psl->bloom_downsample,
false,
+ false,
false);
eevee_create_bloom_pass("Bloom Upsample",
effects,
EEVEE_shaders_bloom_upsample_get(use_highres),
&psl->bloom_upsample,
true,
+ false,
false);
grp = eevee_create_bloom_pass("Bloom Blit",
@@ -212,6 +216,7 @@ void EEVEE_bloom_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *ved
EEVEE_shaders_bloom_blit_get(use_antiflicker),
&psl->bloom_blit,
false,
+ false,
false);
DRW_shgroup_uniform_vec4(grp, "curveThreshold", effects->bloom_curve_threshold, 1);
DRW_shgroup_uniform_float(grp, "clampIntensity", &effects->bloom_clamp, 1);
@@ -221,6 +226,7 @@ void EEVEE_bloom_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *ved
EEVEE_shaders_bloom_resolve_get(use_highres),
&psl->bloom_resolve,
true,
+ true,
true);
}
}
@@ -304,13 +310,13 @@ void EEVEE_bloom_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->bloom_accum)});
/* Create Pass and shgroup. */
- DRWShadingGroup *grp = eevee_create_bloom_pass("Bloom Accumulate",
- effects,
- EEVEE_shaders_bloom_resolve_get(use_highres),
- &psl->bloom_accum_ps,
- true,
- true);
- DRW_shgroup_uniform_bool_copy(grp, "bloomAddBase", false);
+ eevee_create_bloom_pass("Bloom Accumulate",
+ effects,
+ EEVEE_shaders_bloom_resolve_get(use_highres),
+ &psl->bloom_accum_ps,
+ true,
+ true,
+ false);
}
void EEVEE_bloom_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c
index 6fd5d97089d..5709621fc05 100644
--- a/source/blender/draw/engines/eevee/eevee_shaders.c
+++ b/source/blender/draw/engines/eevee/eevee_shaders.c
@@ -718,7 +718,7 @@ GPUShader *EEVEE_shaders_cryptomatte_sh_get(bool is_hair)
if (e_data.cryptomatte_sh[index] == NULL) {
DynStr *ds = BLI_dynstr_new();
BLI_dynstr_append(ds, SHADER_DEFINES);
- BLI_dynstr_append(ds, "#define attrib_load(a) \n");
+ BLI_dynstr_append(ds, "#define attrib_load() \n");
if (is_hair) {
BLI_dynstr_append(ds, "#define HAIR_SHADER\n");
}
diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_surface_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_surface_lib.glsl
index 0f5290a7c07..ffca97b6b8f 100644
--- a/source/blender/draw/engines/eevee/shaders/closure_eval_surface_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/closure_eval_surface_lib.glsl
@@ -181,6 +181,8 @@ Closure closure_eval(ClosureDiffuse diffuse, ClosureReflection reflection)
/* Glue with the old system. */
CLOSURE_VARS_DECLARE_2(Diffuse, Glossy);
+ /* WORKAROUND: This is to avoid regression in 3.2 and avoid messing with EEVEE-Next. */
+ in_common.occlusion = (diffuse.sss_radius.g == -1.0) ? diffuse.sss_radius.r : 1.0;
in_Diffuse_0.N = diffuse.N;
in_Diffuse_0.albedo = diffuse.color;
in_Glossy_1.N = reflection.N;
@@ -207,6 +209,8 @@ Closure closure_eval(ClosureDiffuse diffuse,
/* Glue with the old system. */
CLOSURE_VARS_DECLARE_3(Diffuse, Glossy, Glossy);
+ /* WORKAROUND: This is to avoid regression in 3.2 and avoid messing with EEVEE-Next. */
+ in_common.occlusion = (diffuse.sss_radius.g == -1.0) ? diffuse.sss_radius.r : 1.0;
in_Diffuse_0.N = diffuse.N;
in_Diffuse_0.albedo = diffuse.color;
in_Glossy_1.N = reflection.N;
diff --git a/source/blender/draw/intern/draw_attributes.cc b/source/blender/draw/intern/draw_attributes.cc
index 8fb4210901f..3f187aef8e6 100644
--- a/source/blender/draw/intern/draw_attributes.cc
+++ b/source/blender/draw/intern/draw_attributes.cc
@@ -65,9 +65,10 @@ bool drw_attributes_overlap(const DRW_Attributes *a, const DRW_Attributes *b)
}
DRW_AttributeRequest *drw_attributes_add_request(DRW_Attributes *attrs,
- eCustomDataType type,
- int layer,
- eAttrDomain domain)
+ const char *name,
+ const eCustomDataType type,
+ const int layer_index,
+ const eAttrDomain domain)
{
if (attrs->num_requests >= GPU_MAX_ATTR) {
return nullptr;
@@ -75,7 +76,8 @@ DRW_AttributeRequest *drw_attributes_add_request(DRW_Attributes *attrs,
DRW_AttributeRequest *req = &attrs->requests[attrs->num_requests];
req->cd_type = type;
- req->layer_index = layer;
+ BLI_strncpy(req->attribute_name, name, sizeof(req->attribute_name));
+ req->layer_index = layer_index;
req->domain = domain;
attrs->num_requests += 1;
return req;
diff --git a/source/blender/draw/intern/draw_attributes.h b/source/blender/draw/intern/draw_attributes.h
index 4f82f3b94e9..b577c6c4162 100644
--- a/source/blender/draw/intern/draw_attributes.h
+++ b/source/blender/draw/intern/draw_attributes.h
@@ -46,8 +46,9 @@ void drw_attributes_merge(DRW_Attributes *dst,
bool drw_attributes_overlap(const DRW_Attributes *a, const DRW_Attributes *b);
DRW_AttributeRequest *drw_attributes_add_request(DRW_Attributes *attrs,
- eCustomDataType type,
- int layer,
+ const char *name,
+ eCustomDataType data_type,
+ int layer_index,
eAttrDomain domain);
bool drw_custom_data_match_attribute(const CustomData *custom_data,
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc
index 00005fd7b4c..380736ef656 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.cc
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc
@@ -155,7 +155,7 @@ struct ExtractTaskData {
bool use_threading = false;
ExtractTaskData(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
ExtractorRunDatas *extractors,
MeshBufferList *mbuflist,
const bool use_threading)
@@ -193,7 +193,7 @@ static void extract_task_data_free(void *data)
* \{ */
BLI_INLINE void extract_init(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
ExtractorRunDatas &extractors,
MeshBufferList *mbuflist,
void *data_stack)
@@ -209,7 +209,7 @@ BLI_INLINE void extract_init(const MeshRenderData *mr,
}
BLI_INLINE void extract_finish(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
const ExtractorRunDatas &extractors,
void *data_stack)
{
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 0755d5967d5..4fa5813d476 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -156,11 +156,15 @@ struct GPUBatch *DRW_lattice_batch_cache_get_edit_verts(struct Lattice *lt);
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Hair
+/** \name Curves
* \{ */
int DRW_curves_material_count_get(struct Curves *curves);
+struct GPUBatch *DRW_curves_batch_cache_get_edit_points(struct Curves *curves);
+
+void DRW_curves_batch_cache_create_requested(struct Object *ob);
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -352,16 +356,6 @@ struct GPUBatch *DRW_particles_batch_cache_get_edit_tip_points(struct Object *ob
/** \} */
-/* -------------------------------------------------------------------- */
-/** \name Curves
- * \{ */
-
-struct GPUBatch *DRW_curves_batch_cache_get_edit_points(struct Curves *curves);
-
-void DRW_curves_batch_cache_create_requested(const struct Object *ob);
-
-/** \} */
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc
index 992ffe16a14..ee81f74ca26 100644
--- a/source/blender/draw/intern/draw_cache_impl_curves.cc
+++ b/source/blender/draw/intern/draw_cache_impl_curves.cc
@@ -87,13 +87,13 @@ static void curves_batch_cache_init(Curves &curves)
static void curves_discard_attributes(CurvesEvalCache &curves_cache)
{
- for (int i = 0; i < GPU_MAX_ATTR; i++) {
+ for (const int i : IndexRange(GPU_MAX_ATTR)) {
GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_attributes_buf[i]);
DRW_TEXTURE_FREE_SAFE(curves_cache.proc_attributes_tex[i]);
}
- for (int i = 0; i < MAX_HAIR_SUBDIV; i++) {
- for (int j = 0; j < GPU_MAX_ATTR; j++) {
+ for (const int i : IndexRange(MAX_HAIR_SUBDIV)) {
+ for (const int j : IndexRange(GPU_MAX_ATTR)) {
GPU_VERTBUF_DISCARD_SAFE(curves_cache.final[i].attributes_buf[j]);
DRW_TEXTURE_FREE_SAFE(curves_cache.final[i].attributes_tex[j]);
}
@@ -115,10 +115,10 @@ static void curves_batch_cache_clear_data(CurvesEvalCache &curves_cache)
DRW_TEXTURE_FREE_SAFE(curves_cache.strand_tex);
DRW_TEXTURE_FREE_SAFE(curves_cache.strand_seg_tex);
- for (int i = 0; i < MAX_HAIR_SUBDIV; i++) {
+ for (const int i : IndexRange(MAX_HAIR_SUBDIV)) {
GPU_VERTBUF_DISCARD_SAFE(curves_cache.final[i].proc_buf);
DRW_TEXTURE_FREE_SAFE(curves_cache.final[i].proc_tex);
- for (int j = 0; j < MAX_THICKRES; j++) {
+ for (const int j : IndexRange(MAX_THICKRES)) {
GPU_BATCH_DISCARD_SAFE(curves_cache.final[i].proc_hairs[j]);
}
}
@@ -184,7 +184,7 @@ void DRW_curves_batch_cache_free_old(Curves *curves, int ctime)
bool do_discard = false;
- for (int i = 0; i < MAX_HAIR_SUBDIV; i++) {
+ for (const int i : IndexRange(MAX_HAIR_SUBDIV)) {
CurvesEvalFinalCache &final_cache = cache->curves_cache.final[i];
if (drw_attributes_overlap(&final_cache.attr_used_over_time, &final_cache.attr_used)) {
@@ -515,48 +515,28 @@ static bool curves_ensure_attributes(const Curves &curves,
ListBase gpu_attrs = GPU_material_attributes(gpu_material);
LISTBASE_FOREACH (GPUMaterialAttribute *, gpu_attr, &gpu_attrs) {
const char *name = gpu_attr->name;
- eCustomDataType type = static_cast<eCustomDataType>(gpu_attr->type);
- int layer = -1;
- eAttrDomain domain;
- if (drw_custom_data_match_attribute(cd_curve, name, &layer, &type)) {
+ int layer_index;
+ eCustomDataType type;
+ eAttrDomain domain;
+ if (drw_custom_data_match_attribute(cd_curve, name, &layer_index, &type)) {
domain = ATTR_DOMAIN_CURVE;
}
- else if (drw_custom_data_match_attribute(cd_point, name, &layer, &type)) {
+ else if (drw_custom_data_match_attribute(cd_point, name, &layer_index, &type)) {
domain = ATTR_DOMAIN_POINT;
}
else {
continue;
}
- switch (type) {
- case CD_PROP_BOOL:
- case CD_PROP_INT8:
- case CD_PROP_INT32:
- case CD_PROP_FLOAT:
- case CD_PROP_FLOAT2:
- case CD_PROP_FLOAT3:
- case CD_PROP_COLOR: {
- if (layer != -1) {
- DRW_AttributeRequest *req = drw_attributes_add_request(
- &attrs_needed, (eCustomDataType)type, layer, domain);
- if (req) {
- BLI_strncpy(req->attribute_name, name, sizeof(req->attribute_name));
- }
- }
- break;
- }
- default:
- break;
- }
+ drw_attributes_add_request(&attrs_needed, name, type, layer_index, domain);
}
CurvesEvalFinalCache &final_cache = cache.curves_cache.final[subdiv];
- const bool attr_overlap = drw_attributes_overlap(&final_cache.attr_used, &attrs_needed);
- if (attr_overlap == false) {
+ if (!drw_attributes_overlap(&final_cache.attr_used, &attrs_needed)) {
/* Some new attributes have been added, free all and start over. */
- for (int i = 0; i < GPU_MAX_ATTR; i++) {
+ for (const int i : IndexRange(GPU_MAX_ATTR)) {
GPU_VERTBUF_DISCARD_SAFE(cache.curves_cache.proc_attributes_buf[i]);
DRW_TEXTURE_FREE_SAFE(cache.curves_cache.proc_attributes_tex[i]);
}
@@ -566,7 +546,7 @@ static bool curves_ensure_attributes(const Curves &curves,
bool need_tf_update = false;
- for (int i = 0; i < final_cache.attr_used.num_requests; i++) {
+ for (const int i : IndexRange(final_cache.attr_used.num_requests)) {
const DRW_AttributeRequest &request = final_cache.attr_used.requests[i];
if (cache.curves_cache.proc_attributes_buf[i] != nullptr) {
@@ -638,7 +618,7 @@ GPUBatch *DRW_curves_batch_cache_get_edit_points(Curves *curves)
return DRW_batch_request(&cache.edit_points);
}
-void DRW_curves_batch_cache_create_requested(const Object *ob)
+void DRW_curves_batch_cache_create_requested(Object *ob)
{
Curves *curves = static_cast<Curves *>(ob->data);
CurvesBatchCache &cache = curves_batch_cache_get(*curves);
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc
index 7c02ee2c033..e93b1a66b66 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.cc
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc
@@ -574,7 +574,7 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object,
}
if (layer != -1 && domain.has_value()) {
- drw_attributes_add_request(attributes, type, layer, *domain);
+ drw_attributes_add_request(attributes, name, type, layer, *domain);
}
break;
}
@@ -585,7 +585,7 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object,
case CD_PROP_FLOAT:
case CD_PROP_FLOAT2: {
if (layer != -1 && domain.has_value()) {
- drw_attributes_add_request(attributes, type, layer, *domain);
+ drw_attributes_add_request(attributes, name, type, layer, *domain);
}
break;
}
diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc
index b37a420b555..afec92a894d 100644
--- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc
+++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc
@@ -1204,8 +1204,8 @@ struct DRWSubdivUboStorage {
* of out of bond accesses as compute dispatch are of fixed size. */
uint total_dispatch_size;
- int _pad0;
- int _pad2;
+ int is_edit_mode;
+ int use_hide;
int _pad3;
};
@@ -1236,6 +1236,8 @@ static void draw_subdiv_init_ubo_storage(const DRWSubdivCache *cache,
ubo->coarse_face_hidden_mask = SUBDIV_COARSE_FACE_FLAG_HIDDEN_MASK;
ubo->coarse_face_loopstart_mask = SUBDIV_COARSE_FACE_LOOP_START_MASK;
ubo->total_dispatch_size = total_dispatch_size;
+ ubo->is_edit_mode = cache->is_edit_mode;
+ ubo->use_hide = cache->use_hide;
}
static void draw_subdiv_ubo_update_and_bind(const DRWSubdivCache *cache,
@@ -2004,7 +2006,7 @@ static void draw_subdiv_cache_ensure_mat_offsets(DRWSubdivCache *cache,
static bool draw_subdiv_create_requested_buffers(Object *ob,
Mesh *mesh,
- struct MeshBatchCache *batch_cache,
+ MeshBatchCache *batch_cache,
MeshBufferCache *mbc,
const bool is_editmode,
const bool is_paint_mode,
@@ -2083,6 +2085,12 @@ static bool draw_subdiv_create_requested_buffers(Object *ob,
MeshRenderData *mr = mesh_render_data_create(
ob, mesh, is_editmode, is_paint_mode, is_mode_active, obmat, do_final, do_uvedit, ts);
mr->use_hide = use_hide;
+ draw_cache->use_hide = use_hide;
+
+ /* Used for setting loop normals flags. Mapped extraction is only used during edit mode.
+ * See comments in #extract_lnor_iter_poly_mesh.
+ */
+ draw_cache->is_edit_mode = mr->edit_bmesh != nullptr;
draw_subdiv_cache_update_extra_coarse_face_data(draw_cache, mesh_eval, mr);
@@ -2195,7 +2203,7 @@ static OpenSubdiv_EvaluatorCache *g_evaluator_cache = nullptr;
void DRW_create_subdivision(Object *ob,
Mesh *mesh,
- struct MeshBatchCache *batch_cache,
+ MeshBatchCache *batch_cache,
MeshBufferCache *mbc,
const bool is_editmode,
const bool is_paint_mode,
diff --git a/source/blender/draw/intern/draw_subdivision.h b/source/blender/draw/intern/draw_subdivision.h
index 2d9f4713feb..ef580fc116a 100644
--- a/source/blender/draw/intern/draw_subdivision.h
+++ b/source/blender/draw/intern/draw_subdivision.h
@@ -177,6 +177,10 @@ typedef struct DRWSubdivCache {
/* UBO to store settings for the various compute shaders. */
struct GPUUniformBuf *ubo;
+
+ /* Extra flags, passed to the UBO. */
+ bool is_edit_mode;
+ bool use_hide;
} DRWSubdivCache;
/* Only frees the data of the cache, caller is responsible to free the cache itself if necessary.
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc
index 9824602b129..2ff093d0bd8 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc
@@ -22,7 +22,7 @@ struct MeshExtract_EditUvElem_Data {
};
static void extract_edituv_tris_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *UNUSED(ibo),
void *tls_data)
{
@@ -69,7 +69,7 @@ static void extract_edituv_tris_iter_looptri_mesh(const MeshRenderData *mr,
}
static void extract_edituv_tris_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *_data)
{
@@ -142,7 +142,7 @@ static void extract_edituv_tris_iter_subdiv_mesh(const DRWSubdivCache *UNUSED(su
static void extract_edituv_tris_finish_subdiv(const struct DRWSubdivCache *UNUSED(subdiv_cache),
const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *_data)
{
@@ -176,7 +176,7 @@ constexpr MeshExtract create_extractor_edituv_tris()
* \{ */
static void extract_edituv_lines_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *UNUSED(ibo),
void *tls_data)
{
@@ -236,7 +236,7 @@ static void extract_edituv_lines_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_edituv_lines_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *_data)
{
@@ -307,7 +307,7 @@ static void extract_edituv_lines_iter_subdiv_mesh(const DRWSubdivCache *subdiv_c
static void extract_edituv_lines_finish_subdiv(const struct DRWSubdivCache *UNUSED(subdiv_cache),
const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *_data)
{
@@ -341,7 +341,7 @@ constexpr MeshExtract create_extractor_edituv_lines()
* \{ */
static void extract_edituv_points_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *UNUSED(ibo),
void *tls_data)
{
@@ -394,7 +394,7 @@ static void extract_edituv_points_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_edituv_points_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *_data)
{
@@ -459,7 +459,7 @@ static void extract_edituv_points_iter_subdiv_mesh(const DRWSubdivCache *subdiv_
static void extract_edituv_points_finish_subdiv(const struct DRWSubdivCache *UNUSED(subdiv_cache),
const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *_data)
{
@@ -493,7 +493,7 @@ constexpr MeshExtract create_extractor_edituv_points()
* \{ */
static void extract_edituv_fdots_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *UNUSED(ibo),
void *tls_data)
{
@@ -557,7 +557,7 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_edituv_fdots_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *_data)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc
index 4eebea1b79f..cc0b383f12b 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc
@@ -15,7 +15,7 @@ namespace blender::draw {
* \{ */
static void extract_fdots_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *UNUSED(buf),
void *tls_data)
{
@@ -68,7 +68,7 @@ static void extract_fdots_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_fdots_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *_userdata)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc
index 4e89b34c0a0..51d98d1ff26 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc
@@ -18,7 +18,7 @@ namespace blender::draw {
* \{ */
static void extract_lines_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *UNUSED(buf),
void *tls_data)
{
@@ -132,7 +132,7 @@ static void extract_lines_task_reduce(void *_userdata_to, void *_userdata_from)
}
static void extract_lines_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *data)
{
@@ -143,7 +143,7 @@ static void extract_lines_finish(const MeshRenderData *UNUSED(mr),
static void extract_lines_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buffer,
void *UNUSED(data))
{
@@ -229,7 +229,7 @@ constexpr MeshExtract create_extractor_lines()
/** \name Extract Lines and Loose Edges Sub Buffer
* \{ */
-static void extract_lines_loose_subbuffer(const MeshRenderData *mr, struct MeshBatchCache *cache)
+static void extract_lines_loose_subbuffer(const MeshRenderData *mr, MeshBatchCache *cache)
{
BLI_assert(cache->final.buff.ibo.lines);
/* Multiply by 2 because these are edges indices. */
@@ -241,7 +241,7 @@ static void extract_lines_loose_subbuffer(const MeshRenderData *mr, struct MeshB
}
static void extract_lines_with_lines_loose_finish(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buf,
void *data)
{
@@ -253,7 +253,7 @@ static void extract_lines_with_lines_loose_finish(const MeshRenderData *mr,
static void extract_lines_with_lines_loose_finish_subdiv(const struct DRWSubdivCache *subdiv_cache,
const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *UNUSED(buf),
void *UNUSED(_data))
{
@@ -292,7 +292,7 @@ constexpr MeshExtract create_extractor_lines_with_lines_loose()
* \{ */
static void extract_lines_loose_only_init(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buf,
void *UNUSED(tls_data))
{
@@ -303,7 +303,7 @@ static void extract_lines_loose_only_init(const MeshRenderData *mr,
static void extract_lines_loose_only_init_subdiv(const DRWSubdivCache *UNUSED(subdiv_cache),
const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buffer,
void *UNUSED(data))
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc
index 9ba9453dada..c2cfb66ec28 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc
@@ -42,7 +42,7 @@ static void line_adjacency_data_init(MeshExtract_LineAdjacency_Data *data,
}
static void extract_lines_adjacency_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *UNUSED(buf),
void *tls_data)
{
@@ -132,7 +132,7 @@ static void extract_lines_adjacency_iter_looptri_mesh(const MeshRenderData *mr,
}
static void extract_lines_adjacency_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buf,
void *_data)
{
@@ -166,7 +166,7 @@ static void extract_lines_adjacency_finish(const MeshRenderData *UNUSED(mr),
static void extract_lines_adjacency_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *UNUSED(buf),
void *_data)
{
@@ -222,7 +222,7 @@ static void extract_lines_adjacency_iter_subdiv_mesh(const DRWSubdivCache *subdi
static void extract_lines_adjacency_finish_subdiv(const DRWSubdivCache *UNUSED(subdiv_cache),
const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buf,
void *_data)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc
index 713a533492f..11c71d61775 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc
@@ -26,7 +26,7 @@ struct MeshExtract_LinePaintMask_Data {
};
static void extract_lines_paint_mask_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *UNUSED(ibo),
void *tls_data)
{
@@ -78,7 +78,7 @@ static void extract_lines_paint_mask_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_lines_paint_mask_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *_data)
{
@@ -126,7 +126,8 @@ static void extract_lines_paint_mask_iter_subdiv_mesh(const DRWSubdivCache *subd
if (!((mr->use_hide && (me->flag & ME_HIDE)) ||
((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->e_origindex) &&
(mr->e_origindex[coarse_edge_index] == ORIGINDEX_NONE)))) {
- const uint ml_index_other = (loop_idx == end_loop_idx) ? start_loop_idx : loop_idx + 1;
+ const uint ml_index_other = (loop_idx == (end_loop_idx - 1)) ? start_loop_idx :
+ loop_idx + 1;
if (coarse_quad->flag & ME_FACE_SEL) {
if (BLI_BITMAP_TEST_AND_SET_ATOMIC(data->select_map, coarse_edge_index)) {
/* Hide edge as it has more than 2 selected loop. */
@@ -154,7 +155,7 @@ static void extract_lines_paint_mask_iter_subdiv_mesh(const DRWSubdivCache *subd
static void extract_lines_paint_mask_finish_subdiv(
const struct DRWSubdivCache *UNUSED(subdiv_cache),
const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buf,
void *_data)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc
index e746b37fd30..f7c5505422b 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc
@@ -19,7 +19,7 @@ namespace blender::draw {
* \{ */
static void extract_points_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *UNUSED(buf),
void *tls_data)
{
@@ -131,7 +131,7 @@ static void extract_points_task_reduce(void *_userdata_to, void *_userdata_from)
}
static void extract_points_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *_userdata)
{
@@ -142,7 +142,7 @@ static void extract_points_finish(const MeshRenderData *UNUSED(mr),
static void extract_points_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *UNUSED(buffer),
void *data)
{
@@ -285,7 +285,7 @@ static void extract_points_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
static void extract_points_finish_subdiv(const DRWSubdivCache *UNUSED(subdiv_cache),
const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *_userdata)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
index 4c8d1d0002a..9fc18620d11 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
@@ -25,7 +25,7 @@ static void extract_tris_mat_task_reduce(void *_userdata_to, void *_userdata_fro
* \{ */
static void extract_tris_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *UNUSED(ibo),
void *tls_data)
{
@@ -81,7 +81,7 @@ static void extract_tris_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_tris_finish(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buf,
void *_data)
{
@@ -111,7 +111,7 @@ static void extract_tris_finish(const MeshRenderData *mr,
static void extract_tris_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buffer,
void *UNUSED(data))
{
@@ -157,7 +157,7 @@ constexpr MeshExtract create_extractor_tris()
* \{ */
static void extract_tris_single_mat_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *UNUSED(ibo),
void *tls_data)
{
@@ -199,7 +199,7 @@ static void extract_tris_single_mat_iter_looptri_mesh(const MeshRenderData *mr,
}
static void extract_tris_single_mat_finish(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buf,
void *_data)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc
index fb6b5e1904b..ff86bc768a3 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc
@@ -120,8 +120,7 @@ static GPUVertCompType get_comp_type_for_type(eCustomDataType type)
}
}
-static void init_vbo_for_attribute(const MeshRenderData *mr,
- GPUVertBuf *vbo,
+static void init_vbo_for_attribute(GPUVertBuf *vbo,
const DRW_AttributeRequest &request,
bool build_on_device,
uint32_t len)
@@ -132,11 +131,8 @@ static void init_vbo_for_attribute(const MeshRenderData *mr,
/* We should not be here if the attribute type is not supported. */
BLI_assert(comp_size != 0);
- const CustomData *custom_data = get_custom_data_for_domain(mr, request.domain);
char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
- const char *layer_name = CustomData_get_layer_name(
- custom_data, request.cd_type, request.layer_index);
- GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
+ GPU_vertformat_safe_attr_name(request.attribute_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
/* Attributes use auto-name. */
BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name);
@@ -258,18 +254,15 @@ static void extract_attr_generic(const MeshRenderData *mr,
}
}
-static void extract_attr_init(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
- void *buf,
- void *UNUSED(tls_data),
- int index)
+static void extract_attr_init(
+ const MeshRenderData *mr, MeshBatchCache *cache, void *buf, void *UNUSED(tls_data), int index)
{
const DRW_Attributes *attrs_used = &cache->attr_used;
const DRW_AttributeRequest &request = attrs_used->requests[index];
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
- init_vbo_for_attribute(mr, vbo, request, false, static_cast<uint32_t>(mr->loop_len));
+ init_vbo_for_attribute(vbo, request, false, static_cast<uint32_t>(mr->loop_len));
/* TODO(@kevindietrich): float3 is used for scalar attributes as the implicit conversion done by
* OpenGL to vec4 for a scalar `s` will produce a `vec4(s, 0, 0, 1)`. However, following the
@@ -350,7 +343,7 @@ static void extract_attr_init_subdiv(const DRWSubdivCache *subdiv_cache,
}
GPUVertBuf *dst_buffer = static_cast<GPUVertBuf *>(buffer);
- init_vbo_for_attribute(mr, dst_buffer, request, true, subdiv_cache->num_subdiv_loops);
+ init_vbo_for_attribute(dst_buffer, request, true, subdiv_cache->num_subdiv_loops);
/* Ensure data is uploaded properly. */
GPU_vertbuf_tag_dirty(src_data);
@@ -364,13 +357,13 @@ static void extract_attr_init_subdiv(const DRWSubdivCache *subdiv_cache,
* extract. The overall API does not allow us to pass this in a convenient way. */
#define EXTRACT_INIT_WRAPPER(index) \
static void extract_attr_init##index( \
- const MeshRenderData *mr, struct MeshBatchCache *cache, void *buf, void *tls_data) \
+ const MeshRenderData *mr, MeshBatchCache *cache, void *buf, void *tls_data) \
{ \
extract_attr_init(mr, cache, buf, tls_data, index); \
} \
static void extract_attr_init_subdiv##index(const DRWSubdivCache *subdiv_cache, \
const MeshRenderData *mr, \
- struct MeshBatchCache *cache, \
+ MeshBatchCache *cache, \
void *buf, \
void *tls_data) \
{ \
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc
index a11f740239a..eb6e800023a 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc
@@ -43,7 +43,7 @@ static float loop_edge_factor_get(const float f_no[3],
}
static void extract_edge_fac_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *tls_data)
{
@@ -167,7 +167,7 @@ static void extract_edge_fac_iter_ledge_mesh(const MeshRenderData *mr,
}
static void extract_edge_fac_finish(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *_data)
{
@@ -218,7 +218,7 @@ static GPUVertFormat *get_subdiv_edge_fac_format()
static void extract_edge_fac_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buffer,
void *UNUSED(data))
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc
index 3bb706e82cd..27fd6546b8c 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc
@@ -112,7 +112,7 @@ static GPUVertFormat *get_edit_data_format()
}
static void extract_edit_data_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *tls_data)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc
index 6d54fce2a0d..0b9043e3289 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc
@@ -43,7 +43,7 @@ static void extract_edituv_data_init_common(const MeshRenderData *mr,
}
static void extract_edituv_data_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *tls_data)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc
index 5d6dd14b57a..969ff9f6f09 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc
@@ -74,7 +74,7 @@ static void edituv_get_edituv_stretch_angle(float auv[2][2],
}
static void extract_edituv_stretch_angle_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *tls_data)
{
@@ -212,7 +212,7 @@ static GPUVertFormat *get_edituv_stretch_angle_format_subdiv()
static void extract_edituv_stretch_angle_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buffer,
void *UNUSED(tls_data))
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc
index 70dcc24f946..2bb786303c4 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc
@@ -20,7 +20,7 @@ namespace blender::draw {
* \{ */
static void extract_edituv_stretch_area_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *UNUSED(tls_data))
{
@@ -89,7 +89,7 @@ static void compute_area_ratio(const MeshRenderData *mr,
}
static void extract_edituv_stretch_area_finish(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buf,
void *UNUSED(data))
{
@@ -131,7 +131,7 @@ static void extract_edituv_stretch_area_finish(const MeshRenderData *mr,
static void extract_edituv_stretch_area_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buffer,
void *UNUSED(data))
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc
index 64bec0adad4..27d1975d67b 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc
@@ -21,7 +21,7 @@ struct MeshExtract_EditUVFdotData_Data {
};
static void extract_fdots_edituv_data_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *tls_data)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_nor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_nor.cc
index 8d189db9f12..c2af7f2c9bd 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_nor.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_nor.cc
@@ -19,7 +19,7 @@ namespace blender::draw {
#define NOR_AND_FLAG_HIDDEN -2
static void extract_fdots_nor_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *UNUSED(tls_data))
{
@@ -34,7 +34,7 @@ static void extract_fdots_nor_init(const MeshRenderData *mr,
}
static void extract_fdots_nor_finish(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *UNUSED(data))
{
@@ -101,7 +101,7 @@ constexpr MeshExtract create_extractor_fdots_nor()
* \{ */
static void extract_fdots_nor_hq_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *UNUSED(tls_data))
{
@@ -116,7 +116,7 @@ static void extract_fdots_nor_hq_init(const MeshRenderData *mr,
}
static void extract_fdots_nor_hq_finish(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *UNUSED(data))
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc
index 822b5928c49..c391cb6ca5a 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc
@@ -36,7 +36,7 @@ static GPUVertFormat *get_fdots_nor_format_subdiv()
}
static void extract_fdots_pos_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *tls_data)
{
@@ -101,7 +101,7 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr,
static void extract_fdots_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buffer,
void *UNUSED(data))
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc
index de21c63e5fd..b0403cf7c4c 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc
@@ -22,7 +22,7 @@ struct MeshExtract_FdotUV_Data {
};
static void extract_fdots_uv_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *tls_data)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc
index 42a9a58bbe4..ac517269e7d 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_lnor.cc
@@ -16,7 +16,7 @@ namespace blender::draw {
* \{ */
static void extract_lnor_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *tls_data)
{
@@ -105,7 +105,7 @@ static GPUVertFormat *get_subdiv_lnor_format()
static void extract_lnor_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buffer,
void *UNUSED(data))
{
@@ -141,7 +141,7 @@ struct gpuHQNor {
};
static void extract_lnor_hq_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *tls_data)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc
index b57e2f6b807..951990466d0 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc
@@ -23,7 +23,7 @@ namespace blender::draw {
* \{ */
static void extract_mesh_analysis_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *UNUSED(tls_data))
{
@@ -587,7 +587,7 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp)
}
static void extract_analysis_iter_finish_mesh(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *UNUSED(data))
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc
index 68d838e9e62..4fcbdb1fc7c 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_orco.cc
@@ -19,7 +19,7 @@ struct MeshExtract_Orco_Data {
};
static void extract_orco_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *tls_data)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
index 313744bdd27..9788beabeb5 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
@@ -28,7 +28,7 @@ struct MeshExtract_PosNor_Data {
};
static void extract_pos_nor_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *tls_data)
{
@@ -171,7 +171,7 @@ static void extract_pos_nor_iter_lvert_mesh(const MeshRenderData *mr,
}
static void extract_pos_nor_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *UNUSED(buf),
void *_data)
{
@@ -201,7 +201,7 @@ static GPUVertFormat *get_custom_normals_format()
static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buffer,
void *UNUSED(data))
{
@@ -372,7 +372,7 @@ struct MeshExtract_PosNorHQ_Data {
};
static void extract_pos_nor_hq_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *tls_data)
{
@@ -521,7 +521,7 @@ static void extract_pos_nor_hq_iter_lvert_mesh(const MeshRenderData *mr,
}
static void extract_pos_nor_hq_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *UNUSED(buf),
void *_data)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc
index 0d959e324f8..492721b4853 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc
@@ -31,7 +31,7 @@ static GPUVertFormat *get_sculpt_data_format()
}
static void extract_sculpt_data_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *UNUSED(tls_data))
{
@@ -113,7 +113,7 @@ static void extract_sculpt_data_init(const MeshRenderData *mr,
static void extract_sculpt_data_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buffer,
void *UNUSED(data))
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc
index 6230e1974be..9e0d171c9e4 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc
@@ -30,7 +30,7 @@ static void extract_select_idx_init_impl(const MeshRenderData *UNUSED(mr),
}
static void extract_select_idx_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *tls_data)
{
@@ -366,7 +366,7 @@ constexpr MeshExtract create_extractor_vert_idx()
}
static void extract_fdot_idx_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *tls_data)
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_skin_roots.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_skin_roots.cc
index a275f247cad..f7655658bdd 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_skin_roots.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_skin_roots.cc
@@ -19,7 +19,7 @@ struct SkinRootData {
};
static void extract_skin_roots_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
+ MeshBatchCache *UNUSED(cache),
void *buf,
void *UNUSED(tls_data))
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc
index 83453d6ef38..049fa416523 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc
@@ -25,7 +25,7 @@ namespace blender::draw {
* \{ */
static void extract_tan_init_common(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
GPUVertFormat *format,
GPUVertCompType comp_type,
GPUVertFetchMode fetch_mode,
@@ -161,7 +161,7 @@ static void extract_tan_init_common(const MeshRenderData *mr,
}
static void extract_tan_ex_init(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
GPUVertBuf *vbo,
const bool do_hq)
{
@@ -235,7 +235,7 @@ static void extract_tan_ex_init(const MeshRenderData *mr,
}
static void extract_tan_init(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buf,
void *UNUSED(tls_data))
{
@@ -254,7 +254,7 @@ static GPUVertFormat *get_coarse_tan_format()
static void extract_tan_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buffer,
void *UNUSED(data))
{
@@ -344,7 +344,7 @@ constexpr MeshExtract create_extractor_tan()
* \{ */
static void extract_tan_hq_init(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buf,
void *UNUSED(tls_data))
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc
index ddb8ed9b25b..6606912850d 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc
@@ -19,7 +19,7 @@ namespace blender::draw {
/* Initialize the vertex format to be used for UVs. Return true if any UV layer is
* found, false otherwise. */
static bool mesh_extract_uv_format_init(GPUVertFormat *format,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
CustomData *cd_ldata,
eMRExtractType extract_type,
uint32_t &r_uv_layers)
@@ -72,7 +72,7 @@ static bool mesh_extract_uv_format_init(GPUVertFormat *format,
}
static void extract_uv_init(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buf,
void *UNUSED(tls_data))
{
@@ -120,7 +120,7 @@ static void extract_uv_init(const MeshRenderData *mr,
static void extract_uv_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buffer,
void *UNUSED(data))
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc
index 84ab20f8f90..419cbb0267f 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc
@@ -123,7 +123,7 @@ struct gpuMeshVcol {
};
static void extract_vcol_init(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buf,
void *UNUSED(tls_data))
{
@@ -234,7 +234,7 @@ static void extract_vcol_init(const MeshRenderData *mr,
static void extract_vcol_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buffer,
void *UNUSED(data))
{
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc
index c64cca4dff5..ba194a4b167 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc
@@ -79,7 +79,7 @@ static float evaluate_vertex_weight(const MDeformVert *dvert, const DRW_MeshWeig
}
static void extract_weights_init(const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buf,
void *tls_data)
{
@@ -154,7 +154,7 @@ static void extract_weights_iter_poly_mesh(const MeshRenderData *mr,
static void extract_weights_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
- struct MeshBatchCache *cache,
+ MeshBatchCache *cache,
void *buffer,
void *_data)
{
diff --git a/source/blender/draw/intern/shaders/common_subdiv_ibo_lines_comp.glsl b/source/blender/draw/intern/shaders/common_subdiv_ibo_lines_comp.glsl
index 3244b7960d8..eacdf8e6333 100644
--- a/source/blender/draw/intern/shaders/common_subdiv_ibo_lines_comp.glsl
+++ b/source/blender/draw/intern/shaders/common_subdiv_ibo_lines_comp.glsl
@@ -35,7 +35,7 @@ void emit_line(uint line_offset, uint quad_index, uint start_loop_index, uint co
uint coarse_quad_index = coarse_polygon_index_from_subdiv_quad_index(quad_index,
coarse_poly_count);
- if (is_face_hidden(coarse_quad_index) ||
+ if (use_hide && is_face_hidden(coarse_quad_index) ||
(input_origindex[vertex_index] == ORIGINDEX_NONE && optimal_display)) {
output_lines[line_offset + 0] = 0xffffffff;
output_lines[line_offset + 1] = 0xffffffff;
diff --git a/source/blender/draw/intern/shaders/common_subdiv_ibo_tris_comp.glsl b/source/blender/draw/intern/shaders/common_subdiv_ibo_tris_comp.glsl
index ce3c8478d3f..a46d69eca88 100644
--- a/source/blender/draw/intern/shaders/common_subdiv_ibo_tris_comp.glsl
+++ b/source/blender/draw/intern/shaders/common_subdiv_ibo_tris_comp.glsl
@@ -45,7 +45,7 @@ void main()
int triangle_loop_index = (int(quad_index) + mat_offset) * 6;
#endif
- if (is_face_hidden(coarse_quad_index)) {
+ if (use_hide && is_face_hidden(coarse_quad_index)) {
output_tris[triangle_loop_index + 0] = 0xffffffff;
output_tris[triangle_loop_index + 1] = 0xffffffff;
output_tris[triangle_loop_index + 2] = 0xffffffff;
diff --git a/source/blender/draw/intern/shaders/common_subdiv_lib.glsl b/source/blender/draw/intern/shaders/common_subdiv_lib.glsl
index d76a7369f79..4183b4a1cd3 100644
--- a/source/blender/draw/intern/shaders/common_subdiv_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_subdiv_lib.glsl
@@ -36,6 +36,10 @@ layout(std140) uniform shader_data
/* Total number of elements to process. */
uint total_dispatch_size;
+
+ bool is_edit_mode;
+
+ bool use_hide;
};
uint get_global_invocation_index()
diff --git a/source/blender/draw/intern/shaders/common_subdiv_patch_evaluation_comp.glsl b/source/blender/draw/intern/shaders/common_subdiv_patch_evaluation_comp.glsl
index e146ccb343a..81e346863c2 100644
--- a/source/blender/draw/intern/shaders/common_subdiv_patch_evaluation_comp.glsl
+++ b/source/blender/draw/intern/shaders/common_subdiv_patch_evaluation_comp.glsl
@@ -427,7 +427,7 @@ void main()
output_nors[coarse_quad_index] = fnor;
# endif
- if (is_face_hidden(coarse_quad_index)) {
+ if (use_hide && is_face_hidden(coarse_quad_index)) {
output_indices[coarse_quad_index] = 0xffffffff;
}
else {
diff --git a/source/blender/draw/intern/shaders/common_subdiv_vbo_lnor_comp.glsl b/source/blender/draw/intern/shaders/common_subdiv_vbo_lnor_comp.glsl
index f5c4c7895aa..97c07704c06 100644
--- a/source/blender/draw/intern/shaders/common_subdiv_vbo_lnor_comp.glsl
+++ b/source/blender/draw/intern/shaders/common_subdiv_vbo_lnor_comp.glsl
@@ -26,6 +26,23 @@ bool is_face_selected(uint coarse_quad_index)
return (extra_coarse_face_data[coarse_quad_index] & coarse_face_select_mask) != 0;
}
+bool is_face_hidden(uint coarse_quad_index)
+{
+ return (extra_coarse_face_data[coarse_quad_index] & coarse_face_hidden_mask) != 0;
+}
+
+/* Flag for paint mode overlay and normals drawing in edit-mode. */
+float get_loop_flag(uint coarse_quad_index, int vert_origindex)
+{
+ if (is_face_hidden(coarse_quad_index) || (is_edit_mode && vert_origindex == -1)) {
+ return -1.0;
+ }
+ if (is_face_selected(coarse_quad_index)) {
+ return 1.0;
+ }
+ return 0.0;
+}
+
void main()
{
/* We execute for each quad. */
@@ -44,7 +61,11 @@ void main()
/* Face is smooth, use vertex normals. */
for (int i = 0; i < 4; i++) {
PosNorLoop pos_nor_loop = pos_nor[start_loop_index + i];
- output_lnor[start_loop_index + i] = get_normal_and_flag(pos_nor_loop);
+ int origindex = input_vert_origindex[start_loop_index + i];
+ LoopNormal loop_normal = get_normal_and_flag(pos_nor_loop);
+ loop_normal.flag = get_loop_flag(coarse_quad_index, origindex);
+
+ output_lnor[start_loop_index + i] = loop_normal;
}
}
else {
@@ -68,11 +89,7 @@ void main()
for (int i = 0; i < 4; i++) {
int origindex = input_vert_origindex[start_loop_index + i];
- float flag = 0.0;
- if (origindex == -1) {
- flag = -1.0;
- }
- loop_normal.flag = flag;
+ loop_normal.flag = get_loop_flag(coarse_quad_index, origindex);
output_lnor[start_loop_index + i] = loop_normal;
}
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index fc5b3838900..7b659511aaa 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -388,6 +388,17 @@ const EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf(bContext *C,
/* Create new layer */
/* TODO: have some way of specifying that we don't want this? */
+ {
+ /* "New Layer" entry */
+ item_tmp.identifier = "__CREATE__";
+ item_tmp.name = "New Layer";
+ item_tmp.value = -1;
+ item_tmp.icon = ICON_ADD;
+ RNA_enum_item_add(&item, &totitem, &item_tmp);
+
+ /* separator */
+ RNA_enum_item_add_separator(&item, &totitem);
+ }
const int tot = BLI_listbase_count(&gpd->layers);
/* Existing layers */
@@ -405,17 +416,6 @@ const EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf(bContext *C,
RNA_enum_item_add(&item, &totitem, &item_tmp);
}
- {
- /* separator */
- RNA_enum_item_add_separator(&item, &totitem);
-
- /* "New Layer" entry */
- item_tmp.identifier = "__CREATE__";
- item_tmp.name = "New Layer";
- item_tmp.value = -1;
- item_tmp.icon = ICON_ADD;
- RNA_enum_item_add(&item, &totitem, &item_tmp);
- }
RNA_enum_item_end(&item, &totitem);
*r_free = true;
diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h
index c5a45f8b73e..74735018814 100644
--- a/source/blender/editors/include/ED_clip.h
+++ b/source/blender/editors/include/ED_clip.h
@@ -22,13 +22,36 @@ struct bScreen;
/* ** clip_editor.c ** */
-/* common poll functions */
+/* Returns true when the following conditions are met:
+ * - Current space is Space Clip.
+ * - There is a movie clip opened in it. */
bool ED_space_clip_poll(struct bContext *C);
+/* Returns true when the following conditions are met:
+ * - Current space is Space Clip.
+ * - It is set to Clip view.
+ *
+ * It is not required to have movie clip opened for editing. */
bool ED_space_clip_view_clip_poll(struct bContext *C);
+/* Returns true when the following conditions are met:
+ * - Current space is Space Clip.
+ * - It is set to Tracking mode.
+ *
+ * It is not required to have movie clip opened for editing. */
bool ED_space_clip_tracking_poll(struct bContext *C);
+
+/* Returns true when the following conditions are met:
+ * - Current space is Space Clip.
+ * - It is set to Mask mode.
+ *
+ * It is not required to have mask opened for editing. */
bool ED_space_clip_maskedit_poll(struct bContext *C);
+
+/* Returns true when the following conditions are met:
+ * - Current space is Space Clip.
+ * - It is set to Mask mode.
+ * - The space has mask opened. */
bool ED_space_clip_maskedit_mask_poll(struct bContext *C);
void ED_space_clip_get_size(struct SpaceClip *sc, int *width, int *height);
diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h
index b16844c01ea..3e5d4c3adf4 100644
--- a/source/blender/editors/include/ED_image.h
+++ b/source/blender/editors/include/ED_image.h
@@ -137,8 +137,22 @@ bool ED_space_image_paint_curve(const struct bContext *C);
* Matches clip function.
*/
bool ED_space_image_check_show_maskedit(struct SpaceImage *sima, struct Object *obedit);
+
+/* Returns true when the following conditions are met:
+ * - Current space is Image Editor.
+ * - The image editor is not a UV Editor.
+ * - It is set to Mask mode.
+ *
+ * It is not required to have mask opened for editing. */
bool ED_space_image_maskedit_poll(struct bContext *C);
+
+/* Returns true when the following conditions are met:
+ * - Current space is Image Editor.
+ * - The image editor is not a UV Editor.
+ * - It is set to Mask mode.
+ * - The space has mask opened. */
bool ED_space_image_maskedit_mask_poll(struct bContext *C);
+
bool ED_space_image_cursor_poll(struct bContext *C);
/**
diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h
index 7039d6d9fc7..6d4d4fcff48 100644
--- a/source/blender/editors/include/ED_mask.h
+++ b/source/blender/editors/include/ED_mask.h
@@ -22,6 +22,19 @@ struct wmKeyConfig;
/* mask_edit.c */
+/* Returns true when the following conditions are met:
+ * - Current space supports mask editing.
+ * - The space is configured to interact with mask.
+ *
+ * It is not required to have mask opened for editing. */
+bool ED_maskedit_poll(struct bContext *C);
+
+/* Returns true when the following conditions are met:
+ * - Current space supports mask editing.
+ * - The space is configured to interact with mask.
+ * - The space has mask open for editing. */
+bool ED_maskedit_mask_poll(struct bContext *C);
+
void ED_mask_deselect_all(const struct bContext *C);
void ED_operatortypes_mask(void);
@@ -73,6 +86,7 @@ void ED_mask_draw_region(struct Depsgraph *depsgraph,
char draw_flag,
char draw_type,
eMaskOverlayMode overlay_mode,
+ float blend_factor,
int width_i,
int height_i,
float aspx,
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index aa62a6209e4..a24c8625a63 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -595,7 +595,6 @@ bool ED_operator_object_active_local_editable_posemode_exclusive(struct bContext
bool ED_operator_posemode_context(struct bContext *C);
bool ED_operator_posemode(struct bContext *C);
bool ED_operator_posemode_local(struct bContext *C);
-bool ED_operator_mask(struct bContext *C);
bool ED_operator_camera_poll(struct bContext *C);
/* screen_user_menu.c */
diff --git a/source/blender/editors/include/ED_select_utils.h b/source/blender/editors/include/ED_select_utils.h
index fa02ebe18f6..8c856794ec8 100644
--- a/source/blender/editors/include/ED_select_utils.h
+++ b/source/blender/editors/include/ED_select_utils.h
@@ -40,11 +40,11 @@ typedef enum {
} eSelectOp;
/* Select Similar */
-enum {
+typedef enum {
SIM_CMP_EQ = 0,
SIM_CMP_GT,
SIM_CMP_LT,
-};
+} eSimilarCmp;
#define SEL_OP_USE_OUTSIDE(sel_op) (ELEM(sel_op, SEL_OP_AND))
#define SEL_OP_USE_PRE_DESELECT(sel_op) (ELEM(sel_op, SEL_OP_SET))
@@ -63,11 +63,11 @@ int ED_select_op_action(eSelectOp sel_op, bool is_select, bool is_inside);
*/
int ED_select_op_action_deselected(eSelectOp sel_op, bool is_select, bool is_inside);
-int ED_select_similar_compare_float(float delta, float thresh, int compare);
+bool ED_select_similar_compare_float(float delta, float thresh, eSimilarCmp compare);
bool ED_select_similar_compare_float_tree(const struct KDTree_1d *tree,
float length,
float thresh,
- int compare);
+ eSimilarCmp compare);
/**
* Utility to use for selection operations that run multiple times (circle select).
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 341d5e78872..7c00c4f1875 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -4818,8 +4818,7 @@ static int ui_do_but_GRIDTILE(bContext *C,
uiHandleButtonData *data,
const wmEvent *event)
{
- uiButGridTile *grid_tile_but = (uiButGridTile *)but;
- BLI_assert(grid_tile_but->but.type == UI_BTYPE_GRID_TILE);
+ BLI_assert(but->type == UI_BTYPE_GRID_TILE);
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (event->type == LEFTMOUSE) {
@@ -4840,7 +4839,8 @@ static int ui_do_but_GRIDTILE(bContext *C,
case KM_DBL_CLICK:
data->cancel = true;
- // UI_tree_view_item_begin_rename(grid_tile_but->tree_item);
+ // uiButGridTile *grid_tile_but = (uiButGridTile *)but;
+ // UI_tree_view_item_begin_rename(grid_tile_but->tree_item);
ED_region_tag_redraw(CTX_wm_region(C));
return WM_UI_HANDLER_BREAK;
}
diff --git a/source/blender/editors/interface/interface_region_search.cc b/source/blender/editors/interface/interface_region_search.cc
index 64de31dfe6a..81c0c29d09a 100644
--- a/source/blender/editors/interface/interface_region_search.cc
+++ b/source/blender/editors/interface/interface_region_search.cc
@@ -451,15 +451,16 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re
/* reset vars */
data->items.totitem = 0;
data->items.more = 0;
- if (reset == false) {
+ if (!reset) {
data->items.offset_i = data->items.offset;
}
else {
data->items.offset_i = data->items.offset = 0;
data->active = -1;
- /* handle active */
- if (search_but->items_update_fn && search_but->item_active) {
+ /* On init, find and center active item. */
+ const bool is_first_search = !search_but->but.changed;
+ if (is_first_search && search_but->items_update_fn && search_but->item_active) {
data->items.active = search_but->item_active;
ui_searchbox_update_fn(C, search_but, but->editstr, &data->items);
data->items.active = nullptr;
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index c7ebecb178b..82d4405e1b5 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -800,7 +800,7 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
.style = UI_TIP_STYLE_HEADER,
.color_id = UI_TIP_LC_NORMAL,
});
- field->text = BLI_sprintfN("%s", but_label.strinfo);
+ field->text = BLI_strdup(but_label.strinfo);
}
/* Tip */
diff --git a/source/blender/editors/interface/interface_style.cc b/source/blender/editors/interface/interface_style.cc
index 291ede05730..904765f6dc4 100644
--- a/source/blender/editors/interface/interface_style.cc
+++ b/source/blender/editors/interface/interface_style.cc
@@ -382,19 +382,8 @@ void uiStyleInit(void)
}
CLAMP(U.dpi, 48, 144);
- LISTBASE_FOREACH (uiFont *, font, &U.uifonts) {
- BLF_unload_id(font->blf_id);
- }
-
- if (blf_mono_font != -1) {
- BLF_unload_id(blf_mono_font);
- blf_mono_font = -1;
- }
-
- if (blf_mono_font_render != -1) {
- BLF_unload_id(blf_mono_font_render);
- blf_mono_font_render = -1;
- }
+ /* Needed so that custom fonts are always first. */
+ BLF_unload_all();
uiFont *font_first = static_cast<uiFont *>(U.uifonts.first);
@@ -498,6 +487,9 @@ void uiStyleInit(void)
const bool unique = true;
blf_mono_font_render = BLF_load_mono_default(unique);
}
+
+ /* Load the fallback fonts last. */
+ BLF_load_font_stack();
}
void UI_fontstyle_set(const uiFontStyle *fs)
diff --git a/source/blender/editors/io/io_obj.c b/source/blender/editors/io/io_obj.c
index 4819ae09785..53fa4788d0e 100644
--- a/source/blender/editors/io/io_obj.c
+++ b/source/blender/editors/io/io_obj.c
@@ -392,6 +392,7 @@ static int wm_obj_import_exec(bContext *C, wmOperator *op)
import_params.clamp_size = RNA_float_get(op->ptr, "clamp_size");
import_params.forward_axis = RNA_enum_get(op->ptr, "forward_axis");
import_params.up_axis = RNA_enum_get(op->ptr, "up_axis");
+ import_params.import_vertex_groups = RNA_boolean_get(op->ptr, "import_vertex_groups");
import_params.validate_meshes = RNA_boolean_get(op->ptr, "validate_meshes");
OBJ_import(C, &import_params);
@@ -422,6 +423,7 @@ static void ui_obj_import_settings(uiLayout *layout, PointerRNA *imfptr)
box = uiLayoutBox(layout);
uiItemL(box, IFACE_("Options"), ICON_EXPORT);
col = uiLayoutColumn(box, false);
+ uiItemR(col, imfptr, "import_vertex_groups", 0, NULL, ICON_NONE);
uiItemR(col, imfptr, "validate_meshes", 0, NULL, ICON_NONE);
}
@@ -468,6 +470,11 @@ void WM_OT_obj_import(struct wmOperatorType *ot)
ot->srna, "forward_axis", io_transform_axis, IO_AXIS_NEGATIVE_Z, "Forward Axis", "");
RNA_def_enum(ot->srna, "up_axis", io_transform_axis, IO_AXIS_Y, "Up Axis", "");
RNA_def_boolean(ot->srna,
+ "import_vertex_groups",
+ false,
+ "Vertex Groups",
+ "Import OBJ groups as vertex groups");
+ RNA_def_boolean(ot->srna,
"validate_meshes",
false,
"Validate Meshes",
diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c
index 194170b1677..42f3acaa6bc 100644
--- a/source/blender/editors/mask/mask_add.c
+++ b/source/blender/editors/mask/mask_add.c
@@ -583,7 +583,7 @@ void MASK_OT_add_vertex(wmOperatorType *ot)
/* api callbacks */
ot->exec = add_vertex_exec;
ot->invoke = add_vertex_invoke;
- ot->poll = ED_operator_mask;
+ ot->poll = ED_maskedit_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -862,7 +862,7 @@ void MASK_OT_primitive_circle_add(wmOperatorType *ot)
/* api callbacks */
ot->exec = primitive_circle_add_exec;
ot->invoke = primitive_add_invoke;
- ot->poll = ED_operator_mask;
+ ot->poll = ED_maskedit_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -897,7 +897,7 @@ void MASK_OT_primitive_square_add(wmOperatorType *ot)
/* api callbacks */
ot->exec = primitive_square_add_exec;
ot->invoke = primitive_add_invoke;
- ot->poll = ED_operator_mask;
+ ot->poll = ED_maskedit_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index aab4007854f..1bd224fe763 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -663,6 +663,7 @@ void ED_mask_draw_region(
const char draw_flag,
const char draw_type,
const eMaskOverlayMode overlay_mode,
+ const float blend_factor,
/* convert directly into aspect corrected vars */
const int width_i,
const int height_i,
@@ -721,12 +722,14 @@ void ED_mask_draw_region(
}
if (draw_flag & MASK_DRAWFLAG_OVERLAY) {
- const float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
+ float buf_col[4] = {1.0f, 0.0f, 0.0f, 0.0f};
float *buffer = mask_rasterize(mask_eval, width, height);
if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) {
/* More blending types could be supported in the future. */
- GPU_blend(GPU_BLEND_MULTIPLY);
+ GPU_blend(GPU_BLEND_ALPHA);
+ buf_col[0] = -1.0f;
+ buf_col[3] = 1.0f;
}
GPU_matrix_push();
@@ -737,10 +740,18 @@ void ED_mask_draw_region(
}
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
GPU_shader_uniform_vector(
- state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
- immDrawPixelsTexTiled(
- &state, 0.0f, 0.0f, width, height, GPU_R16F, false, buffer, 1.0f, 1.0f, NULL);
+ state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, buf_col);
+ if (overlay_mode == MASK_OVERLAY_COMBINED) {
+ const float blend_col[4] = {0.0f, 0.0f, 0.0f, blend_factor};
+
+ immDrawPixelsTexTiled(
+ &state, 0.0f, 0.0f, width, height, GPU_R16F, false, buffer, 1.0f, 1.0f, blend_col);
+ }
+ else {
+ immDrawPixelsTexTiled(
+ &state, 0.0f, 0.0f, width, height, GPU_R16F, false, buffer, 1.0f, 1.0f, NULL);
+ }
GPU_matrix_pop();
if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) {
diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h
index c620d781c7f..2e99b45f215 100644
--- a/source/blender/editors/mask/mask_intern.h
+++ b/source/blender/editors/mask/mask_intern.h
@@ -86,9 +86,6 @@ void ED_mask_select_flush_all(struct Mask *mask);
/* mask_editor.c */
-bool ED_maskedit_poll(struct bContext *C);
-bool ED_maskedit_mask_poll(struct bContext *C);
-
/* Generalized solution for preserving editor viewport when making changes while lock-to-selection
* is enabled.
* Any mask operator can use this API, without worrying that some editors do not have an idea of
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index 3c0e7ee399c..3ca9f4d06e2 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -113,7 +113,7 @@ void MASK_OT_new(wmOperatorType *ot)
/* api callbacks */
ot->exec = mask_new_exec;
- ot->poll = ED_operator_mask;
+ ot->poll = ED_maskedit_poll;
/* properties */
RNA_def_string(ot->srna, "name", NULL, MAX_ID_NAME - 2, "Name", "Name of new mask");
@@ -146,7 +146,7 @@ void MASK_OT_layer_new(wmOperatorType *ot)
/* api callbacks */
ot->exec = mask_layer_new_exec;
- ot->poll = ED_maskedit_poll;
+ ot->poll = ED_maskedit_mask_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -181,7 +181,7 @@ void MASK_OT_layer_remove(wmOperatorType *ot)
/* api callbacks */
ot->exec = mask_layer_remove_exec;
- ot->poll = ED_maskedit_poll;
+ ot->poll = ED_maskedit_mask_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -907,7 +907,7 @@ void MASK_OT_slide_point(wmOperatorType *ot)
/* api callbacks */
ot->invoke = slide_point_invoke;
ot->modal = slide_point_modal;
- ot->poll = ED_operator_mask;
+ ot->poll = ED_maskedit_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1297,7 +1297,7 @@ void MASK_OT_slide_spline_curvature(wmOperatorType *ot)
/* api callbacks */
ot->invoke = slide_spline_curvature_invoke;
ot->modal = slide_spline_curvature_modal;
- ot->poll = ED_operator_mask;
+ ot->poll = ED_maskedit_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c
index 9d8b84de66b..afeb1500267 100644
--- a/source/blender/editors/mask/mask_relationships.c
+++ b/source/blender/editors/mask/mask_relationships.c
@@ -21,6 +21,7 @@
#include "WM_types.h"
#include "ED_clip.h" /* frame remapping functions */
+#include "ED_mask.h"
#include "ED_screen.h"
#include "mask_intern.h" /* own include */
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index 969d5b5912c..e7891450bd6 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -669,7 +669,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
short etype = event->type;
short eval = event->val;
- /* When activated from toolbar, need to convert leftmouse release to confirm */
+ /* When activated from toolbar, need to convert left-mouse release to confirm. */
if (ELEM(etype, LEFTMOUSE, opdata->launch_event) && (eval == KM_RELEASE) &&
RNA_boolean_get(op->ptr, "release_confirm")) {
etype = EVT_MODAL_MAP;
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 369ca553a8c..f58baa0e25c 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -3458,9 +3458,9 @@ ScrArea *ED_area_find_under_cursor(const bContext *C, int spacetype, const int x
if (!area) {
/* Check all windows except the active one. */
int scr_pos[2];
- wmWindow *r_win = WM_window_find_under_cursor(win, xy, scr_pos);
- if (r_win && r_win != win) {
- win = r_win;
+ wmWindow *win_other = WM_window_find_under_cursor(win, xy, scr_pos);
+ if (win_other && win_other != win) {
+ win = win_other;
screen = WM_window_get_active_screen(win);
area = BKE_screen_find_area_xy(screen, spacetype, scr_pos);
}
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 55721e6380d..212fb846b43 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -659,32 +659,6 @@ bool ED_operator_editmball(bContext *C)
return false;
}
-bool ED_operator_mask(bContext *C)
-{
- ScrArea *area = CTX_wm_area(C);
- if (area && area->spacedata.first) {
- switch (area->spacetype) {
- case SPACE_CLIP: {
- SpaceClip *space_clip = area->spacedata.first;
- return ED_space_clip_check_show_maskedit(space_clip);
- }
- case SPACE_SEQ: {
- SpaceSeq *sseq = area->spacedata.first;
- Scene *scene = CTX_data_scene(C);
- return ED_space_sequencer_check_show_maskedit(sseq, scene);
- }
- case SPACE_IMAGE: {
- SpaceImage *sima = area->spacedata.first;
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
- return ED_space_image_check_show_maskedit(sima, obedit);
- }
- }
- }
-
- return false;
-}
-
bool ED_operator_camera_poll(bContext *C)
{
struct Camera *cam = CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data;
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index b1b52d16c6d..8879161d2af 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -52,7 +52,7 @@ set(SRC
paint_stroke.c
paint_utils.c
paint_vertex.cc
- paint_vertex_color_ops.c
+ paint_vertex_color_ops.cc
paint_vertex_color_utils.c
paint_vertex_proj.c
paint_vertex_weight_ops.c
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc
index f013fa05f4c..bac03de77e7 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc
@@ -22,9 +22,9 @@
#include "BKE_geometry_set.hh"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
+#include "BKE_mesh_sample.hh"
#include "BKE_paint.h"
#include "BKE_report.h"
-#include "BKE_spline.hh"
#include "DNA_brush_enums.h"
#include "DNA_brush_types.h"
@@ -38,10 +38,12 @@
#include "ED_screen.h"
#include "ED_view3d.h"
+#include "GEO_add_curves_on_mesh.hh"
+
#include "WM_api.h"
/**
- * The code below uses a prefix naming convention to indicate the coordinate space:
+ * The code below uses a suffix naming convention to indicate the coordinate space:
* cu: Local space of the curves object that is being edited.
* su: Local space of the surface object.
* wo: World space.
@@ -70,16 +72,6 @@ class AddOperation : public CurvesSculptStrokeOperation {
void on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension) override;
};
-static void initialize_straight_curve_positions(const float3 &p1,
- const float3 &p2,
- MutableSpan<float3> r_positions)
-{
- const float step = 1.0f / (float)(r_positions.size() - 1);
- for (const int i : r_positions.index_range()) {
- r_positions[i] = math::interpolate(p1, p2, i * step);
- }
-}
-
/**
* Utility class that actually executes the update when the stroke is updated. That's useful
* because it avoids passing a very large number of parameters between functions.
@@ -95,54 +87,26 @@ struct AddOperationExecutor {
Object *surface_ob_ = nullptr;
Mesh *surface_ = nullptr;
Span<MLoopTri> surface_looptris_;
- Span<float3> corner_normals_su_;
- VArray_Span<float2> surface_uv_map_;
const CurvesSculpt *curves_sculpt_ = nullptr;
const Brush *brush_ = nullptr;
const BrushCurvesSculptSettings *brush_settings_ = nullptr;
+ int add_amount_;
+ bool use_front_face_;
float brush_radius_re_;
float2 brush_pos_re_;
- bool use_front_face_;
- bool interpolate_length_;
- bool interpolate_shape_;
- bool interpolate_point_count_;
- bool use_interpolation_;
- float new_curve_length_;
- int add_amount_;
- int constant_points_per_curve_;
-
- /** Various matrices to convert between coordinate spaces. */
- float4x4 curves_to_world_mat_;
- float4x4 curves_to_surface_mat_;
- float4x4 world_to_curves_mat_;
- float4x4 world_to_surface_mat_;
- float4x4 surface_to_world_mat_;
- float4x4 surface_to_curves_mat_;
- float4x4 surface_to_curves_normal_mat_;
+ CurvesSculptTransforms transforms_;
BVHTreeFromMesh surface_bvh_;
- int tot_old_curves_;
- int tot_old_points_;
-
struct AddedPoints {
Vector<float3> positions_cu;
Vector<float3> bary_coords;
Vector<int> looptri_indices;
};
- struct NeighborInfo {
- /* Curve index of the neighbor. */
- int index;
- /* The weights of all neighbors of a new curve add up to 1. */
- float weight;
- };
- static constexpr int max_neighbors = 5;
- using NeighborsVector = Vector<NeighborInfo, max_neighbors>;
-
AddOperationExecutor(const bContext &C) : ctx_(C)
{
}
@@ -159,23 +123,10 @@ struct AddOperationExecutor {
return;
}
- curves_to_world_mat_ = object_->obmat;
- world_to_curves_mat_ = curves_to_world_mat_.inverted();
+ transforms_ = CurvesSculptTransforms(*object_, curves_id_->surface);
surface_ob_ = curves_id_->surface;
surface_ = static_cast<Mesh *>(surface_ob_->data);
- surface_to_world_mat_ = surface_ob_->obmat;
- world_to_surface_mat_ = surface_to_world_mat_.inverted();
- surface_to_curves_mat_ = world_to_curves_mat_ * surface_to_world_mat_;
- surface_to_curves_normal_mat_ = surface_to_curves_mat_.inverted().transposed();
- curves_to_surface_mat_ = world_to_surface_mat_ * curves_to_world_mat_;
-
- if (!CustomData_has_layer(&surface_->ldata, CD_NORMAL)) {
- BKE_mesh_calc_normals_split(surface_);
- }
- corner_normals_su_ = {
- reinterpret_cast<const float3 *>(CustomData_get_layer(&surface_->ldata, CD_NORMAL)),
- surface_->totloop};
curves_sculpt_ = ctx_.scene->toolsettings->curves_sculpt;
brush_ = BKE_paint_brush_for_read(&curves_sculpt_->paint);
@@ -187,16 +138,6 @@ struct AddOperationExecutor {
const eBrushFalloffShape falloff_shape = static_cast<eBrushFalloffShape>(
brush_->falloff_shape);
add_amount_ = std::max(0, brush_settings_->add_amount);
- constant_points_per_curve_ = std::max(2, brush_settings_->points_per_curve);
- interpolate_length_ = brush_settings_->flag & BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_LENGTH;
- interpolate_shape_ = brush_settings_->flag & BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_SHAPE;
- interpolate_point_count_ = brush_settings_->flag &
- BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_POINT_COUNT;
- use_interpolation_ = interpolate_length_ || interpolate_shape_ || interpolate_point_count_;
- new_curve_length_ = brush_settings_->curve_length;
-
- tot_old_curves_ = curves_->curves_num();
- tot_old_points_ = curves_->points_num();
if (add_amount_ == 0) {
return;
@@ -212,15 +153,6 @@ struct AddOperationExecutor {
surface_looptris_ = {BKE_mesh_runtime_looptri_ensure(surface_),
BKE_mesh_runtime_looptri_len(surface_)};
- if (curves_id_->surface_uv_map != nullptr) {
- MeshComponent surface_component;
- surface_component.replace(surface_, GeometryOwnershipType::ReadOnly);
- surface_uv_map_ = surface_component
- .attribute_try_get_for_read(curves_id_->surface_uv_map,
- ATTR_DOMAIN_CORNER)
- .typed<float2>();
- }
-
/* Sample points on the surface using one of multiple strategies. */
AddedPoints added_points;
if (add_amount_ == 1) {
@@ -241,28 +173,52 @@ struct AddOperationExecutor {
return;
}
- Array<NeighborsVector> neighbors_per_curve;
- if (use_interpolation_) {
- this->ensure_curve_roots_kdtree();
- neighbors_per_curve = this->find_curve_neighbors(added_points);
+ /* Find UV map. */
+ VArray_Span<float2> surface_uv_map;
+ if (curves_id_->surface_uv_map != nullptr) {
+ MeshComponent surface_component;
+ surface_component.replace(surface_, GeometryOwnershipType::ReadOnly);
+ surface_uv_map = surface_component
+ .attribute_try_get_for_read(curves_id_->surface_uv_map,
+ ATTR_DOMAIN_CORNER)
+ .typed<float2>();
}
- /* Resize to add the new curves, building the offsets in the array owned by the curves. */
- const int tot_added_curves = added_points.bary_coords.size();
- curves_->resize(curves_->points_num(), curves_->curves_num() + tot_added_curves);
- if (interpolate_point_count_) {
- this->initialize_curve_offsets_with_interpolation(neighbors_per_curve);
- }
- else {
- this->initialize_curve_offsets_without_interpolation(constant_points_per_curve_);
+ /* Find normals. */
+ if (!CustomData_has_layer(&surface_->ldata, CD_NORMAL)) {
+ BKE_mesh_calc_normals_split(surface_);
}
+ const Span<float3> corner_normals_su = {
+ reinterpret_cast<const float3 *>(CustomData_get_layer(&surface_->ldata, CD_NORMAL)),
+ surface_->totloop};
- /* Resize to add the correct point count calculated as part of building the offsets. */
- curves_->resize(curves_->offsets().last(), curves_->curves_num());
-
- this->initialize_attributes(added_points, neighbors_per_curve);
+ geometry::AddCurvesOnMeshInputs add_inputs;
+ add_inputs.root_positions_cu = added_points.positions_cu;
+ add_inputs.bary_coords = added_points.bary_coords;
+ add_inputs.looptri_indices = added_points.looptri_indices;
+ add_inputs.interpolate_length = brush_settings_->flag &
+ BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_LENGTH;
+ add_inputs.interpolate_shape = brush_settings_->flag &
+ BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_SHAPE;
+ add_inputs.interpolate_point_count = brush_settings_->flag &
+ BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_POINT_COUNT;
+ add_inputs.fallback_curve_length = brush_settings_->curve_length;
+ add_inputs.fallback_point_count = std::max(2, brush_settings_->points_per_curve);
+ add_inputs.surface = surface_;
+ add_inputs.surface_bvh = &surface_bvh_;
+ add_inputs.surface_looptris = surface_looptris_;
+ add_inputs.surface_uv_map = surface_uv_map;
+ add_inputs.corner_normals_su = corner_normals_su;
+ add_inputs.curves_to_surface_mat = transforms_.curves_to_surface;
+ add_inputs.surface_to_curves_normal_mat = transforms_.surface_to_curves_normal;
+
+ if (add_inputs.interpolate_length || add_inputs.interpolate_shape ||
+ add_inputs.interpolate_point_count) {
+ this->ensure_curve_roots_kdtree();
+ add_inputs.old_roots_kdtree = self_->curve_roots_kdtree_;
+ }
- curves_->update_curve_types();
+ geometry::add_curves_on_mesh(*curves_, add_inputs);
DEG_id_tag_update(&curves_id_->id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, &curves_id_->id);
@@ -277,14 +233,14 @@ struct AddOperationExecutor {
float3 ray_start_wo, ray_end_wo;
ED_view3d_win_to_segment_clipped(
ctx_.depsgraph, ctx_.region, ctx_.v3d, brush_pos_re_, ray_start_wo, ray_end_wo, true);
- const float3 ray_start_cu = world_to_curves_mat_ * ray_start_wo;
- const float3 ray_end_cu = world_to_curves_mat_ * ray_end_wo;
+ const float3 ray_start_cu = transforms_.world_to_curves * ray_start_wo;
+ const float3 ray_end_cu = transforms_.world_to_curves * ray_end_wo;
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
- const float4x4 transform = curves_to_surface_mat_ * brush_transform;
+ const float4x4 transform = transforms_.curves_to_surface * brush_transform;
this->sample_in_center(r_added_points, transform * ray_start_cu, transform * ray_end_cu);
}
}
@@ -312,10 +268,10 @@ struct AddOperationExecutor {
const int looptri_index = ray_hit.index;
const float3 brush_pos_su = ray_hit.co;
- const float3 bary_coords = compute_bary_coord_in_triangle(
+ const float3 bary_coords = bke::mesh_surface_sample::compute_bary_coord_in_triangle(
*surface_, surface_looptris_[looptri_index], brush_pos_su);
- const float3 brush_pos_cu = surface_to_curves_mat_ * brush_pos_su;
+ const float3 brush_pos_cu = transforms_.surface_to_curves * brush_pos_su;
r_added_points.positions_cu.append(brush_pos_cu);
r_added_points.bary_coords.append(bary_coords);
@@ -339,60 +295,37 @@ struct AddOperationExecutor {
const float4x4 &brush_transform)
{
const int old_amount = r_added_points.bary_coords.size();
- const int max_iterations = std::max(100'000, add_amount_ * 10);
+ const int max_iterations = 100;
int current_iteration = 0;
while (r_added_points.bary_coords.size() < old_amount + add_amount_) {
if (current_iteration++ >= max_iterations) {
break;
}
-
- const float r = brush_radius_re_ * std::sqrt(rng.get_float());
- const float angle = rng.get_float() * 2.0f * M_PI;
- const float2 pos_re = brush_pos_re_ + r * float2(std::cos(angle), std::sin(angle));
-
- float3 ray_start_wo, ray_end_wo;
- ED_view3d_win_to_segment_clipped(
- ctx_.depsgraph, ctx_.region, ctx_.v3d, pos_re, ray_start_wo, ray_end_wo, true);
- const float3 ray_start_cu = brush_transform * (world_to_curves_mat_ * ray_start_wo);
- const float3 ray_end_cu = brush_transform * (world_to_curves_mat_ * ray_end_wo);
-
- const float3 ray_start_su = curves_to_surface_mat_ * ray_start_cu;
- const float3 ray_end_su = curves_to_surface_mat_ * ray_end_cu;
- const float3 ray_direction_su = math::normalize(ray_end_su - ray_start_su);
-
- BVHTreeRayHit ray_hit;
- ray_hit.dist = FLT_MAX;
- ray_hit.index = -1;
- BLI_bvhtree_ray_cast(surface_bvh_.tree,
- ray_start_su,
- ray_direction_su,
- 0.0f,
- &ray_hit,
- surface_bvh_.raycast_callback,
- &surface_bvh_);
-
- if (ray_hit.index == -1) {
- continue;
- }
-
- if (use_front_face_) {
- const float3 normal_su = ray_hit.no;
- if (math::dot(ray_direction_su, normal_su) >= 0.0f) {
- continue;
- }
+ const int missing_amount = add_amount_ + old_amount - r_added_points.bary_coords.size();
+ const int new_points = bke::mesh_surface_sample::sample_surface_points_projected(
+ rng,
+ *surface_,
+ surface_bvh_,
+ brush_pos_re_,
+ brush_radius_re_,
+ [&](const float2 &pos_re, float3 &r_start_su, float3 &r_end_su) {
+ float3 start_wo, end_wo;
+ ED_view3d_win_to_segment_clipped(
+ ctx_.depsgraph, ctx_.region, ctx_.v3d, pos_re, start_wo, end_wo, true);
+ const float3 start_cu = brush_transform * (transforms_.world_to_curves * start_wo);
+ const float3 end_cu = brush_transform * (transforms_.world_to_curves * end_wo);
+ r_start_su = transforms_.curves_to_surface * start_cu;
+ r_end_su = transforms_.curves_to_surface * end_cu;
+ },
+ use_front_face_,
+ add_amount_,
+ missing_amount,
+ r_added_points.bary_coords,
+ r_added_points.looptri_indices,
+ r_added_points.positions_cu);
+ for (float3 &pos : r_added_points.positions_cu.as_mutable_span().take_back(new_points)) {
+ pos = transforms_.surface_to_curves * pos;
}
-
- const int looptri_index = ray_hit.index;
- const float3 pos_su = ray_hit.co;
-
- const float3 bary_coords = compute_bary_coord_in_triangle(
- *surface_, surface_looptris_[looptri_index], pos_su);
-
- const float3 pos_cu = surface_to_curves_mat_ * pos_su;
-
- r_added_points.positions_cu.append(pos_cu);
- r_added_points.bary_coords.append(bary_coords);
- r_added_points.looptri_indices.append(looptri_index);
}
}
@@ -401,72 +334,47 @@ struct AddOperationExecutor {
*/
void sample_spherical_with_symmetry(RandomNumberGenerator &rng, AddedPoints &r_added_points)
{
- /* Find ray that starts in the center of the brush. */
- float3 brush_ray_start_wo, brush_ray_end_wo;
- ED_view3d_win_to_segment_clipped(ctx_.depsgraph,
- ctx_.region,
- ctx_.v3d,
- brush_pos_re_,
- brush_ray_start_wo,
- brush_ray_end_wo,
- true);
- const float3 brush_ray_start_cu = world_to_curves_mat_ * brush_ray_start_wo;
- const float3 brush_ray_end_cu = world_to_curves_mat_ * brush_ray_end_wo;
+ const std::optional<CurvesBrush3D> brush_3d = sample_curves_surface_3d_brush(*ctx_.depsgraph,
+ *ctx_.region,
+ *ctx_.v3d,
+ transforms_,
+ surface_bvh_,
+ brush_pos_re_,
+ brush_radius_re_);
+ if (!brush_3d.has_value()) {
+ return;
+ }
- /* Find ray that starts on the boundary of the brush. That is used to compute the brush radius
- * in 3D. */
- float3 brush_radius_ray_start_wo, brush_radius_ray_end_wo;
+ float3 view_ray_start_wo, view_ray_end_wo;
ED_view3d_win_to_segment_clipped(ctx_.depsgraph,
ctx_.region,
ctx_.v3d,
- brush_pos_re_ + float2(brush_radius_re_, 0),
- brush_radius_ray_start_wo,
- brush_radius_ray_end_wo,
+ brush_pos_re_,
+ view_ray_start_wo,
+ view_ray_end_wo,
true);
- const float3 brush_radius_ray_start_cu = world_to_curves_mat_ * brush_radius_ray_start_wo;
- const float3 brush_radius_ray_end_cu = world_to_curves_mat_ * brush_radius_ray_end_wo;
+ const float3 view_direction_su = math::normalize(
+ transforms_.world_to_surface * view_ray_end_wo -
+ transforms_.world_to_surface * view_ray_start_wo);
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
- const float4x4 transform = curves_to_surface_mat_ * brush_transform;
- this->sample_spherical(rng,
- r_added_points,
- transform * brush_ray_start_cu,
- transform * brush_ray_end_cu,
- transform * brush_radius_ray_start_cu,
- transform * brush_radius_ray_end_cu);
+ const float4x4 transform = transforms_.curves_to_surface * brush_transform;
+ const float3 brush_pos_su = transform * brush_3d->position_cu;
+ const float brush_radius_su = transform_brush_radius(
+ transform, brush_3d->position_cu, brush_3d->radius_cu);
+ this->sample_spherical(
+ rng, r_added_points, brush_pos_su, brush_radius_su, view_direction_su);
}
}
void sample_spherical(RandomNumberGenerator &rng,
AddedPoints &r_added_points,
- const float3 &brush_ray_start_su,
- const float3 &brush_ray_end_su,
- const float3 &brush_radius_ray_start_su,
- const float3 &brush_radius_ray_end_su)
+ const float3 &brush_pos_su,
+ const float brush_radius_su,
+ const float3 &view_direction_su)
{
- const float3 brush_ray_direction_su = math::normalize(brush_ray_end_su - brush_ray_start_su);
-
- BVHTreeRayHit ray_hit;
- ray_hit.dist = FLT_MAX;
- ray_hit.index = -1;
- BLI_bvhtree_ray_cast(surface_bvh_.tree,
- brush_ray_start_su,
- brush_ray_direction_su,
- 0.0f,
- &ray_hit,
- surface_bvh_.raycast_callback,
- &surface_bvh_);
-
- if (ray_hit.index == -1) {
- return;
- }
-
- /* Compute brush radius. */
- const float3 brush_pos_su = ray_hit.co;
- const float brush_radius_su = dist_to_line_v3(
- brush_pos_su, brush_radius_ray_start_su, brush_radius_ray_end_su);
const float brush_radius_sq_su = pow2f(brush_radius_su);
/* Find surface triangles within brush radius. */
@@ -483,7 +391,7 @@ struct AddOperationExecutor {
const float3 v2_su = surface_->mvert[surface_->mloop[looptri.tri[2]].v].co;
float3 normal_su;
normal_tri_v3(normal_su, v0_su, v1_su, v2_su);
- if (math::dot(normal_su, brush_ray_direction_su) >= 0.0f) {
+ if (math::dot(normal_su, view_direction_su) >= 0.0f) {
return;
}
looptri_indices.append(index);
@@ -505,9 +413,6 @@ struct AddOperationExecutor {
const float brush_plane_area_su = M_PI * brush_radius_sq_su;
const float approximate_density_su = add_amount_ / brush_plane_area_su;
- /* Used for switching between two triangle sampling strategies. */
- const float area_threshold = brush_plane_area_su;
-
/* Usually one or two iterations should be enough. */
const int max_iterations = 5;
int current_iteration = 0;
@@ -517,78 +422,18 @@ struct AddOperationExecutor {
if (current_iteration++ >= max_iterations) {
break;
}
-
- for (const int looptri_index : looptri_indices) {
- const MLoopTri &looptri = surface_looptris_[looptri_index];
-
- const float3 v0_su = surface_->mvert[surface_->mloop[looptri.tri[0]].v].co;
- const float3 v1_su = surface_->mvert[surface_->mloop[looptri.tri[1]].v].co;
- const float3 v2_su = surface_->mvert[surface_->mloop[looptri.tri[2]].v].co;
-
- const float looptri_area_su = area_tri_v3(v0_su, v1_su, v2_su);
-
- if (looptri_area_su < area_threshold) {
- /* The triangle is small compared to the brush radius. Sample by generating random
- * barycentric coordinates. */
- const int amount = rng.round_probabilistic(approximate_density_su * looptri_area_su);
- for ([[maybe_unused]] const int i : IndexRange(amount)) {
- const float3 bary_coord = rng.get_barycentric_coordinates();
- const float3 point_pos_su = attribute_math::mix3(bary_coord, v0_su, v1_su, v2_su);
- const float distance_to_brush_sq_su = math::distance_squared(point_pos_su,
- brush_pos_su);
- if (distance_to_brush_sq_su > brush_radius_sq_su) {
- continue;
- }
-
- r_added_points.bary_coords.append(bary_coord);
- r_added_points.looptri_indices.append(looptri_index);
- r_added_points.positions_cu.append(surface_to_curves_mat_ * point_pos_su);
- }
- }
- else {
- /* The triangle is large compared to the brush radius. Sample by generating random points
- * on the triangle plane within the brush radius. */
- float3 normal_su;
- normal_tri_v3(normal_su, v0_su, v1_su, v2_su);
-
- float3 brush_pos_proj_su = brush_pos_su;
- project_v3_plane(brush_pos_proj_su, normal_su, v0_su);
-
- const float proj_distance_sq_su = math::distance_squared(brush_pos_proj_su,
- brush_pos_su);
- const float brush_radius_factor_sq = 1.0f -
- std::min(1.0f,
- proj_distance_sq_su / brush_radius_sq_su);
- const float radius_proj_sq_su = brush_radius_sq_su * brush_radius_factor_sq;
- const float radius_proj_su = std::sqrt(radius_proj_sq_su);
- const float circle_area_su = M_PI * radius_proj_su;
-
- const int amount = rng.round_probabilistic(approximate_density_su * circle_area_su);
-
- const float3 axis_1_su = math::normalize(v1_su - v0_su) * radius_proj_su;
- const float3 axis_2_su = math::normalize(math::cross(
- axis_1_su, math::cross(axis_1_su, v2_su - v0_su))) *
- radius_proj_su;
-
- for ([[maybe_unused]] const int i : IndexRange(amount)) {
- const float r = std::sqrt(rng.get_float());
- const float angle = rng.get_float() * 2.0f * M_PI;
- const float x = r * std::cos(angle);
- const float y = r * std::sin(angle);
- const float3 point_pos_su = brush_pos_proj_su + axis_1_su * x + axis_2_su * y;
- if (!isect_point_tri_prism_v3(point_pos_su, v0_su, v1_su, v2_su)) {
- /* Sampled point is not in the triangle. */
- continue;
- }
-
- float3 bary_coord;
- interp_weights_tri_v3(bary_coord, v0_su, v1_su, v2_su, point_pos_su);
-
- r_added_points.bary_coords.append(bary_coord);
- r_added_points.looptri_indices.append(looptri_index);
- r_added_points.positions_cu.append(surface_to_curves_mat_ * point_pos_su);
- }
- }
+ const int new_points = bke::mesh_surface_sample::sample_surface_points_spherical(
+ rng,
+ *surface_,
+ looptri_indices,
+ brush_pos_su,
+ brush_radius_su,
+ approximate_density_su,
+ r_added_points.bary_coords,
+ r_added_points.looptri_indices,
+ r_added_points.positions_cu);
+ for (float3 &pos : r_added_points.positions_cu.as_mutable_span().take_back(new_points)) {
+ pos = transforms_.surface_to_curves * pos;
}
}
@@ -613,312 +458,6 @@ struct AddOperationExecutor {
BLI_kdtree_3d_balance(self_->curve_roots_kdtree_);
}
}
-
- void initialize_curve_offsets_with_interpolation(const Span<NeighborsVector> neighbors_per_curve)
- {
- MutableSpan<int> new_offsets = curves_->offsets_for_write().drop_front(tot_old_curves_);
-
- attribute_math::DefaultMixer<int> mixer{new_offsets};
- threading::parallel_for(neighbors_per_curve.index_range(), 1024, [&](IndexRange curves_range) {
- for (const int i : curves_range) {
- if (neighbors_per_curve[i].is_empty()) {
- mixer.mix_in(i, constant_points_per_curve_, 1.0f);
- }
- else {
- for (const NeighborInfo &neighbor : neighbors_per_curve[i]) {
- const int neighbor_points_num = curves_->points_for_curve(neighbor.index).size();
- mixer.mix_in(i, neighbor_points_num, neighbor.weight);
- }
- }
- }
- });
- mixer.finalize();
-
- bke::curves::accumulate_counts_to_offsets(new_offsets, tot_old_points_);
- }
-
- void initialize_curve_offsets_without_interpolation(const int points_per_curve)
- {
- MutableSpan<int> new_offsets = curves_->offsets_for_write().drop_front(tot_old_curves_);
- int offset = tot_old_points_;
- for (const int i : new_offsets.index_range()) {
- new_offsets[i] = offset;
- offset += points_per_curve;
- }
- }
-
- void initialize_attributes(const AddedPoints &added_points,
- const Span<NeighborsVector> neighbors_per_curve)
- {
- Array<float> new_lengths_cu(added_points.bary_coords.size());
- if (interpolate_length_) {
- this->interpolate_lengths(neighbors_per_curve, new_lengths_cu);
- }
- else {
- new_lengths_cu.fill(new_curve_length_);
- }
-
- Array<float3> new_normals_su = this->compute_normals_for_added_curves_su(added_points);
- if (!surface_uv_map_.is_empty()) {
- this->initialize_surface_attachment(added_points);
- }
-
- this->fill_new_selection();
-
- if (interpolate_shape_) {
- this->initialize_position_with_interpolation(
- added_points, neighbors_per_curve, new_normals_su, new_lengths_cu);
- }
- else {
- this->initialize_position_without_interpolation(
- added_points, new_lengths_cu, new_normals_su);
- }
- }
-
- /**
- * Select newly created points or curves in new curves if necessary.
- */
- void fill_new_selection()
- {
- switch (curves_id_->selection_domain) {
- case ATTR_DOMAIN_CURVE: {
- const VArray<float> selection = curves_->selection_curve_float();
- if (selection.is_single() && selection.get_internal_single() >= 1.0f) {
- return;
- }
- curves_->selection_curve_float_for_write().drop_front(tot_old_curves_).fill(1.0f);
- break;
- }
- case ATTR_DOMAIN_POINT: {
- const VArray<float> selection = curves_->selection_point_float();
- if (selection.is_single() && selection.get_internal_single() >= 1.0f) {
- return;
- }
- curves_->selection_point_float_for_write().drop_front(tot_old_points_).fill(1.0f);
- break;
- }
- default:
- BLI_assert_unreachable();
- }
- }
-
- Array<NeighborsVector> find_curve_neighbors(const AddedPoints &added_points)
- {
- const int tot_added_curves = added_points.bary_coords.size();
- Array<NeighborsVector> neighbors_per_curve(tot_added_curves);
- threading::parallel_for(IndexRange(tot_added_curves), 128, [&](const IndexRange range) {
- for (const int i : range) {
- const float3 root_cu = added_points.positions_cu[i];
- std::array<KDTreeNearest_3d, max_neighbors> nearest_n;
- const int found_neighbors = BLI_kdtree_3d_find_nearest_n(
- self_->curve_roots_kdtree_, root_cu, nearest_n.data(), max_neighbors);
- float tot_weight = 0.0f;
- for (const int neighbor_i : IndexRange(found_neighbors)) {
- KDTreeNearest_3d &nearest = nearest_n[neighbor_i];
- const float weight = 1.0f / std::max(nearest.dist, 0.00001f);
- tot_weight += weight;
- neighbors_per_curve[i].append({nearest.index, weight});
- }
- /* Normalize weights. */
- for (NeighborInfo &neighbor : neighbors_per_curve[i]) {
- neighbor.weight /= tot_weight;
- }
- }
- });
- return neighbors_per_curve;
- }
-
- void interpolate_lengths(const Span<NeighborsVector> neighbors_per_curve,
- MutableSpan<float> r_lengths)
- {
- const Span<float3> positions_cu = curves_->positions();
-
- threading::parallel_for(r_lengths.index_range(), 128, [&](const IndexRange range) {
- for (const int added_curve_i : range) {
- const Span<NeighborInfo> neighbors = neighbors_per_curve[added_curve_i];
- float length_sum = 0.0f;
- for (const NeighborInfo &neighbor : neighbors) {
- const IndexRange neighbor_points = curves_->points_for_curve(neighbor.index);
- float neighbor_length = 0.0f;
- for (const int segment_i : neighbor_points.drop_back(1)) {
- const float3 &p1 = positions_cu[segment_i];
- const float3 &p2 = positions_cu[segment_i + 1];
- neighbor_length += math::distance(p1, p2);
- }
- length_sum += neighbor.weight * neighbor_length;
- }
- const float length = neighbors.is_empty() ? new_curve_length_ : length_sum;
- r_lengths[added_curve_i] = length;
- }
- });
- }
-
- float3 compute_point_normal_su(const int looptri_index, const float3 &bary_coord)
- {
- const MLoopTri &looptri = surface_looptris_[looptri_index];
- const int l0 = looptri.tri[0];
- const int l1 = looptri.tri[1];
- const int l2 = looptri.tri[2];
-
- const float3 &l0_normal_su = corner_normals_su_[l0];
- const float3 &l1_normal_su = corner_normals_su_[l1];
- const float3 &l2_normal_su = corner_normals_su_[l2];
-
- const float3 normal_su = math::normalize(
- attribute_math::mix3(bary_coord, l0_normal_su, l1_normal_su, l2_normal_su));
- return normal_su;
- }
-
- Array<float3> compute_normals_for_added_curves_su(const AddedPoints &added_points)
- {
- Array<float3> normals_su(added_points.bary_coords.size());
- threading::parallel_for(normals_su.index_range(), 256, [&](const IndexRange range) {
- for (const int i : range) {
- const int looptri_index = added_points.looptri_indices[i];
- const float3 &bary_coord = added_points.bary_coords[i];
- normals_su[i] = compute_surface_point_normal(
- surface_looptris_[looptri_index], bary_coord, corner_normals_su_);
- }
- });
- return normals_su;
- }
-
- void initialize_surface_attachment(const AddedPoints &added_points)
- {
- MutableSpan<float2> surface_uv_coords = curves_->surface_uv_coords_for_write();
- threading::parallel_for(
- added_points.bary_coords.index_range(), 1024, [&](const IndexRange range) {
- for (const int i : range) {
- const int curve_i = tot_old_curves_ + i;
- const MLoopTri &looptri = surface_looptris_[added_points.looptri_indices[i]];
- const float2 &uv0 = surface_uv_map_[looptri.tri[0]];
- const float2 &uv1 = surface_uv_map_[looptri.tri[1]];
- const float2 &uv2 = surface_uv_map_[looptri.tri[2]];
- const float3 &bary_coords = added_points.bary_coords[i];
- const float2 uv = attribute_math::mix3(bary_coords, uv0, uv1, uv2);
- surface_uv_coords[curve_i] = uv;
- }
- });
- }
-
- /**
- * Initialize new curves so that they are just a straight line in the normal direction.
- */
- void initialize_position_without_interpolation(const AddedPoints &added_points,
- const Span<float> lengths_cu,
- const MutableSpan<float3> normals_su)
- {
- MutableSpan<float3> positions_cu = curves_->positions_for_write();
-
- threading::parallel_for(
- added_points.bary_coords.index_range(), 256, [&](const IndexRange range) {
- for (const int i : range) {
- const IndexRange points = curves_->points_for_curve(tot_old_curves_ + i);
- const float3 &root_cu = added_points.positions_cu[i];
- const float length = lengths_cu[i];
- const float3 &normal_su = normals_su[i];
- const float3 normal_cu = math::normalize(surface_to_curves_normal_mat_ * normal_su);
- const float3 tip_cu = root_cu + length * normal_cu;
-
- initialize_straight_curve_positions(root_cu, tip_cu, positions_cu.slice(points));
- }
- });
- }
-
- /**
- * Use neighboring curves to determine the shape.
- */
- void initialize_position_with_interpolation(const AddedPoints &added_points,
- const Span<NeighborsVector> neighbors_per_curve,
- const Span<float3> new_normals_su,
- const Span<float> new_lengths_cu)
- {
- MutableSpan<float3> positions_cu = curves_->positions_for_write();
-
- threading::parallel_for(
- added_points.bary_coords.index_range(), 256, [&](const IndexRange range) {
- for (const int i : range) {
- const Span<NeighborInfo> neighbors = neighbors_per_curve[i];
- const IndexRange points = curves_->points_for_curve(tot_old_curves_ + i);
-
- const float length_cu = new_lengths_cu[i];
- const float3 &normal_su = new_normals_su[i];
- const float3 normal_cu = math::normalize(surface_to_curves_normal_mat_ * normal_su);
-
- const float3 &root_cu = added_points.positions_cu[i];
-
- if (neighbors.is_empty()) {
- /* If there are no neighbors, just make a straight line. */
- const float3 tip_cu = root_cu + length_cu * normal_cu;
- initialize_straight_curve_positions(root_cu, tip_cu, positions_cu.slice(points));
- continue;
- }
-
- positions_cu.slice(points).fill(root_cu);
-
- for (const NeighborInfo &neighbor : neighbors) {
- const int neighbor_curve_i = neighbor.index;
- const float3 &neighbor_first_pos_cu =
- positions_cu[curves_->offsets()[neighbor_curve_i]];
- const float3 neighbor_first_pos_su = curves_to_surface_mat_ * neighbor_first_pos_cu;
-
- BVHTreeNearest nearest;
- nearest.dist_sq = FLT_MAX;
- BLI_bvhtree_find_nearest(surface_bvh_.tree,
- neighbor_first_pos_su,
- &nearest,
- surface_bvh_.nearest_callback,
- &surface_bvh_);
- const int neighbor_looptri_index = nearest.index;
- const MLoopTri &neighbor_looptri = surface_looptris_[neighbor_looptri_index];
-
- const float3 neighbor_bary_coord = compute_bary_coord_in_triangle(
- *surface_, neighbor_looptri, nearest.co);
-
- const float3 neighbor_normal_su = compute_surface_point_normal(
- surface_looptris_[neighbor_looptri_index],
- neighbor_bary_coord,
- corner_normals_su_);
- const float3 neighbor_normal_cu = math::normalize(surface_to_curves_normal_mat_ *
- neighbor_normal_su);
-
- /* The rotation matrix used to transform relative coordinates of the neighbor curve
- * to the new curve. */
- float normal_rotation_cu[3][3];
- rotation_between_vecs_to_mat3(normal_rotation_cu, neighbor_normal_cu, normal_cu);
-
- const IndexRange neighbor_points = curves_->points_for_curve(neighbor_curve_i);
- const float3 &neighbor_root_cu = positions_cu[neighbor_points[0]];
-
- /* Use a temporary #PolySpline, because that's the easiest way to resample an
- * existing curve right now. Resampling is necessary if the length of the new curve
- * does not match the length of the neighbors or the number of handle points is
- * different. */
- PolySpline neighbor_spline;
- neighbor_spline.resize(neighbor_points.size());
- neighbor_spline.positions().copy_from(positions_cu.slice(neighbor_points));
- neighbor_spline.mark_cache_invalid();
-
- const float neighbor_length_cu = neighbor_spline.length();
- const float length_factor = std::min(1.0f, length_cu / neighbor_length_cu);
-
- const float resample_factor = (1.0f / (points.size() - 1.0f)) * length_factor;
- for (const int j : IndexRange(points.size())) {
- const Spline::LookupResult lookup = neighbor_spline.lookup_evaluated_factor(
- j * resample_factor);
- const float index_factor = lookup.evaluated_index + lookup.factor;
- float3 p;
- neighbor_spline.sample_with_index_factors<float3>(
- neighbor_spline.positions(), {&index_factor, 1}, {&p, 1});
- const float3 relative_coord = p - neighbor_root_cu;
- float3 rotated_relative_coord = relative_coord;
- mul_m3_v3(normal_rotation_cu, rotated_relative_coord);
- positions_cu[points[j]] += neighbor.weight * rotated_relative_coord;
- }
- }
- }
- });
- }
};
void AddOperation::on_stroke_extended(const bContext &C, const StrokeExtension &stroke_extension)
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc b/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc
index 7e583773512..8c6ef34ef26 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc
@@ -256,6 +256,55 @@ std::optional<CurvesBrush3D> sample_curves_3d_brush(const Depsgraph &depsgraph,
return brush_3d;
}
+std::optional<CurvesBrush3D> sample_curves_surface_3d_brush(
+ const Depsgraph &depsgraph,
+ const ARegion &region,
+ const View3D &v3d,
+ const CurvesSculptTransforms &transforms,
+ const BVHTreeFromMesh &surface_bvh,
+ const float2 &brush_pos_re,
+ const float brush_radius_re)
+{
+ float3 brush_ray_start_wo, brush_ray_end_wo;
+ ED_view3d_win_to_segment_clipped(
+ &depsgraph, &region, &v3d, brush_pos_re, brush_ray_start_wo, brush_ray_end_wo, true);
+ const float3 brush_ray_start_su = transforms.world_to_surface * brush_ray_start_wo;
+ const float3 brush_ray_end_su = transforms.world_to_surface * brush_ray_end_wo;
+
+ const float3 brush_ray_direction_su = math::normalize(brush_ray_end_su - brush_ray_start_su);
+
+ BVHTreeRayHit ray_hit;
+ ray_hit.dist = FLT_MAX;
+ ray_hit.index = -1;
+ BLI_bvhtree_ray_cast(surface_bvh.tree,
+ brush_ray_start_su,
+ brush_ray_direction_su,
+ 0.0f,
+ &ray_hit,
+ surface_bvh.raycast_callback,
+ const_cast<void *>(static_cast<const void *>(&surface_bvh)));
+ if (ray_hit.index == -1) {
+ return std::nullopt;
+ }
+
+ float3 brush_radius_ray_start_wo, brush_radius_ray_end_wo;
+ ED_view3d_win_to_segment_clipped(&depsgraph,
+ &region,
+ &v3d,
+ brush_pos_re + float2(brush_radius_re, 0),
+ brush_radius_ray_start_wo,
+ brush_radius_ray_end_wo,
+ true);
+ const float3 brush_radius_ray_start_cu = transforms.world_to_curves * brush_radius_ray_start_wo;
+ const float3 brush_radius_ray_end_cu = transforms.world_to_curves * brush_radius_ray_end_wo;
+
+ const float3 brush_pos_su = ray_hit.co;
+ const float3 brush_pos_cu = transforms.surface_to_curves * brush_pos_su;
+ const float brush_radius_cu = dist_to_line_v3(
+ brush_pos_cu, brush_radius_ray_start_cu, brush_radius_ray_end_cu);
+ return CurvesBrush3D{brush_pos_cu, brush_radius_cu};
+}
+
Vector<float4x4> get_symmetry_brush_transforms(const eCurvesSymmetryType symmetry)
{
Vector<float4x4> matrices;
@@ -284,6 +333,16 @@ Vector<float4x4> get_symmetry_brush_transforms(const eCurvesSymmetryType symmetr
return matrices;
}
+float transform_brush_radius(const float4x4 &transform,
+ const float3 &brush_position,
+ const float old_radius)
+{
+ const float3 offset_position = brush_position + float3(old_radius, 0.0f, 0.0f);
+ const float3 new_position = transform * brush_position;
+ const float3 new_offset_position = transform * offset_position;
+ return math::distance(new_position, new_offset_position);
+}
+
void move_last_point_and_resample(MutableSpan<float3> positions, const float3 &new_last_position)
{
/* Find the accumulated length of each point in the original curve,
@@ -324,33 +383,18 @@ CurvesSculptCommonContext::CurvesSculptCommonContext(const bContext &C)
this->rv3d = CTX_wm_region_view3d(&C);
}
-float3 compute_surface_point_normal(const MLoopTri &looptri,
- const float3 &bary_coord,
- const Span<float3> corner_normals)
-{
- const int l0 = looptri.tri[0];
- const int l1 = looptri.tri[1];
- const int l2 = looptri.tri[2];
-
- const float3 &l0_normal = corner_normals[l0];
- const float3 &l1_normal = corner_normals[l1];
- const float3 &l2_normal = corner_normals[l2];
-
- const float3 normal = math::normalize(
- attribute_math::mix3(bary_coord, l0_normal, l1_normal, l2_normal));
- return normal;
-}
-
-float3 compute_bary_coord_in_triangle(const Mesh &mesh,
- const MLoopTri &looptri,
- const float3 &position)
+CurvesSculptTransforms::CurvesSculptTransforms(const Object &curves_ob, const Object *surface_ob)
{
- const float3 &v0 = mesh.mvert[mesh.mloop[looptri.tri[0]].v].co;
- const float3 &v1 = mesh.mvert[mesh.mloop[looptri.tri[1]].v].co;
- const float3 &v2 = mesh.mvert[mesh.mloop[looptri.tri[2]].v].co;
- float3 bary_coords;
- interp_weights_tri_v3(bary_coords, v0, v1, v2, position);
- return bary_coords;
+ this->curves_to_world = curves_ob.obmat;
+ this->world_to_curves = this->curves_to_world.inverted();
+
+ if (surface_ob != nullptr) {
+ this->surface_to_world = surface_ob->obmat;
+ this->world_to_surface = this->surface_to_world.inverted();
+ this->surface_to_curves = this->world_to_curves * this->surface_to_world;
+ this->curves_to_surface = this->world_to_surface * this->curves_to_world;
+ this->surface_to_curves_normal = this->surface_to_curves.inverted().transposed();
+ }
}
} // namespace blender::ed::sculpt_paint
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc
index ae0a512c5ee..541bf9d8253 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc
@@ -100,8 +100,7 @@ struct CombOperationExecutor {
float2 brush_pos_re_;
float2 brush_pos_diff_re_;
- float4x4 curves_to_world_mat_;
- float4x4 world_to_curves_mat_;
+ CurvesSculptTransforms transforms_;
CombOperationExecutor(const bContext &C) : ctx_(C)
{
@@ -121,9 +120,6 @@ struct CombOperationExecutor {
brush_radius_factor_ = brush_radius_factor(*brush_, stroke_extension);
brush_strength_ = brush_strength_get(*ctx_.scene, *brush_, stroke_extension);
- curves_to_world_mat_ = object_->obmat;
- world_to_curves_mat_ = curves_to_world_mat_.inverted();
-
falloff_shape_ = static_cast<eBrushFalloffShape>(brush_->falloff_shape);
curves_id_ = static_cast<Curves *>(object_->data);
@@ -132,6 +128,8 @@ struct CombOperationExecutor {
return;
}
+ transforms_ = CurvesSculptTransforms(*object_, curves_id_->surface);
+
point_factors_ = get_point_selection(*curves_id_);
curve_selection_ = retrieve_selected_curves(*curves_id_, selected_curve_indices_);
@@ -225,11 +223,11 @@ struct CombOperationExecutor {
float3 new_position_wo;
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
- curves_to_world_mat_ * old_pos_cu,
+ transforms_.curves_to_world * old_pos_cu,
new_position_re,
new_position_wo);
const float3 new_position_cu = brush_transform *
- (world_to_curves_mat_ * new_position_wo);
+ (transforms_.world_to_curves * new_position_wo);
positions_cu[point_i] = new_position_cu;
curve_changed = true;
@@ -252,16 +250,16 @@ struct CombOperationExecutor {
float3 brush_start_wo, brush_end_wo;
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
- curves_to_world_mat_ * self_->brush_3d_.position_cu,
+ transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_prev_re_,
brush_start_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
- curves_to_world_mat_ * self_->brush_3d_.position_cu,
+ transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_re_,
brush_end_wo);
- const float3 brush_start_cu = world_to_curves_mat_ * brush_start_wo;
- const float3 brush_end_cu = world_to_curves_mat_ * brush_end_wo;
+ const float3 brush_start_cu = transforms_.world_to_curves * brush_start_wo;
+ const float3 brush_end_cu = transforms_.world_to_curves * brush_end_wo;
const float brush_radius_cu = self_->brush_3d_.radius_cu * brush_radius_factor_;
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc
index 6f12d539aa2..eab7dabcd22 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc
@@ -76,8 +76,7 @@ struct DeleteOperationExecutor {
float2 brush_pos_re_;
- float4x4 curves_to_world_mat_;
- float4x4 world_to_curves_mat_;
+ CurvesSculptTransforms transforms_;
DeleteOperationExecutor(const bContext &C) : ctx_(C)
{
@@ -101,8 +100,7 @@ struct DeleteOperationExecutor {
brush_pos_re_ = stroke_extension.mouse_position;
- curves_to_world_mat_ = object_->obmat;
- world_to_curves_mat_ = curves_to_world_mat_.inverted();
+ transforms_ = CurvesSculptTransforms(*object_, curves_id_->surface);
const eBrushFalloffShape falloff_shape = static_cast<eBrushFalloffShape>(
brush_->falloff_shape);
@@ -199,10 +197,10 @@ struct DeleteOperationExecutor {
float3 brush_wo;
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
- curves_to_world_mat_ * self_->brush_3d_.position_cu,
+ transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_re_,
brush_wo);
- const float3 brush_cu = world_to_curves_mat_ * brush_wo;
+ const float3 brush_cu = transforms_.world_to_curves * brush_wo;
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_->symmetry));
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc
index 3420659520b..cf893f09fc6 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc
@@ -247,8 +247,7 @@ struct CurvesEffectOperationExecutor {
eBrushFalloffShape falloff_shape_;
- float4x4 curves_to_world_mat_;
- float4x4 world_to_curves_mat_;
+ CurvesSculptTransforms transforms_;
float2 brush_pos_start_re_;
float2 brush_pos_end_re_;
@@ -290,8 +289,7 @@ struct CurvesEffectOperationExecutor {
falloff_shape_ = eBrushFalloffShape(brush_->falloff_shape);
- curves_to_world_mat_ = object_->obmat;
- world_to_curves_mat_ = curves_to_world_mat_.inverted();
+ transforms_ = CurvesSculptTransforms(*object_, curves_id_->surface);
brush_pos_start_re_ = self.last_mouse_position_;
brush_pos_end_re_ = stroke_extension.mouse_position;
@@ -398,16 +396,16 @@ struct CurvesEffectOperationExecutor {
float3 brush_start_pos_wo, brush_end_pos_wo;
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
- curves_to_world_mat_ * closest_on_segment_cu,
+ transforms_.curves_to_world * closest_on_segment_cu,
brush_pos_start_re_,
brush_start_pos_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
- curves_to_world_mat_ * closest_on_segment_cu,
+ transforms_.curves_to_world * closest_on_segment_cu,
brush_pos_end_re_,
brush_end_pos_wo);
- const float3 brush_start_pos_cu = world_to_curves_mat_ * brush_start_pos_wo;
- const float3 brush_end_pos_cu = world_to_curves_mat_ * brush_end_pos_wo;
+ const float3 brush_start_pos_cu = transforms_.world_to_curves * brush_start_pos_wo;
+ const float3 brush_end_pos_cu = transforms_.world_to_curves * brush_end_pos_wo;
const float move_distance_cu = weight *
math::distance(brush_start_pos_cu, brush_end_pos_cu);
@@ -430,16 +428,16 @@ struct CurvesEffectOperationExecutor {
float3 brush_pos_start_wo, brush_pos_end_wo;
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
- curves_to_world_mat_ * self_->brush_3d_.position_cu,
+ transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_start_re_,
brush_pos_start_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
- curves_to_world_mat_ * self_->brush_3d_.position_cu,
+ transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_end_re_,
brush_pos_end_wo);
- const float3 brush_pos_start_cu = world_to_curves_mat_ * brush_pos_start_wo;
- const float3 brush_pos_end_cu = world_to_curves_mat_ * brush_pos_end_wo;
+ const float3 brush_pos_start_cu = transforms_.world_to_curves * brush_pos_start_wo;
+ const float3 brush_pos_end_cu = transforms_.world_to_curves * brush_pos_end_wo;
const float3 brush_pos_diff_cu = brush_pos_end_cu - brush_pos_start_cu;
const float brush_pos_diff_length_cu = math::length(brush_pos_diff_cu);
const float brush_radius_cu = self_->brush_3d_.radius_cu * brush_radius_factor_;
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh
index 5c926b1a740..ad3871bee45 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh
@@ -21,6 +21,7 @@ struct View3D;
struct Object;
struct Brush;
struct Scene;
+struct BVHTreeFromMesh;
namespace blender::ed::sculpt_paint {
@@ -60,6 +61,13 @@ std::unique_ptr<CurvesSculptStrokeOperation> new_grow_shrink_operation(
const BrushStrokeMode brush_mode, const bContext &C);
std::unique_ptr<CurvesSculptStrokeOperation> new_selection_paint_operation(
const BrushStrokeMode brush_mode, const bContext &C);
+std::unique_ptr<CurvesSculptStrokeOperation> new_pinch_operation(const BrushStrokeMode brush_mode,
+ const bContext &C);
+std::unique_ptr<CurvesSculptStrokeOperation> new_smooth_operation();
+std::unique_ptr<CurvesSculptStrokeOperation> new_puff_operation();
+std::unique_ptr<CurvesSculptStrokeOperation> new_density_operation(
+ const BrushStrokeMode brush_mode, const bContext &C);
+std::unique_ptr<CurvesSculptStrokeOperation> new_slide_operation();
struct CurvesBrush3D {
float3 position_cu;
@@ -97,14 +105,6 @@ IndexMask retrieve_selected_curves(const Curves &curves_id, Vector<int64_t> &r_i
void move_last_point_and_resample(MutableSpan<float3> positions, const float3 &new_last_position);
-float3 compute_surface_point_normal(const MLoopTri &looptri,
- const float3 &bary_coord,
- const Span<float3> corner_normals);
-
-float3 compute_bary_coord_in_triangle(const Mesh &mesh,
- const MLoopTri &looptri,
- const float3 &position);
-
class CurvesSculptCommonContext {
public:
const Depsgraph *depsgraph = nullptr;
@@ -116,4 +116,30 @@ class CurvesSculptCommonContext {
CurvesSculptCommonContext(const bContext &C);
};
+struct CurvesSculptTransforms {
+ float4x4 curves_to_world;
+ float4x4 curves_to_surface;
+ float4x4 world_to_curves;
+ float4x4 world_to_surface;
+ float4x4 surface_to_world;
+ float4x4 surface_to_curves;
+ float4x4 surface_to_curves_normal;
+
+ CurvesSculptTransforms() = default;
+ CurvesSculptTransforms(const Object &curves_ob, const Object *surface_ob);
+};
+
+std::optional<CurvesBrush3D> sample_curves_surface_3d_brush(
+ const Depsgraph &depsgraph,
+ const ARegion &region,
+ const View3D &v3d,
+ const CurvesSculptTransforms &transforms,
+ const BVHTreeFromMesh &surface_bvh,
+ const float2 &brush_pos_re,
+ const float brush_radius_re);
+
+float transform_brush_radius(const float4x4 &transform,
+ const float3 &brush_position,
+ const float old_radius);
+
} // namespace blender::ed::sculpt_paint
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc b/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc
index 69615a3bfb4..b40aebcaaf1 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc
@@ -66,8 +66,7 @@ struct SelectionPaintOperationExecutor {
float2 brush_pos_re_;
- float4x4 curves_to_world_mat_;
- float4x4 world_to_curves_mat_;
+ CurvesSculptTransforms transforms_;
SelectionPaintOperationExecutor(const bContext &C) : ctx_(C)
{
@@ -105,8 +104,7 @@ struct SelectionPaintOperationExecutor {
}
}
- curves_to_world_mat_ = object_->obmat;
- world_to_curves_mat_ = curves_to_world_mat_.inverted();
+ transforms_ = CurvesSculptTransforms(*object_, curves_id_->surface);
const eBrushFalloffShape falloff_shape = static_cast<eBrushFalloffShape>(
brush_->falloff_shape);
@@ -201,10 +199,10 @@ struct SelectionPaintOperationExecutor {
float3 brush_wo;
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
- curves_to_world_mat_ * self_->brush_3d_.position_cu,
+ transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_re_,
brush_wo);
- const float3 brush_cu = world_to_curves_mat_ * brush_wo;
+ const float3 brush_cu = transforms_.world_to_curves * brush_wo;
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_->symmetry));
@@ -309,10 +307,10 @@ struct SelectionPaintOperationExecutor {
float3 brush_wo;
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
- curves_to_world_mat_ * self_->brush_3d_.position_cu,
+ transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_re_,
brush_wo);
- const float3 brush_cu = world_to_curves_mat_ * brush_wo;
+ const float3 brush_cu = transforms_.world_to_curves * brush_wo;
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_->symmetry));
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc
index e1aecabdcc7..b63e5a7756b 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc
@@ -89,8 +89,7 @@ struct SnakeHookOperatorExecutor {
Vector<int64_t> selected_curve_indices_;
IndexMask curve_selection_;
- float4x4 curves_to_world_mat_;
- float4x4 world_to_curves_mat_;
+ CurvesSculptTransforms transforms_;
float2 brush_pos_prev_re_;
float2 brush_pos_re_;
@@ -118,15 +117,14 @@ struct SnakeHookOperatorExecutor {
falloff_shape_ = static_cast<eBrushFalloffShape>(brush_->falloff_shape);
- curves_to_world_mat_ = object_->obmat;
- world_to_curves_mat_ = curves_to_world_mat_.inverted();
-
curves_id_ = static_cast<Curves *>(object_->data);
curves_ = &CurvesGeometry::wrap(curves_id_->geometry);
if (curves_->curves_num() == 0) {
return;
}
+ transforms_ = CurvesSculptTransforms(*object_, curves_id_->surface);
+
curve_factors_ = get_curves_selection(*curves_id_);
curve_selection_ = retrieve_selected_curves(*curves_id_, selected_curve_indices_);
@@ -210,10 +208,11 @@ struct SnakeHookOperatorExecutor {
float3 new_position_wo;
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
- curves_to_world_mat_ * old_pos_cu,
+ transforms_.curves_to_world * old_pos_cu,
new_position_re,
new_position_wo);
- const float3 new_position_cu = brush_transform * (world_to_curves_mat_ * new_position_wo);
+ const float3 new_position_cu = brush_transform *
+ (transforms_.world_to_curves * new_position_wo);
move_last_point_and_resample(positions_cu.slice(points), new_position_cu);
}
@@ -228,16 +227,16 @@ struct SnakeHookOperatorExecutor {
float3 brush_start_wo, brush_end_wo;
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
- curves_to_world_mat_ * self_->brush_3d_.position_cu,
+ transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_prev_re_,
brush_start_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
- curves_to_world_mat_ * self_->brush_3d_.position_cu,
+ transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_re_,
brush_end_wo);
- const float3 brush_start_cu = world_to_curves_mat_ * brush_start_wo;
- const float3 brush_end_cu = world_to_curves_mat_ * brush_end_wo;
+ const float3 brush_start_cu = transforms_.world_to_curves * brush_start_wo;
+ const float3 brush_end_cu = transforms_.world_to_curves * brush_end_wo;
const float brush_radius_cu = self_->brush_3d_.radius_cu * brush_radius_factor_;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc
index a2e1adff50a..6a47aceb2b0 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc
@@ -11,6 +11,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "BLI_array.hh"
#include "BLI_math_base.h"
#include "BLI_math_color.h"
@@ -30,6 +31,8 @@
#include "paint_intern.h" /* own include */
+using blender::Array;
+
/* -------------------------------------------------------------------- */
/** \name Internal Utility Functions
* \{ */
@@ -45,7 +48,7 @@ static bool vertex_weight_paint_mode_poll(bContext *C)
static void tag_object_after_update(Object *object)
{
BLI_assert(object->type == OB_MESH);
- Mesh *mesh = object->data;
+ Mesh *mesh = static_cast<Mesh *>(object->data);
DEG_id_tag_update(&mesh->id, ID_RECALC_COPY_ON_WRITE);
/* NOTE: Original mesh is used for display, so tag it directly here. */
BKE_mesh_batch_cache_dirty_tag(mesh, BKE_MESH_BATCH_DIRTY_ALL);
@@ -63,7 +66,8 @@ static bool vertex_paint_from_weight(Object *ob)
const MPoly *mp;
int vgroup_active;
- if (((me = BKE_mesh_from_object(ob)) == NULL || (ED_mesh_color_ensure(me, NULL)) == false)) {
+ if (((me = BKE_mesh_from_object(ob)) == nullptr ||
+ (ED_mesh_color_ensure(me, nullptr)) == false)) {
return false;
}
@@ -128,14 +132,13 @@ static void vertex_color_smooth_looptag(Mesh *me, const bool *mlooptag)
{
const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
const MPoly *mp;
- int(*scol)[4];
bool has_shared = false;
- if (me->mloopcol == NULL || me->totvert == 0 || me->totpoly == 0) {
+ if (me->mloopcol == nullptr || me->totvert == 0 || me->totpoly == 0) {
return;
}
- scol = MEM_callocN(sizeof(int) * me->totvert * 5, "scol");
+ int(*scol)[4] = static_cast<int(*)[4]>(MEM_callocN(sizeof(int) * me->totvert * 5, "scol"));
int i;
for (i = 0, mp = me->mpoly; i < me->totpoly; i++, mp++) {
@@ -185,16 +188,15 @@ static bool vertex_color_smooth(Object *ob)
const MPoly *mp;
int i, j;
- bool *mlooptag;
-
- if (((me = BKE_mesh_from_object(ob)) == NULL) || (ED_mesh_color_ensure(me, NULL) == false)) {
+ if (((me = BKE_mesh_from_object(ob)) == nullptr) ||
+ (ED_mesh_color_ensure(me, nullptr) == false)) {
return false;
}
const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
- mlooptag = MEM_callocN(sizeof(bool) * me->totloop, "VPaintData mlooptag");
+ Array<bool> loop_tag(me->totloop, false);
/* simply tag loops of selected faces */
mp = me->mpoly;
@@ -208,7 +210,7 @@ static bool vertex_color_smooth(Object *ob)
j = 0;
do {
if (!(use_vert_sel && !(me->mvert[ml->v].flag & SELECT))) {
- mlooptag[mp->loopstart + j] = true;
+ loop_tag[mp->loopstart + j] = true;
}
ml++;
j++;
@@ -218,9 +220,7 @@ static bool vertex_color_smooth(Object *ob)
/* remove stale me->mcol, will be added later */
BKE_mesh_tessface_clear(me);
- vertex_color_smooth_looptag(me, mlooptag);
-
- MEM_freeN(mlooptag);
+ vertex_color_smooth_looptag(me, loop_tag.data());
tag_object_after_update(ob);
@@ -268,7 +268,8 @@ static void vpaint_tx_brightness_contrast(const float col[3],
const void *user_data,
float r_col[3])
{
- const struct VPaintTx_BrightContrastData *data = user_data;
+ const VPaintTx_BrightContrastData *data = static_cast<const VPaintTx_BrightContrastData *>(
+ user_data);
for (int i = 0; i < 3; i++) {
r_col[i] = data->gain * col[i] + data->offset;
@@ -302,10 +303,9 @@ static int vertex_color_brightness_contrast_exec(bContext *C, wmOperator *op)
}
}
- const struct VPaintTx_BrightContrastData user_data = {
- .gain = gain,
- .offset = offset,
- };
+ VPaintTx_BrightContrastData user_data{};
+ user_data.gain = gain;
+ user_data.offset = offset;
if (ED_vpaint_color_transform(obact, vpaint_tx_brightness_contrast, &user_data)) {
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
@@ -345,7 +345,7 @@ struct VPaintTx_HueSatData {
static void vpaint_tx_hsv(const float col[3], const void *user_data, float r_col[3])
{
- const struct VPaintTx_HueSatData *data = user_data;
+ const VPaintTx_HueSatData *data = static_cast<const VPaintTx_HueSatData *>(user_data);
float hsv[3];
rgb_to_hsv_v(col, hsv);
@@ -366,11 +366,10 @@ static int vertex_color_hsv_exec(bContext *C, wmOperator *op)
{
Object *obact = CTX_data_active_object(C);
- const struct VPaintTx_HueSatData user_data = {
- .hue = RNA_float_get(op->ptr, "h"),
- .sat = RNA_float_get(op->ptr, "s"),
- .val = RNA_float_get(op->ptr, "v"),
- };
+ VPaintTx_HueSatData user_data{};
+ user_data.hue = RNA_float_get(op->ptr, "h");
+ user_data.sat = RNA_float_get(op->ptr, "s");
+ user_data.val = RNA_float_get(op->ptr, "v");
if (ED_vpaint_color_transform(obact, vpaint_tx_hsv, &user_data)) {
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
@@ -410,7 +409,7 @@ static int vertex_color_invert_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *obact = CTX_data_active_object(C);
- if (ED_vpaint_color_transform(obact, vpaint_tx_invert, NULL)) {
+ if (ED_vpaint_color_transform(obact, vpaint_tx_invert, nullptr)) {
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
return OPERATOR_FINISHED;
}
@@ -439,7 +438,7 @@ struct VPaintTx_LevelsData {
static void vpaint_tx_levels(const float col[3], const void *user_data, float r_col[3])
{
- const struct VPaintTx_LevelsData *data = user_data;
+ const VPaintTx_LevelsData *data = static_cast<const VPaintTx_LevelsData *>(user_data);
for (int i = 0; i < 3; i++) {
r_col[i] = data->gain * (col[i] + data->offset);
}
@@ -449,10 +448,9 @@ static int vertex_color_levels_exec(bContext *C, wmOperator *op)
{
Object *obact = CTX_data_active_object(C);
- const struct VPaintTx_LevelsData user_data = {
- .gain = RNA_float_get(op->ptr, "gain"),
- .offset = RNA_float_get(op->ptr, "offset"),
- };
+ VPaintTx_LevelsData user_data{};
+ user_data.gain = RNA_float_get(op->ptr, "gain");
+ user_data.offset = RNA_float_get(op->ptr, "offset");
if (ED_vpaint_color_transform(obact, vpaint_tx_levels, &user_data)) {
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 5f52e1a3071..a73883e7624 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -860,6 +860,7 @@ static void clip_main_region_draw(const bContext *C, ARegion *region)
sc->mask_info.draw_flag,
sc->mask_info.draw_type,
sc->mask_info.overlay_mode,
+ sc->mask_info.blend_factor,
mask_width,
mask_height,
aspx,
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index fa49e996c2a..537132ac428 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -964,7 +964,7 @@ static int image_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
static bool image_view_selected_poll(bContext *C)
{
- return (space_image_main_region_poll(C) && (ED_operator_uvedit(C) || ED_operator_mask(C)));
+ return (space_image_main_region_poll(C) && (ED_operator_uvedit(C) || ED_maskedit_poll(C)));
}
void IMAGE_OT_view_selected(wmOperatorType *ot)
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index ab8143c5bf5..785a5419e04 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -694,6 +694,7 @@ static void image_main_region_draw(const bContext *C, ARegion *region)
sima->mask_info.draw_flag & ~MASK_DRAWFLAG_OVERLAY,
sima->mask_info.draw_type,
sima->mask_info.overlay_mode,
+ sima->mask_info.blend_factor,
width,
height,
aspx,
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index 6c631f46069..bb9e201d94a 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -621,7 +621,6 @@ static void nla_draw_strip(SpaceNla *snla,
static void nla_draw_strip_text(AnimData *adt,
NlaTrack *nlt,
NlaStrip *strip,
- int index,
View2D *v2d,
float xminc,
float xmaxc,
@@ -636,7 +635,7 @@ static void nla_draw_strip_text(AnimData *adt,
/* just print the name and the range */
if (strip->flag & NLASTRIP_FLAG_TEMP_META) {
- str_len = BLI_snprintf_rlen(str, sizeof(str), "%d) Temp-Meta", index);
+ str_len = BLI_snprintf_rlen(str, sizeof(str), "Temp-Meta");
}
else {
str_len = BLI_strncpy_rlen(str, strip->name, sizeof(str));
@@ -702,6 +701,89 @@ static void nla_draw_strip_frames_text(
/* ---------------------- */
+/**
+ * Gets the first and last visible NLA strips on a track.
+ * Note that this also includes tracks that might only be
+ * visible because of their extendmode.
+ */
+static ListBase get_visible_nla_strips(NlaTrack *nlt, View2D *v2d)
+{
+ if (BLI_listbase_is_empty(&nlt->strips)) {
+ ListBase empty = {NULL, NULL};
+ return empty;
+ }
+
+ NlaStrip *first = NULL;
+ NlaStrip *last = NULL;
+
+ /* Find the first strip that is within the bounds of the view. */
+ LISTBASE_FOREACH (NlaStrip *, strip, &nlt->strips) {
+ if (BKE_nlastrip_within_bounds(strip, v2d->cur.xmin, v2d->cur.xmax)) {
+ first = last = strip;
+ break;
+ }
+ }
+
+ const bool has_strips_within_bounds = first != NULL;
+
+ if (has_strips_within_bounds) {
+ /* Find the last visible strip. */
+ for (NlaStrip *strip = first->next; strip; strip = strip->next) {
+ if (!BKE_nlastrip_within_bounds(strip, v2d->cur.xmin, v2d->cur.xmax)) {
+ break;
+ }
+ last = strip;
+ }
+ /* Check if the first strip is adjacent to a strip outside the view to the left
+ * that has an extendmode region that should be drawn.
+ * If so, adjust the first strip to include drawing that strip as well.
+ */
+ NlaStrip *prev = first->prev;
+ if (prev && prev->extendmode != NLASTRIP_EXTEND_NOTHING) {
+ first = prev;
+ }
+ }
+ else {
+ /* No immediately visible strips.
+ * Figure out where our view is relative to the strips, then determine
+ * if the view is adjacent to a strip that should have its extendmode
+ * rendered.
+ */
+ NlaStrip *first_strip = nlt->strips.first;
+ NlaStrip *last_strip = nlt->strips.last;
+ if (first_strip && v2d->cur.xmax < first_strip->start &&
+ first_strip->extendmode == NLASTRIP_EXTEND_HOLD) {
+ /* The view is to the left of all strips and the first strip has an
+ * extendmode that should be drawn.
+ */
+ first = last = first_strip;
+ }
+ else if (last_strip && v2d->cur.xmin > last_strip->end &&
+ last_strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
+ /* The view is to the right of all strips and the last strip has an
+ * extendmode that should be drawn.
+ */
+ first = last = last_strip;
+ }
+ else {
+ /* The view is in the middle of two strips. */
+ LISTBASE_FOREACH (NlaStrip *, strip, &nlt->strips) {
+ /* Find the strip to the left by finding the strip to the right and getting its prev. */
+ if (v2d->cur.xmax < strip->start) {
+ /* If the strip to the left has an extendmode, set that as the only visible strip. */
+ if (strip->prev && strip->prev->extendmode != NLASTRIP_EXTEND_NOTHING) {
+ first = last = strip->prev;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ ListBase visible_strips = {first, last};
+ return visible_strips;
+}
+
void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *region)
{
View2D *v2d = &region->v2d;
@@ -737,29 +819,26 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *region)
case ANIMTYPE_NLATRACK: {
AnimData *adt = ale->adt;
NlaTrack *nlt = (NlaTrack *)ale->data;
- NlaStrip *strip;
- int index;
-
- /* draw each strip in the track (if visible) */
- for (strip = nlt->strips.first, index = 1; strip; strip = strip->next, index++) {
- if (BKE_nlastrip_within_bounds(strip, v2d->cur.xmin, v2d->cur.xmax)) {
- const float xminc = strip->start + text_margin_x;
- const float xmaxc = strip->end - text_margin_x;
-
- /* draw the visualization of the strip */
- nla_draw_strip(snla, adt, nlt, strip, v2d, ymin, ymax);
-
- /* add the text for this strip to the cache */
- if (xminc < xmaxc) {
- nla_draw_strip_text(adt, nlt, strip, index, v2d, xminc, xmaxc, ymin, ymax);
- }
-
- /* if transforming strips (only real reason for temp-metas currently),
- * add to the cache the frame numbers of the strip's extents
- */
- if (strip->flag & NLASTRIP_FLAG_TEMP_META) {
- nla_draw_strip_frames_text(nlt, strip, v2d, ymin, ymax);
- }
+ ListBase visible_nla_strips = get_visible_nla_strips(nlt, v2d);
+
+ /* Draw each visible strip in the track. */
+ LISTBASE_FOREACH (NlaStrip *, strip, &visible_nla_strips) {
+ const float xminc = strip->start + text_margin_x;
+ const float xmaxc = strip->end - text_margin_x;
+
+ /* draw the visualization of the strip */
+ nla_draw_strip(snla, adt, nlt, strip, v2d, ymin, ymax);
+
+ /* add the text for this strip to the cache */
+ if (xminc < xmaxc) {
+ nla_draw_strip_text(adt, nlt, strip, v2d, xminc, xmaxc, ymin, ymax);
+ }
+
+ /* if transforming strips (only real reason for temp-metas currently),
+ * add to the cache the frame numbers of the strip's extents
+ */
+ if (strip->flag & NLASTRIP_FLAG_TEMP_META) {
+ nla_draw_strip_frames_text(nlt, strip, v2d, ymin, ymax);
}
}
break;
diff --git a/source/blender/editors/util/select_utils.c b/source/blender/editors/util/select_utils.c
index 263ef06718f..660afa4c3d7 100644
--- a/source/blender/editors/util/select_utils.c
+++ b/source/blender/editors/util/select_utils.c
@@ -66,15 +66,18 @@ eSelectOp ED_select_op_modal(const eSelectOp sel_op, const bool is_first)
return sel_op;
}
-int ED_select_similar_compare_float(const float delta, const float thresh, const int compare)
+bool ED_select_similar_compare_float(const float delta,
+ const float thresh,
+ const eSimilarCmp compare)
{
+ BLI_assert(thresh >= 0.0f);
switch (compare) {
case SIM_CMP_EQ:
return (fabsf(delta) <= thresh);
case SIM_CMP_GT:
- return ((delta + thresh) >= 0.0);
+ return ((delta + thresh) >= 0.0f);
case SIM_CMP_LT:
- return ((delta - thresh) <= 0.0);
+ return ((delta - thresh) <= 0.0f);
default:
BLI_assert_unreachable();
return 0;
@@ -84,8 +87,10 @@ int ED_select_similar_compare_float(const float delta, const float thresh, const
bool ED_select_similar_compare_float_tree(const KDTree_1d *tree,
const float length,
const float thresh,
- const int compare)
+ const eSimilarCmp compare)
{
+ BLI_assert(compare == SIM_CMP_EQ || length >= 0.0f); /* See precision note below. */
+
/* Length of the edge we want to compare against. */
float nearest_edge_length;
@@ -112,6 +117,7 @@ bool ED_select_similar_compare_float_tree(const KDTree_1d *tree,
KDTreeNearest_1d nearest;
if (BLI_kdtree_1d_find_nearest(tree, &nearest_edge_length, &nearest) != -1) {
+ BLI_assert(compare == SIM_CMP_EQ || nearest.co[0] >= 0.0f); /* See precision note above. */
float delta = length - nearest.co[0];
return ED_select_similar_compare_float(delta, thresh, compare);
}
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index 181982f0b2c..04128cf378c 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -182,5 +182,6 @@ void UV_OT_select_circle(struct wmOperatorType *ot);
void UV_OT_select_more(struct wmOperatorType *ot);
void UV_OT_select_less(struct wmOperatorType *ot);
void UV_OT_select_overlap(struct wmOperatorType *ot);
+void UV_OT_select_similar(struct wmOperatorType *ot);
/* Used only when UV sync select is disabled. */
void UV_OT_select_mode(struct wmOperatorType *ot);
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index fe6f9f0d513..0b5d6592426 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -2044,6 +2044,7 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_select_pinned);
WM_operatortype_append(UV_OT_select_box);
WM_operatortype_append(UV_OT_select_lasso);
+ WM_operatortype_append(UV_OT_select_similar);
WM_operatortype_append(UV_OT_select_circle);
WM_operatortype_append(UV_OT_select_more);
WM_operatortype_append(UV_OT_select_less);
diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c
index cea2bb05547..8dcf2ceb679 100644
--- a/source/blender/editors/uvedit/uvedit_select.c
+++ b/source/blender/editors/uvedit/uvedit_select.c
@@ -12,6 +12,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_image_types.h"
+#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
@@ -22,6 +23,7 @@
#include "BLI_blenlib.h"
#include "BLI_hash.h"
#include "BLI_kdopbvh.h"
+#include "BLI_kdtree.h"
#include "BLI_lasso_2d.h"
#include "BLI_math.h"
#include "BLI_polyfill_2d.h"
@@ -31,6 +33,7 @@
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_layer.h"
+#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_report.h"
@@ -75,6 +78,16 @@ static void uv_select_tag_update_for_object(Depsgraph *depsgraph,
const ToolSettings *ts,
Object *obedit);
+typedef enum {
+ UV_SSIM_AREA_UV = 1000,
+ UV_SSIM_AREA_3D,
+ UV_SSIM_LENGTH_UV,
+ UV_SSIM_LENGTH_3D,
+ UV_SSIM_SIDES,
+ UV_SSIM_PIN,
+ UV_SSIM_MATERIAL,
+} eUVSelectSimilar;
+
/* -------------------------------------------------------------------- */
/** \name Active Selection Tracking
*
@@ -586,12 +599,25 @@ bool uvedit_uv_select_test_ex(const ToolSettings *ts, BMLoop *l, const int cd_lo
if (ts->selectmode & SCE_SELECT_FACE) {
return BM_elem_flag_test_bool(l->f, BM_ELEM_SELECT);
}
+ if (ts->selectmode & SCE_SELECT_EDGE) {
+ /* Are you looking for `uvedit_edge_select_test(...)` instead? */
+ }
return BM_elem_flag_test_bool(l->v, BM_ELEM_SELECT);
}
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+
+ if (ts->selectmode & SCE_SELECT_FACE) {
+ /* Are you looking for `uvedit_face_select_test(...)` instead? */
+ }
+
+ if (ts->selectmode & SCE_SELECT_EDGE) {
+ /* Are you looking for `uvedit_edge_select_test(...)` instead? */
+ }
+
return (luv->flag & MLOOPUV_VERTSEL) != 0;
}
+
bool uvedit_uv_select_test(const Scene *scene, BMLoop *l, const int cd_loop_uv_offset)
{
return uvedit_uv_select_test_ex(scene->toolsettings, l, cd_loop_uv_offset);
@@ -699,6 +725,10 @@ void uvedit_uv_select_enable(const Scene *scene,
{
const ToolSettings *ts = scene->toolsettings;
+ if (ts->selectmode & SCE_SELECT_EDGE) {
+ /* Are you looking for `uvedit_edge_select_set(...)` instead? */
+ }
+
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (ts->selectmode & SCE_SELECT_FACE) {
BM_face_select_set(em->bm, l->f, true);
@@ -4412,6 +4442,550 @@ void UV_OT_select_overlap(wmOperatorType *ot)
}
/** \} */
+/** \name Select Similar Operator
+ * \{ */
+
+static float get_uv_vert_needle(const eUVSelectSimilar type,
+ BMVert *vert,
+ const float ob_m3[3][3],
+ MLoopUV *luv,
+ const int cd_loop_uv_offset)
+{
+ float result = 0.0f;
+ switch (type) {
+ case UV_SSIM_AREA_UV: {
+ BMFace *f;
+ BMIter iter;
+ BM_ITER_ELEM (f, &iter, vert, BM_FACES_OF_VERT) {
+ result += BM_face_calc_area_uv(f, cd_loop_uv_offset);
+ }
+ } break;
+ case UV_SSIM_AREA_3D: {
+ BMFace *f;
+ BMIter iter;
+ BM_ITER_ELEM (f, &iter, vert, BM_FACES_OF_VERT) {
+ result += BM_face_calc_area_with_mat3(f, ob_m3);
+ }
+ } break;
+ case UV_SSIM_SIDES: {
+ BMEdge *e;
+ BMIter iter;
+ BM_ITER_ELEM (e, &iter, vert, BM_EDGES_OF_VERT) {
+ result += 1.0f;
+ }
+ } break;
+ case UV_SSIM_PIN:
+ return (luv->flag & MLOOPUV_PINNED) ? 1.0f : 0.0f;
+ default:
+ BLI_assert_unreachable();
+ return false;
+ }
+
+ return result;
+}
+
+static float get_uv_edge_needle(const eUVSelectSimilar type,
+ BMEdge *edge,
+ const float ob_m3[3][3],
+ MLoopUV *luv_a,
+ MLoopUV *luv_b,
+ const int cd_loop_uv_offset)
+{
+ float result = 0.0f;
+ switch (type) {
+ case UV_SSIM_AREA_UV: {
+ BMFace *f;
+ BMIter iter;
+ BM_ITER_ELEM (f, &iter, edge, BM_FACES_OF_EDGE) {
+ result += BM_face_calc_area_uv(f, cd_loop_uv_offset);
+ }
+ } break;
+ case UV_SSIM_AREA_3D: {
+ BMFace *f;
+ BMIter iter;
+ BM_ITER_ELEM (f, &iter, edge, BM_FACES_OF_EDGE) {
+ result += BM_face_calc_area_with_mat3(f, ob_m3);
+ }
+ } break;
+ case UV_SSIM_LENGTH_UV:
+ return len_v2v2(luv_a->uv, luv_b->uv);
+ case UV_SSIM_LENGTH_3D:
+ return len_v3v3(edge->v1->co, edge->v2->co);
+ case UV_SSIM_SIDES: {
+ BMEdge *e;
+ BMIter iter;
+ BM_ITER_ELEM (e, &iter, edge, BM_FACES_OF_EDGE) {
+ result += 1.0f;
+ }
+ } break;
+ case UV_SSIM_PIN:
+ if (luv_a->flag & MLOOPUV_PINNED) {
+ result += 1.0f;
+ }
+ if (luv_b->flag & MLOOPUV_PINNED) {
+ result += 1.0f;
+ }
+ break;
+ default:
+ BLI_assert_unreachable();
+ return false;
+ }
+
+ return result;
+}
+
+static float get_uv_face_needle(const eUVSelectSimilar type,
+ BMFace *face,
+ const float ob_m3[3][3],
+ const int cd_loop_uv_offset)
+{
+ float result = 0.0f;
+ switch (type) {
+ case UV_SSIM_AREA_UV:
+ return BM_face_calc_area_uv(face, cd_loop_uv_offset);
+ case UV_SSIM_AREA_3D:
+ return BM_face_calc_area_with_mat3(face, ob_m3);
+ case UV_SSIM_SIDES:
+ return face->len;
+ case UV_SSIM_PIN: {
+ BMLoop *l;
+ BMIter liter;
+ BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) {
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ if (luv->flag & MLOOPUV_PINNED) {
+ result += 1.0f;
+ }
+ }
+ } break;
+ case UV_SSIM_MATERIAL:
+ return face->mat_nr;
+ default:
+ BLI_assert_unreachable();
+ return false;
+ }
+ return result;
+}
+
+static int uv_select_similar_vert_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+
+ const eUVSelectSimilar type = RNA_enum_get(op->ptr, "type");
+ const float threshold = RNA_float_get(op->ptr, "threshold");
+ const eSimilarCmp compare = RNA_enum_get(op->ptr, "compare");
+
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
+ view_layer, ((View3D *)NULL), &objects_len);
+
+ int max_verts_selected_all = 0;
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+ BMFace *face;
+ BMIter iter;
+ BM_ITER_MESH (face, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (!uvedit_face_visible_test(scene, face)) {
+ continue;
+ }
+ max_verts_selected_all += face->len;
+ }
+ /* TODO: Get a tighter bounds */
+ }
+
+ int tree_index = 0;
+ KDTree_1d *tree_1d = BLI_kdtree_1d_new(max_verts_selected_all);
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+ BMesh *bm = em->bm;
+ if (bm->totvertsel == 0) {
+ continue;
+ }
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ float ob_m3[3][3];
+ copy_m3_m4(ob_m3, ob->obmat);
+
+ BMFace *face;
+ BMIter iter;
+ BM_ITER_MESH (face, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (!uvedit_face_visible_test(scene, face)) {
+ continue;
+ }
+ BMLoop *l;
+ BMIter liter;
+ BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) {
+ if (!uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ continue;
+ }
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ float needle = get_uv_vert_needle(type, l->v, ob_m3, luv, cd_loop_uv_offset);
+ BLI_kdtree_1d_insert(tree_1d, tree_index++, &needle);
+ }
+ }
+ }
+
+ if (tree_1d != NULL) {
+ BLI_kdtree_1d_deduplicate(tree_1d);
+ BLI_kdtree_1d_balance(tree_1d);
+ }
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+ BMesh *bm = em->bm;
+ if (bm->totvertsel == 0) {
+ continue;
+ }
+
+ bool changed = false;
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ float ob_m3[3][3];
+ copy_m3_m4(ob_m3, ob->obmat);
+
+ BMFace *face;
+ BMIter iter;
+ BM_ITER_MESH (face, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (!uvedit_face_visible_test(scene, face)) {
+ continue;
+ }
+ BMLoop *l;
+ BMIter liter;
+ BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) {
+ if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ continue; /* Already selected. */
+ }
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ const float needle = get_uv_vert_needle(type, l->v, ob_m3, luv, cd_loop_uv_offset);
+ bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare);
+ if (select) {
+ uvedit_uv_select_set(scene, em, l, select, false, cd_loop_uv_offset);
+ changed = true;
+ }
+ }
+ if (changed) {
+ uv_select_tag_update_for_object(depsgraph, ts, ob);
+ }
+ }
+ }
+
+ MEM_SAFE_FREE(objects);
+ BLI_kdtree_1d_free(tree_1d);
+ return OPERATOR_FINISHED;
+}
+
+static int uv_select_similar_edge_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+
+ const eUVSelectSimilar type = RNA_enum_get(op->ptr, "type");
+ const float threshold = RNA_float_get(op->ptr, "threshold");
+ const eSimilarCmp compare = RNA_enum_get(op->ptr, "compare");
+
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
+ view_layer, ((View3D *)NULL), &objects_len);
+
+ int max_edges_selected_all = 0;
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+ BMFace *face;
+ BMIter iter;
+ BM_ITER_MESH (face, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (!uvedit_face_visible_test(scene, face)) {
+ continue;
+ }
+ max_edges_selected_all += face->len;
+ }
+ /* TODO: Get a tighter bounds. */
+ }
+
+ int tree_index = 0;
+ KDTree_1d *tree_1d = BLI_kdtree_1d_new(max_edges_selected_all);
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+ BMesh *bm = em->bm;
+ if (bm->totvertsel == 0) {
+ continue;
+ }
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ float ob_m3[3][3];
+ copy_m3_m4(ob_m3, ob->obmat);
+
+ BMFace *face;
+ BMIter iter;
+ BM_ITER_MESH (face, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (!uvedit_face_visible_test(scene, face)) {
+ continue;
+ }
+ BMLoop *l;
+ BMIter liter;
+ BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) {
+ if (!uvedit_edge_select_test(scene, l, cd_loop_uv_offset)) {
+ continue;
+ }
+
+ MLoopUV *luv_a = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ MLoopUV *luv_b = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
+ float needle = get_uv_edge_needle(type, l->e, ob_m3, luv_a, luv_b, cd_loop_uv_offset);
+ if (tree_1d) {
+ BLI_kdtree_1d_insert(tree_1d, tree_index++, &needle);
+ }
+ }
+ }
+ }
+
+ if (tree_1d != NULL) {
+ BLI_kdtree_1d_deduplicate(tree_1d);
+ BLI_kdtree_1d_balance(tree_1d);
+ }
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+ BMesh *bm = em->bm;
+ if (bm->totvertsel == 0) {
+ continue;
+ }
+
+ bool changed = false;
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ float ob_m3[3][3];
+ copy_m3_m4(ob_m3, ob->obmat);
+
+ BMFace *face;
+ BMIter iter;
+ BM_ITER_MESH (face, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (!uvedit_face_visible_test(scene, face)) {
+ continue;
+ }
+ BMLoop *l;
+ BMIter liter;
+ BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) {
+ if (uvedit_edge_select_test(scene, l, cd_loop_uv_offset)) {
+ continue; /* Already selected. */
+ }
+
+ MLoopUV *luv_a = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ MLoopUV *luv_b = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
+ float needle = get_uv_edge_needle(type, l->e, ob_m3, luv_a, luv_b, cd_loop_uv_offset);
+ bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare);
+ if (select) {
+ uvedit_edge_select_set(scene, em, l, select, false, cd_loop_uv_offset);
+ changed = true;
+ }
+ }
+ if (changed) {
+ uv_select_tag_update_for_object(depsgraph, ts, ob);
+ }
+ }
+ }
+
+ MEM_SAFE_FREE(objects);
+ BLI_kdtree_1d_free(tree_1d);
+ return OPERATOR_FINISHED;
+}
+
+static int uv_select_similar_face_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+
+ const eUVSelectSimilar type = RNA_enum_get(op->ptr, "type");
+ const float threshold = RNA_float_get(op->ptr, "threshold");
+ const eSimilarCmp compare = RNA_enum_get(op->ptr, "compare");
+
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
+ view_layer, ((View3D *)NULL), &objects_len);
+
+ int max_faces_selected_all = 0;
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+ max_faces_selected_all += em->bm->totfacesel;
+ /* TODO: Get a tighter bounds */
+ }
+
+ int tree_index = 0;
+ KDTree_1d *tree_1d = BLI_kdtree_1d_new(max_faces_selected_all);
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
+
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+ BMesh *bm = em->bm;
+
+ float ob_m3[3][3];
+ copy_m3_m4(ob_m3, ob->obmat);
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+
+ BMFace *face;
+ BMIter iter;
+ BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) {
+ if (!uvedit_face_visible_test(scene, face)) {
+ continue;
+ }
+ if (!uvedit_face_select_test(scene, face, cd_loop_uv_offset)) {
+ continue;
+ }
+
+ float needle = get_uv_face_needle(type, face, ob_m3, cd_loop_uv_offset);
+ if (tree_1d) {
+ BLI_kdtree_1d_insert(tree_1d, tree_index++, &needle);
+ }
+ }
+ }
+
+ if (tree_1d != NULL) {
+ BLI_kdtree_1d_deduplicate(tree_1d);
+ BLI_kdtree_1d_balance(tree_1d);
+ }
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
+
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+ BMesh *bm = em->bm;
+ bool changed = false;
+ bool do_history = false;
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+
+ float ob_m3[3][3];
+ copy_m3_m4(ob_m3, ob->obmat);
+
+ BMFace *face;
+ BMIter iter;
+ BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) {
+ if (!uvedit_face_visible_test(scene, face)) {
+ continue;
+ }
+ if (uvedit_face_select_test(scene, face, cd_loop_uv_offset)) {
+ continue;
+ }
+
+ float needle = get_uv_face_needle(type, face, ob_m3, cd_loop_uv_offset);
+
+ bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare);
+ if (select) {
+ uvedit_face_select_set(scene, em, face, select, do_history, cd_loop_uv_offset);
+ changed = true;
+ }
+ }
+ if (changed) {
+ uv_select_tag_update_for_object(depsgraph, ts, ob);
+ }
+ }
+
+ MEM_SAFE_FREE(objects);
+ BLI_kdtree_1d_free(tree_1d);
+ return OPERATOR_FINISHED;
+}
+
+/* Select similar UV faces/edges/verts based on current selection. */
+static int uv_select_similar_exec(bContext *C, wmOperator *op)
+{
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "threshold");
+
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_float_set(op->ptr, prop, ts->select_thresh);
+ }
+ else {
+ ts->select_thresh = RNA_property_float_get(op->ptr, prop);
+ }
+
+ int selectmode = (ts->uv_flag & UV_SYNC_SELECTION) ? ts->selectmode : ts->uv_selectmode;
+ if (selectmode & UV_SELECT_EDGE) {
+ return uv_select_similar_edge_exec(C, op);
+ }
+ else if (selectmode & UV_SELECT_FACE) {
+ return uv_select_similar_face_exec(C, op);
+ }
+ if (selectmode & UV_SELECT_ISLAND) {
+ // return uv_select_similar_island_exec(C, op);
+ }
+
+ return uv_select_similar_vert_exec(C, op);
+}
+
+static EnumPropertyItem prop_vert_similar_types[] = {{UV_SSIM_PIN, "PIN", 0, "Pinned", ""}, {0}};
+
+static EnumPropertyItem prop_edge_similar_types[] = {
+ {UV_SSIM_LENGTH_UV, "LENGTH", 0, "Length", ""},
+ {UV_SSIM_LENGTH_3D, "LENGTH_3D", 0, "Length 3D", ""},
+ {UV_SSIM_PIN, "PIN", 0, "Pinned", ""},
+ {0}};
+
+static EnumPropertyItem prop_face_similar_types[] = {
+ {UV_SSIM_AREA_UV, "AREA", 0, "Area", ""},
+ {UV_SSIM_AREA_3D, "AREA_3D", 0, "Area 3D", ""},
+ {UV_SSIM_SIDES, "SIDES", 0, "Polygon Sides", ""},
+ {UV_SSIM_MATERIAL, "MATERIAL", 0, "Material", ""},
+ {0}};
+
+static EnumPropertyItem prop_similar_compare_types[] = {{SIM_CMP_EQ, "EQUAL", 0, "Equal", ""},
+ {SIM_CMP_GT, "GREATER", 0, "Greater", ""},
+ {SIM_CMP_LT, "LESS", 0, "Less", ""},
+ {0}};
+
+static const EnumPropertyItem *uv_select_similar_type_itemf(bContext *C,
+ PointerRNA *UNUSED(ptr),
+ PropertyRNA *UNUSED(prop),
+ bool *UNUSED(r_free))
+{
+ const ToolSettings *ts = CTX_data_tool_settings(C);
+ if (ts) {
+ int selectmode = (ts->uv_flag & UV_SYNC_SELECTION) ? ts->selectmode : ts->uv_selectmode;
+ if (selectmode & UV_SELECT_EDGE) {
+ return prop_edge_similar_types;
+ }
+ if (selectmode & UV_SELECT_FACE) {
+ return prop_face_similar_types;
+ }
+ }
+
+ return prop_vert_similar_types;
+}
+void UV_OT_select_similar(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Similar";
+ ot->description = "Select similar UVs by property types";
+ ot->idname = "UV_OT_select_similar";
+
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = uv_select_similar_exec;
+ ot->poll = ED_operator_uvedit_space_image;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ PropertyRNA *prop = ot->prop = RNA_def_enum(
+ ot->srna, "type", prop_vert_similar_types, SIMVERT_NORMAL, "Type", "");
+ RNA_def_enum_funcs(prop, uv_select_similar_type_itemf);
+ RNA_def_enum(ot->srna, "compare", prop_similar_compare_types, SIM_CMP_EQ, "Compare", "");
+ RNA_def_float(ot->srna, "threshold", 0.0f, 0.0f, 1.0f, "Threshold", "", 0.0f, 1.0f);
+}
+
+/** \} */
/* -------------------------------------------------------------------- */
/** \name Selected Elements as Arrays (Vertex, Edge & Faces)
diff --git a/source/blender/functions/FN_multi_function_procedure.hh b/source/blender/functions/FN_multi_function_procedure.hh
index 75a54992a48..da269b08155 100644
--- a/source/blender/functions/FN_multi_function_procedure.hh
+++ b/source/blender/functions/FN_multi_function_procedure.hh
@@ -87,7 +87,7 @@ class MFVariable : NonCopyable, NonMovable {
MFDataType data_type_;
Vector<MFInstruction *> users_;
std::string name_;
- int id_;
+ int index_in_graph_;
friend MFProcedure;
friend MFCallInstruction;
@@ -101,7 +101,7 @@ class MFVariable : NonCopyable, NonMovable {
StringRefNull name() const;
void set_name(std::string name);
- int id() const;
+ int index_in_procedure() const;
};
/** Base class for all instruction types. */
@@ -376,9 +376,9 @@ inline StringRefNull MFVariable::name() const
return name_;
}
-inline int MFVariable::id() const
+inline int MFVariable::index_in_procedure() const
{
- return id_;
+ return index_in_graph_;
}
/** \} */
diff --git a/source/blender/functions/intern/multi_function_procedure.cc b/source/blender/functions/intern/multi_function_procedure.cc
index bc045bfd44b..7ad324a9574 100644
--- a/source/blender/functions/intern/multi_function_procedure.cc
+++ b/source/blender/functions/intern/multi_function_procedure.cc
@@ -173,7 +173,7 @@ MFVariable &MFProcedure::new_variable(MFDataType data_type, std::string name)
MFVariable &variable = *allocator_.construct<MFVariable>().release();
variable.name_ = std::move(name);
variable.data_type_ = data_type;
- variable.id_ = variables_.size();
+ variable.index_in_graph_ = variables_.size();
variables_.append(&variable);
return variable;
}
@@ -753,7 +753,7 @@ class MFProcedureDotExport {
ss << "null";
}
else {
- ss << "$" << variable->id();
+ ss << "$" << variable->index_in_procedure();
if (!variable->name().is_empty()) {
ss << "(" << variable->name() << ")";
}
diff --git a/source/blender/functions/intern/multi_function_procedure_executor.cc b/source/blender/functions/intern/multi_function_procedure_executor.cc
index d852fe19924..a45240dad55 100644
--- a/source/blender/functions/intern/multi_function_procedure_executor.cc
+++ b/source/blender/functions/intern/multi_function_procedure_executor.cc
@@ -157,10 +157,6 @@ class ValueAllocator : NonCopyable, NonMovable {
{
}
- template<typename... Args> VariableState *obtain_variable_state(Args &&...args);
-
- void release_variable_state(VariableState *state);
-
VariableValue_GVArray *obtain_GVArray(const GVArray &varray)
{
return this->obtain<VariableValue_GVArray>(varray);
@@ -294,32 +290,27 @@ class ValueAllocator : NonCopyable, NonMovable {
* This class keeps track of a single variable during evaluation.
*/
class VariableState : NonCopyable, NonMovable {
- private:
+ public:
/** The current value of the variable. The storage format may change over time. */
- VariableValue *value_;
+ VariableValue *value_ = nullptr;
/** Number of indices that are currently initialized in this variable. */
- int tot_initialized_;
+ int tot_initialized_ = 0;
/* This a non-owning pointer to either span buffer or #GVectorArray or null. */
void *caller_provided_storage_ = nullptr;
- public:
- VariableState(VariableValue &value, int tot_initialized, void *caller_provided_storage = nullptr)
- : value_(&value),
- tot_initialized_(tot_initialized),
- caller_provided_storage_(caller_provided_storage)
- {
- }
-
- void destruct_self(ValueAllocator &value_allocator, const MFDataType &data_type)
+ void destruct_value(ValueAllocator &value_allocator, const MFDataType &data_type)
{
value_allocator.release_value(value_, data_type);
- value_allocator.release_variable_state(this);
+ value_ = nullptr;
}
/* True if this contains only one value for all indices, i.e. the value for all indices is
* the same. */
bool is_one() const
{
+ if (value_ == nullptr) {
+ return true;
+ }
switch (value_->type) {
case ValueType::GVArray:
return this->value_as<VariableValue_GVArray>()->data.is_single();
@@ -353,6 +344,7 @@ class VariableState : NonCopyable, NonMovable {
{
/* Sanity check to make sure that enough values are initialized. */
BLI_assert(mask.size() <= tot_initialized_);
+ BLI_assert(value_ != nullptr);
switch (value_->type) {
case ValueType::GVArray: {
@@ -391,7 +383,7 @@ class VariableState : NonCopyable, NonMovable {
const MFDataType &data_type,
ValueAllocator &value_allocator)
{
- if (ELEM(value_->type, ValueType::Span, ValueType::GVectorArray)) {
+ if (value_ != nullptr && ELEM(value_->type, ValueType::Span, ValueType::GVectorArray)) {
return;
}
@@ -408,22 +400,24 @@ class VariableState : NonCopyable, NonMovable {
/* Reuse the storage provided caller when possible. */
new_value = value_allocator.obtain_Span_not_owned(caller_provided_storage_);
}
- if (value_->type == ValueType::GVArray) {
- /* Fill new buffer with data from virtual array. */
- this->value_as<VariableValue_GVArray>()->data.materialize_to_uninitialized(
- full_mask, new_value->data);
- }
- else if (value_->type == ValueType::OneSingle) {
- auto *old_value_typed_ = this->value_as<VariableValue_OneSingle>();
- if (old_value_typed_->is_initialized) {
- /* Fill the buffer with a single value. */
- type.fill_construct_indices(old_value_typed_->data, new_value->data, full_mask);
+ if (value_ != nullptr) {
+ if (value_->type == ValueType::GVArray) {
+ /* Fill new buffer with data from virtual array. */
+ this->value_as<VariableValue_GVArray>()->data.materialize_to_uninitialized(
+ full_mask, new_value->data);
}
+ else if (value_->type == ValueType::OneSingle) {
+ auto *old_value_typed_ = this->value_as<VariableValue_OneSingle>();
+ if (old_value_typed_->is_initialized) {
+ /* Fill the buffer with a single value. */
+ type.fill_construct_indices(old_value_typed_->data, new_value->data, full_mask);
+ }
+ }
+ else {
+ BLI_assert_unreachable();
+ }
+ value_allocator.release_value(value_, data_type);
}
- else {
- BLI_assert_unreachable();
- }
- value_allocator.release_value(value_, data_type);
value_ = new_value;
break;
}
@@ -437,19 +431,21 @@ class VariableState : NonCopyable, NonMovable {
new_value = value_allocator.obtain_GVectorArray_not_owned(
*(GVectorArray *)caller_provided_storage_);
}
- if (value_->type == ValueType::GVVectorArray) {
- /* Fill new vector array with data from virtual vector array. */
- new_value->data.extend(full_mask, this->value_as<VariableValue_GVVectorArray>()->data);
- }
- else if (value_->type == ValueType::OneVector) {
- /* Fill all indices with the same value. */
- const GSpan vector = this->value_as<VariableValue_OneVector>()->data[0];
- new_value->data.extend(full_mask, GVVectorArray_For_SingleGSpan{vector, array_size});
- }
- else {
- BLI_assert_unreachable();
+ if (value_ != nullptr) {
+ if (value_->type == ValueType::GVVectorArray) {
+ /* Fill new vector array with data from virtual vector array. */
+ new_value->data.extend(full_mask, this->value_as<VariableValue_GVVectorArray>()->data);
+ }
+ else if (value_->type == ValueType::OneVector) {
+ /* Fill all indices with the same value. */
+ const GSpan vector = this->value_as<VariableValue_OneVector>()->data[0];
+ new_value->data.extend(full_mask, GVVectorArray_For_SingleGSpan{vector, array_size});
+ }
+ else {
+ BLI_assert_unreachable();
+ }
+ value_allocator.release_value(value_, data_type);
}
- value_allocator.release_value(value_, data_type);
value_ = new_value;
break;
}
@@ -466,6 +462,7 @@ class VariableState : NonCopyable, NonMovable {
BLI_assert(mask.size() <= tot_initialized_);
this->ensure_is_mutable(full_mask, data_type, value_allocator);
+ BLI_assert(value_ != nullptr);
switch (value_->type) {
case ValueType::Span: {
@@ -497,6 +494,7 @@ class VariableState : NonCopyable, NonMovable {
/* Sanity check to make sure that enough values are not initialized. */
BLI_assert(mask.size() <= full_mask.size() - tot_initialized_);
this->ensure_is_mutable(full_mask, data_type, value_allocator);
+ BLI_assert(value_ != nullptr);
switch (value_->type) {
case ValueType::Span: {
@@ -524,6 +522,7 @@ class VariableState : NonCopyable, NonMovable {
void add_as_input__one(MFParamsBuilder &params, const MFDataType &data_type) const
{
BLI_assert(this->is_one());
+ BLI_assert(value_ != nullptr);
switch (value_->type) {
case ValueType::GVArray: {
@@ -556,7 +555,7 @@ class VariableState : NonCopyable, NonMovable {
void ensure_is_mutable__one(const MFDataType &data_type, ValueAllocator &value_allocator)
{
BLI_assert(this->is_one());
- if (ELEM(value_->type, ValueType::OneSingle, ValueType::OneVector)) {
+ if (value_ != nullptr && ELEM(value_->type, ValueType::OneSingle, ValueType::OneVector)) {
return;
}
@@ -564,38 +563,42 @@ class VariableState : NonCopyable, NonMovable {
case MFDataType::Single: {
const CPPType &type = data_type.single_type();
VariableValue_OneSingle *new_value = value_allocator.obtain_OneSingle(type);
- if (value_->type == ValueType::GVArray) {
- this->value_as<VariableValue_GVArray>()->data.get_internal_single_to_uninitialized(
- new_value->data);
- new_value->is_initialized = true;
- }
- else if (value_->type == ValueType::Span) {
- BLI_assert(tot_initialized_ == 0);
- /* Nothing to do, the single value is uninitialized already. */
- }
- else {
- BLI_assert_unreachable();
+ if (value_ != nullptr) {
+ if (value_->type == ValueType::GVArray) {
+ this->value_as<VariableValue_GVArray>()->data.get_internal_single_to_uninitialized(
+ new_value->data);
+ new_value->is_initialized = true;
+ }
+ else if (value_->type == ValueType::Span) {
+ BLI_assert(tot_initialized_ == 0);
+ /* Nothing to do, the single value is uninitialized already. */
+ }
+ else {
+ BLI_assert_unreachable();
+ }
+ value_allocator.release_value(value_, data_type);
}
- value_allocator.release_value(value_, data_type);
value_ = new_value;
break;
}
case MFDataType::Vector: {
const CPPType &type = data_type.vector_base_type();
VariableValue_OneVector *new_value = value_allocator.obtain_OneVector(type);
- if (value_->type == ValueType::GVVectorArray) {
- const GVVectorArray &old_vector_array =
- this->value_as<VariableValue_GVVectorArray>()->data;
- new_value->data.extend(IndexRange(1), old_vector_array);
- }
- else if (value_->type == ValueType::GVectorArray) {
- BLI_assert(tot_initialized_ == 0);
- /* Nothing to do. */
- }
- else {
- BLI_assert_unreachable();
+ if (value_ != nullptr) {
+ if (value_->type == ValueType::GVVectorArray) {
+ const GVVectorArray &old_vector_array =
+ this->value_as<VariableValue_GVVectorArray>()->data;
+ new_value->data.extend(IndexRange(1), old_vector_array);
+ }
+ else if (value_->type == ValueType::GVectorArray) {
+ BLI_assert(tot_initialized_ == 0);
+ /* Nothing to do. */
+ }
+ else {
+ BLI_assert_unreachable();
+ }
+ value_allocator.release_value(value_, data_type);
}
- value_allocator.release_value(value_, data_type);
value_ = new_value;
break;
}
@@ -608,6 +611,7 @@ class VariableState : NonCopyable, NonMovable {
{
BLI_assert(this->is_one());
this->ensure_is_mutable__one(data_type, value_allocator);
+ BLI_assert(value_ != nullptr);
switch (value_->type) {
case ValueType::OneSingle: {
@@ -637,6 +641,7 @@ class VariableState : NonCopyable, NonMovable {
{
BLI_assert(this->is_one());
this->ensure_is_mutable__one(data_type, value_allocator);
+ BLI_assert(value_ != nullptr);
switch (value_->type) {
case ValueType::OneSingle: {
@@ -676,6 +681,7 @@ class VariableState : NonCopyable, NonMovable {
const MFDataType &data_type,
ValueAllocator &value_allocator)
{
+ BLI_assert(value_ != nullptr);
int new_tot_initialized = tot_initialized_ - mask.size();
/* Sanity check to make sure that enough indices can be destructed. */
@@ -743,6 +749,7 @@ class VariableState : NonCopyable, NonMovable {
void indices_split(IndexMask mask, IndicesSplitVectors &r_indices)
{
BLI_assert(mask.size() <= tot_initialized_);
+ BLI_assert(value_ != nullptr);
switch (value_->type) {
case ValueType::GVArray: {
@@ -778,51 +785,47 @@ class VariableState : NonCopyable, NonMovable {
template<typename T> T *value_as()
{
+ BLI_assert(value_ != nullptr);
BLI_assert(value_->type == T::static_type);
return static_cast<T *>(value_);
}
template<typename T> const T *value_as() const
{
+ BLI_assert(value_ != nullptr);
BLI_assert(value_->type == T::static_type);
return static_cast<T *>(value_);
}
};
-template<typename... Args> VariableState *ValueAllocator::obtain_variable_state(Args &&...args)
-{
- if (variable_state_free_list_.is_empty()) {
- void *buffer = linear_allocator_.allocate(sizeof(VariableState), alignof(VariableState));
- return new (buffer) VariableState(std::forward<Args>(args)...);
- }
- return new (variable_state_free_list_.pop()) VariableState(std::forward<Args>(args)...);
-}
-
-void ValueAllocator::release_variable_state(VariableState *state)
-{
- state->~VariableState();
- variable_state_free_list_.push(state);
-}
-
/** Keeps track of the states of all variables during evaluation. */
class VariableStates {
private:
ValueAllocator value_allocator_;
- Map<const MFVariable *, VariableState *> variable_states_;
+ const MFProcedure &procedure_;
+ /** The state of every variable, indexed by #MFVariable::index_in_procedure(). */
+ Array<VariableState> variable_states_;
IndexMask full_mask_;
public:
- VariableStates(LinearAllocator<> &linear_allocator, IndexMask full_mask)
- : value_allocator_(linear_allocator), full_mask_(full_mask)
+ VariableStates(LinearAllocator<> &linear_allocator,
+ const MFProcedure &procedure,
+ IndexMask full_mask)
+ : value_allocator_(linear_allocator),
+ procedure_(procedure),
+ variable_states_(procedure.variables().size()),
+ full_mask_(full_mask)
{
}
~VariableStates()
{
- for (auto &&item : variable_states_.items()) {
- const MFVariable *variable = item.key;
- VariableState *state = item.value;
- state->destruct_self(value_allocator_, variable->data_type());
+ for (const int variable_i : procedure_.variables().index_range()) {
+ VariableState &state = variable_states_[variable_i];
+ if (state.value_ != nullptr) {
+ const MFVariable *variable = procedure_.variables()[variable_i];
+ state.destruct_value(value_allocator_, variable->data_type());
+ }
}
}
@@ -848,9 +851,12 @@ class VariableStates {
bool input_is_initialized,
void *caller_provided_storage = nullptr) {
const int tot_initialized = input_is_initialized ? full_mask_.size() : 0;
- variable_states_.add_new(variable,
- value_allocator_.obtain_variable_state(
- *value, tot_initialized, caller_provided_storage));
+ const int variable_i = variable->index_in_procedure();
+ VariableState &variable_state = variable_states_[variable_i];
+ BLI_assert(variable_state.value_ == nullptr);
+ variable_state.value_ = value;
+ variable_state.tot_initialized_ = tot_initialized;
+ variable_state.caller_provided_storage_ = caller_provided_storage;
};
switch (param_type.category()) {
@@ -936,32 +942,15 @@ class VariableStates {
{
VariableState &variable_state = this->get_variable_state(variable);
if (variable_state.destruct(mask, full_mask_, variable.data_type(), value_allocator_)) {
- variable_state.destruct_self(value_allocator_, variable.data_type());
- variable_states_.remove_contained(&variable);
+ variable_state.destruct_value(value_allocator_, variable.data_type());
}
}
VariableState &get_variable_state(const MFVariable &variable)
{
- return *variable_states_.lookup_or_add_cb(
- &variable, [&]() { return this->create_new_state_for_variable(variable); });
- }
-
- VariableState *create_new_state_for_variable(const MFVariable &variable)
- {
- MFDataType data_type = variable.data_type();
- switch (data_type.category()) {
- case MFDataType::Single: {
- const CPPType &type = data_type.single_type();
- return value_allocator_.obtain_variable_state(*value_allocator_.obtain_OneSingle(type), 0);
- }
- case MFDataType::Vector: {
- const CPPType &type = data_type.vector_base_type();
- return value_allocator_.obtain_variable_state(*value_allocator_.obtain_OneVector(type), 0);
- }
- }
- BLI_assert_unreachable();
- return nullptr;
+ const int variable_i = variable.index_in_procedure();
+ VariableState &variable_state = variable_states_[variable_i];
+ return variable_state;
}
};
@@ -977,49 +966,82 @@ static bool evaluate_as_one(const MultiFunction &fn,
return false;
}
for (VariableState *state : param_variable_states) {
- if (state != nullptr && !state->is_one()) {
+ if (state != nullptr && state->value_ != nullptr && !state->is_one()) {
return false;
}
}
return true;
}
-static void execute_call_instruction(const MFCallInstruction &instruction,
- IndexMask mask,
- VariableStates &variable_states,
- const MFContext &context)
+static void gather_parameter_variable_states(const MultiFunction &fn,
+ const MFCallInstruction &instruction,
+ VariableStates &variable_states,
+ MutableSpan<VariableState *> r_param_variable_states)
{
- const MultiFunction &fn = instruction.fn();
-
- Vector<VariableState *> param_variable_states;
- param_variable_states.resize(fn.param_amount());
-
for (const int param_index : fn.param_indices()) {
const MFVariable *variable = instruction.params()[param_index];
if (variable == nullptr) {
- param_variable_states[param_index] = nullptr;
+ r_param_variable_states[param_index] = nullptr;
}
else {
VariableState &variable_state = variable_states.get_variable_state(*variable);
- param_variable_states[param_index] = &variable_state;
+ r_param_variable_states[param_index] = &variable_state;
+ }
+ }
+}
+
+static void fill_params__one(const MultiFunction &fn,
+ const IndexMask mask,
+ MFParamsBuilder &params,
+ VariableStates &variable_states,
+ const Span<VariableState *> param_variable_states)
+{
+ for (const int param_index : fn.param_indices()) {
+ const MFParamType param_type = fn.param_type(param_index);
+ VariableState *variable_state = param_variable_states[param_index];
+ if (variable_state == nullptr) {
+ params.add_ignored_single_output();
+ }
+ else {
+ variable_states.add_as_param__one(*variable_state, params, param_type, mask);
}
}
+}
+
+static void fill_params(const MultiFunction &fn,
+ const IndexMask mask,
+ MFParamsBuilder &params,
+ VariableStates &variable_states,
+ const Span<VariableState *> param_variable_states)
+{
+ for (const int param_index : fn.param_indices()) {
+ const MFParamType param_type = fn.param_type(param_index);
+ VariableState *variable_state = param_variable_states[param_index];
+ if (variable_state == nullptr) {
+ params.add_ignored_single_output();
+ }
+ else {
+ variable_states.add_as_param(*variable_state, params, param_type, mask);
+ }
+ }
+}
+
+static void execute_call_instruction(const MFCallInstruction &instruction,
+ const IndexMask mask,
+ VariableStates &variable_states,
+ const MFContext &context)
+{
+ const MultiFunction &fn = instruction.fn();
+
+ Vector<VariableState *> param_variable_states;
+ param_variable_states.resize(fn.param_amount());
+ gather_parameter_variable_states(fn, instruction, variable_states, param_variable_states);
/* If all inputs to the function are constant, it's enough to call the function only once instead
* of for every index. */
if (evaluate_as_one(fn, param_variable_states, mask, variable_states.full_mask())) {
MFParamsBuilder params(fn, 1);
-
- for (const int param_index : fn.param_indices()) {
- const MFParamType param_type = fn.param_type(param_index);
- VariableState *variable_state = param_variable_states[param_index];
- if (variable_state == nullptr) {
- params.add_ignored_single_output();
- }
- else {
- variable_states.add_as_param__one(*variable_state, params, param_type, mask);
- }
- }
+ fill_params__one(fn, mask, params, variable_states, param_variable_states);
try {
fn.call(IndexRange(1), params, context);
@@ -1031,17 +1053,7 @@ static void execute_call_instruction(const MFCallInstruction &instruction,
}
else {
MFParamsBuilder params(fn, &mask);
-
- for (const int param_index : fn.param_indices()) {
- const MFParamType param_type = fn.param_type(param_index);
- VariableState *variable_state = param_variable_states[param_index];
- if (variable_state == nullptr) {
- params.add_ignored_single_output();
- }
- else {
- variable_states.add_as_param(*variable_state, params, param_type, mask);
- }
- }
+ fill_params(fn, mask, params, variable_states, param_variable_states);
try {
fn.call_auto(mask, params, context);
@@ -1090,7 +1102,7 @@ struct NextInstructionInfo {
*/
class InstructionScheduler {
private:
- Map<const MFInstruction *, Vector<InstructionIndices>> indices_by_instruction_;
+ Stack<NextInstructionInfo> next_instructions_;
public:
InstructionScheduler() = default;
@@ -1103,7 +1115,7 @@ class InstructionScheduler {
InstructionIndices new_indices;
new_indices.is_owned = false;
new_indices.referenced_indices = mask;
- indices_by_instruction_.lookup_or_add_default(&instruction).append(std::move(new_indices));
+ next_instructions_.push({&instruction, std::move(new_indices)});
}
void add_owned_indices(const MFInstruction &instruction, Vector<int64_t> indices)
@@ -1116,43 +1128,28 @@ class InstructionScheduler {
InstructionIndices new_indices;
new_indices.is_owned = true;
new_indices.owned_indices = std::move(indices);
- indices_by_instruction_.lookup_or_add_default(&instruction).append(std::move(new_indices));
+ next_instructions_.push({&instruction, std::move(new_indices)});
}
- void add_previous_instruction_indices(const MFInstruction &instruction,
- NextInstructionInfo &instr_info)
+ bool is_done() const
{
- indices_by_instruction_.lookup_or_add_default(&instruction)
- .append(std::move(instr_info.indices));
+ return next_instructions_.is_empty();
}
- NextInstructionInfo pop_next()
+ const NextInstructionInfo &peek() const
{
- if (indices_by_instruction_.is_empty()) {
- return {};
- }
- /* TODO: Implement better mechanism to determine next instruction. */
- const MFInstruction *instruction = *indices_by_instruction_.keys().begin();
+ BLI_assert(!this->is_done());
+ return next_instructions_.peek();
+ }
- NextInstructionInfo next_instruction_info;
- next_instruction_info.instruction = instruction;
- next_instruction_info.indices = this->pop_indices_array(instruction);
- return next_instruction_info;
+ void update_instruction_pointer(const MFInstruction &instruction)
+ {
+ next_instructions_.peek().instruction = &instruction;
}
- private:
- InstructionIndices pop_indices_array(const MFInstruction *instruction)
+ NextInstructionInfo pop()
{
- Vector<InstructionIndices> *indices = indices_by_instruction_.lookup_ptr(instruction);
- if (indices == nullptr) {
- return {};
- }
- InstructionIndices r_indices = (*indices).pop_last();
- BLI_assert(!r_indices.mask().is_empty());
- if (indices->is_empty()) {
- indices_by_instruction_.remove_contained(instruction);
- }
- return r_indices;
+ return next_instructions_.pop();
}
};
@@ -1160,23 +1157,26 @@ void MFProcedureExecutor::call(IndexMask full_mask, MFParams params, MFContext c
{
BLI_assert(procedure_.validate());
+ AlignedBuffer<512, 64> local_buffer;
LinearAllocator<> linear_allocator;
+ linear_allocator.provide_buffer(local_buffer);
- VariableStates variable_states{linear_allocator, full_mask};
+ VariableStates variable_states{linear_allocator, procedure_, full_mask};
variable_states.add_initial_variable_states(*this, procedure_, params);
InstructionScheduler scheduler;
scheduler.add_referenced_indices(*procedure_.entry(), full_mask);
/* Loop until all indices got to a return instruction. */
- while (NextInstructionInfo instr_info = scheduler.pop_next()) {
+ while (!scheduler.is_done()) {
+ const NextInstructionInfo &instr_info = scheduler.peek();
const MFInstruction &instruction = *instr_info.instruction;
switch (instruction.type()) {
case MFInstructionType::Call: {
const MFCallInstruction &call_instruction = static_cast<const MFCallInstruction &>(
instruction);
execute_call_instruction(call_instruction, instr_info.mask(), variable_states, context);
- scheduler.add_previous_instruction_indices(*call_instruction.next(), instr_info);
+ scheduler.update_instruction_pointer(*call_instruction.next());
break;
}
case MFInstructionType::Branch: {
@@ -1187,6 +1187,7 @@ void MFProcedureExecutor::call(IndexMask full_mask, MFParams params, MFContext c
IndicesSplitVectors new_indices;
variable_state.indices_split(instr_info.mask(), new_indices);
+ scheduler.pop();
scheduler.add_owned_indices(*branch_instruction.branch_false(), new_indices[false]);
scheduler.add_owned_indices(*branch_instruction.branch_true(), new_indices[true]);
break;
@@ -1196,17 +1197,18 @@ void MFProcedureExecutor::call(IndexMask full_mask, MFParams params, MFContext c
static_cast<const MFDestructInstruction &>(instruction);
const MFVariable *variable = destruct_instruction.variable();
variable_states.destruct(*variable, instr_info.mask());
- scheduler.add_previous_instruction_indices(*destruct_instruction.next(), instr_info);
+ scheduler.update_instruction_pointer(*destruct_instruction.next());
break;
}
case MFInstructionType::Dummy: {
const MFDummyInstruction &dummy_instruction = static_cast<const MFDummyInstruction &>(
instruction);
- scheduler.add_previous_instruction_indices(*dummy_instruction.next(), instr_info);
+ scheduler.update_instruction_pointer(*dummy_instruction.next());
break;
}
case MFInstructionType::Return: {
/* Don't insert the indices back into the scheduler. */
+ scheduler.pop();
break;
}
}
diff --git a/source/blender/geometry/CMakeLists.txt b/source/blender/geometry/CMakeLists.txt
index 1916c5f91f3..531487a45e2 100644
--- a/source/blender/geometry/CMakeLists.txt
+++ b/source/blender/geometry/CMakeLists.txt
@@ -15,6 +15,7 @@ set(INC
)
set(SRC
+ intern/add_curves_on_mesh.cc
intern/mesh_merge_by_distance.cc
intern/mesh_primitive_cuboid.cc
intern/mesh_to_curve_convert.cc
@@ -24,6 +25,7 @@ set(SRC
intern/reverse_uv_sampler.cc
intern/uv_parametrizer.c
+ GEO_add_curves_on_mesh.hh
GEO_mesh_merge_by_distance.hh
GEO_mesh_primitive_cuboid.hh
GEO_mesh_to_curve.hh
diff --git a/source/blender/geometry/GEO_add_curves_on_mesh.hh b/source/blender/geometry/GEO_add_curves_on_mesh.hh
new file mode 100644
index 00000000000..cf60a8e8ace
--- /dev/null
+++ b/source/blender/geometry/GEO_add_curves_on_mesh.hh
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include "BLI_float4x4.hh"
+#include "BLI_kdtree.h"
+#include "BLI_math_vector.hh"
+#include "BLI_span.hh"
+
+#include "BKE_bvhutils.h"
+#include "BKE_curves.hh"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+namespace blender::geometry {
+
+struct AddCurvesOnMeshInputs {
+ /** Information about the root points where new curves should be generated. */
+ Span<float3> root_positions_cu;
+ Span<float3> bary_coords;
+ Span<int> looptri_indices;
+
+ /** Determines shape of new curves. */
+ bool interpolate_length = false;
+ bool interpolate_shape = false;
+ bool interpolate_point_count = false;
+ float fallback_curve_length = 0.0f;
+ int fallback_point_count = 0;
+
+ /** Information about the surface that the new curves are attached to. */
+ const Mesh *surface = nullptr;
+ BVHTreeFromMesh *surface_bvh = nullptr;
+ Span<MLoopTri> surface_looptris;
+ Span<float2> surface_uv_map;
+ Span<float3> corner_normals_su;
+
+ /** Transformation matrices. */
+ float4x4 curves_to_surface_mat;
+ float4x4 surface_to_curves_normal_mat;
+
+ /**
+ * KD-Tree that contains the root points of existing curves. This is only necessary when
+ * interpolation is used.
+ */
+ KDTree_3d *old_roots_kdtree = nullptr;
+};
+
+/**
+ * Generate new curves on a mesh surface with the given inputs. Existing curves stay intact.
+ */
+void add_curves_on_mesh(bke::CurvesGeometry &curves, const AddCurvesOnMeshInputs &inputs);
+
+} // namespace blender::geometry
diff --git a/source/blender/geometry/intern/add_curves_on_mesh.cc b/source/blender/geometry/intern/add_curves_on_mesh.cc
new file mode 100644
index 00000000000..34551bd474f
--- /dev/null
+++ b/source/blender/geometry/intern/add_curves_on_mesh.cc
@@ -0,0 +1,354 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BKE_mesh_sample.hh"
+#include "BKE_spline.hh"
+
+#include "GEO_add_curves_on_mesh.hh"
+
+/**
+ * The code below uses a suffix naming convention to indicate the coordinate space:
+ * cu: Local space of the curves object that is being edited.
+ * su: Local space of the surface object.
+ */
+
+namespace blender::geometry {
+
+using bke::CurvesGeometry;
+
+struct NeighborCurve {
+ /* Curve index of the neighbor. */
+ int index;
+ /* The weights of all neighbors of a new curve add up to 1. */
+ float weight;
+};
+
+static constexpr int max_neighbors = 5;
+using NeighborCurves = Vector<NeighborCurve, max_neighbors>;
+
+static float3 compute_surface_point_normal(const MLoopTri &looptri,
+ const float3 &bary_coord,
+ const Span<float3> corner_normals)
+{
+ const int l0 = looptri.tri[0];
+ const int l1 = looptri.tri[1];
+ const int l2 = looptri.tri[2];
+
+ const float3 &l0_normal = corner_normals[l0];
+ const float3 &l1_normal = corner_normals[l1];
+ const float3 &l2_normal = corner_normals[l2];
+
+ const float3 normal = math::normalize(
+ attribute_math::mix3(bary_coord, l0_normal, l1_normal, l2_normal));
+ return normal;
+}
+
+static void initialize_straight_curve_positions(const float3 &p1,
+ const float3 &p2,
+ MutableSpan<float3> r_positions)
+{
+ const float step = 1.0f / (float)(r_positions.size() - 1);
+ for (const int i : r_positions.index_range()) {
+ r_positions[i] = math::interpolate(p1, p2, i * step);
+ }
+}
+
+static Array<NeighborCurves> find_curve_neighbors(const Span<float3> root_positions,
+ const KDTree_3d &old_roots_kdtree)
+{
+ const int tot_added_curves = root_positions.size();
+ Array<NeighborCurves> neighbors_per_curve(tot_added_curves);
+ threading::parallel_for(IndexRange(tot_added_curves), 128, [&](const IndexRange range) {
+ for (const int i : range) {
+ const float3 root = root_positions[i];
+ std::array<KDTreeNearest_3d, max_neighbors> nearest_n;
+ const int found_neighbors = BLI_kdtree_3d_find_nearest_n(
+ &old_roots_kdtree, root, nearest_n.data(), max_neighbors);
+ float tot_weight = 0.0f;
+ for (const int neighbor_i : IndexRange(found_neighbors)) {
+ KDTreeNearest_3d &nearest = nearest_n[neighbor_i];
+ const float weight = 1.0f / std::max(nearest.dist, 0.00001f);
+ tot_weight += weight;
+ neighbors_per_curve[i].append({nearest.index, weight});
+ }
+ /* Normalize weights. */
+ for (NeighborCurve &neighbor : neighbors_per_curve[i]) {
+ neighbor.weight /= tot_weight;
+ }
+ }
+ });
+ return neighbors_per_curve;
+}
+
+template<typename T, typename GetValueF>
+void interpolate_from_neighbors(const Span<NeighborCurves> neighbors_per_curve,
+ const T &fallback,
+ const GetValueF &get_value_from_neighbor,
+ MutableSpan<T> r_interpolated_values)
+{
+ attribute_math::DefaultMixer<T> mixer{r_interpolated_values};
+ threading::parallel_for(r_interpolated_values.index_range(), 512, [&](const IndexRange range) {
+ for (const int i : range) {
+ const NeighborCurves &neighbors = neighbors_per_curve[i];
+ if (neighbors.is_empty()) {
+ mixer.mix_in(i, fallback, 1.0f);
+ }
+ else {
+ for (const NeighborCurve &neighbor : neighbors) {
+ const T neighbor_value = get_value_from_neighbor(neighbor.index);
+ mixer.mix_in(i, neighbor_value, neighbor.weight);
+ }
+ }
+ }
+ });
+ mixer.finalize();
+}
+
+static void interpolate_position_without_interpolation(
+ CurvesGeometry &curves,
+ const int old_curves_num,
+ const Span<float3> root_positions_cu,
+ const Span<float> new_lengths_cu,
+ const Span<float3> new_normals_su,
+ const float4x4 &surface_to_curves_normal_mat)
+{
+ const int added_curves_num = root_positions_cu.size();
+ MutableSpan<float3> positions_cu = curves.positions_for_write();
+ threading::parallel_for(IndexRange(added_curves_num), 256, [&](const IndexRange range) {
+ for (const int i : range) {
+ const int curve_i = old_curves_num + i;
+ const IndexRange points = curves.points_for_curve(curve_i);
+ const float3 &root_cu = root_positions_cu[i];
+ const float length = new_lengths_cu[i];
+ const float3 &normal_su = new_normals_su[i];
+ const float3 normal_cu = math::normalize(surface_to_curves_normal_mat * normal_su);
+ const float3 tip_cu = root_cu + length * normal_cu;
+
+ initialize_straight_curve_positions(root_cu, tip_cu, positions_cu.slice(points));
+ }
+ });
+}
+
+static void interpolate_position_with_interpolation(CurvesGeometry &curves,
+ const Span<float3> root_positions_cu,
+ const Span<NeighborCurves> neighbors_per_curve,
+ const int old_curves_num,
+ const Span<float> new_lengths_cu,
+ const Span<float3> new_normals_su,
+ const float4x4 &surface_to_curves_normal_mat,
+ const float4x4 &curves_to_surface_mat,
+ const BVHTreeFromMesh &surface_bvh,
+ const Span<MLoopTri> surface_looptris,
+ const Mesh &surface,
+ const Span<float3> corner_normals_su)
+{
+ MutableSpan<float3> positions_cu = curves.positions_for_write();
+ const int added_curves_num = root_positions_cu.size();
+
+ threading::parallel_for(IndexRange(added_curves_num), 256, [&](const IndexRange range) {
+ for (const int i : range) {
+ const NeighborCurves &neighbors = neighbors_per_curve[i];
+ const int curve_i = old_curves_num + i;
+ const IndexRange points = curves.points_for_curve(curve_i);
+
+ const float length_cu = new_lengths_cu[i];
+ const float3 &normal_su = new_normals_su[i];
+ const float3 normal_cu = math::normalize(surface_to_curves_normal_mat * normal_su);
+
+ const float3 &root_cu = root_positions_cu[i];
+
+ if (neighbors.is_empty()) {
+ /* If there are no neighbors, just make a straight line. */
+ const float3 tip_cu = root_cu + length_cu * normal_cu;
+ initialize_straight_curve_positions(root_cu, tip_cu, positions_cu.slice(points));
+ continue;
+ }
+
+ positions_cu.slice(points).fill(root_cu);
+
+ for (const NeighborCurve &neighbor : neighbors) {
+ const int neighbor_curve_i = neighbor.index;
+ const float3 &neighbor_first_pos_cu = positions_cu[curves.offsets()[neighbor_curve_i]];
+ const float3 neighbor_first_pos_su = curves_to_surface_mat * neighbor_first_pos_cu;
+
+ BVHTreeNearest nearest;
+ nearest.dist_sq = FLT_MAX;
+ BLI_bvhtree_find_nearest(surface_bvh.tree,
+ neighbor_first_pos_su,
+ &nearest,
+ surface_bvh.nearest_callback,
+ const_cast<BVHTreeFromMesh *>(&surface_bvh));
+ const int neighbor_looptri_index = nearest.index;
+ const MLoopTri &neighbor_looptri = surface_looptris[neighbor_looptri_index];
+
+ const float3 neighbor_bary_coord =
+ bke::mesh_surface_sample::compute_bary_coord_in_triangle(
+ surface, neighbor_looptri, nearest.co);
+
+ const float3 neighbor_normal_su = compute_surface_point_normal(
+ surface_looptris[neighbor_looptri_index], neighbor_bary_coord, corner_normals_su);
+ const float3 neighbor_normal_cu = math::normalize(surface_to_curves_normal_mat *
+ neighbor_normal_su);
+
+ /* The rotation matrix used to transform relative coordinates of the neighbor curve
+ * to the new curve. */
+ float normal_rotation_cu[3][3];
+ rotation_between_vecs_to_mat3(normal_rotation_cu, neighbor_normal_cu, normal_cu);
+
+ const IndexRange neighbor_points = curves.points_for_curve(neighbor_curve_i);
+ const float3 &neighbor_root_cu = positions_cu[neighbor_points[0]];
+
+ /* Use a temporary #PolySpline, because that's the easiest way to resample an
+ * existing curve right now. Resampling is necessary if the length of the new curve
+ * does not match the length of the neighbors or the number of handle points is
+ * different. */
+ PolySpline neighbor_spline;
+ neighbor_spline.resize(neighbor_points.size());
+ neighbor_spline.positions().copy_from(positions_cu.slice(neighbor_points));
+ neighbor_spline.mark_cache_invalid();
+
+ const float neighbor_length_cu = neighbor_spline.length();
+ const float length_factor = std::min(1.0f, length_cu / neighbor_length_cu);
+
+ const float resample_factor = (1.0f / (points.size() - 1.0f)) * length_factor;
+ for (const int j : IndexRange(points.size())) {
+ const Spline::LookupResult lookup = neighbor_spline.lookup_evaluated_factor(
+ j * resample_factor);
+ const float index_factor = lookup.evaluated_index + lookup.factor;
+ float3 p;
+ neighbor_spline.sample_with_index_factors<float3>(
+ neighbor_spline.positions(), {&index_factor, 1}, {&p, 1});
+ const float3 relative_coord = p - neighbor_root_cu;
+ float3 rotated_relative_coord = relative_coord;
+ mul_m3_v3(normal_rotation_cu, rotated_relative_coord);
+ positions_cu[points[j]] += neighbor.weight * rotated_relative_coord;
+ }
+ }
+ }
+ });
+}
+
+void add_curves_on_mesh(CurvesGeometry &curves, const AddCurvesOnMeshInputs &inputs)
+{
+ const bool use_interpolation = inputs.interpolate_length || inputs.interpolate_point_count ||
+ inputs.interpolate_shape;
+
+ Array<NeighborCurves> neighbors_per_curve;
+ if (use_interpolation) {
+ BLI_assert(inputs.old_roots_kdtree != nullptr);
+ neighbors_per_curve = find_curve_neighbors(inputs.root_positions_cu, *inputs.old_roots_kdtree);
+ }
+
+ const int added_curves_num = inputs.root_positions_cu.size();
+ const int old_points_num = curves.points_num();
+ const int old_curves_num = curves.curves_num();
+ const int new_curves_num = old_curves_num + added_curves_num;
+
+ /* Grow number of curves first, so that the offsets array can be filled. */
+ curves.resize(old_points_num, new_curves_num);
+
+ /* Compute new curve offsets. */
+ MutableSpan<int> curve_offsets = curves.offsets_for_write();
+ MutableSpan<int> new_point_counts_per_curve = curve_offsets.take_back(added_curves_num);
+ if (inputs.interpolate_point_count) {
+ interpolate_from_neighbors<int>(
+ neighbors_per_curve,
+ inputs.fallback_point_count,
+ [&](const int curve_i) { return curves.points_for_curve(curve_i).size(); },
+ new_point_counts_per_curve);
+ }
+ else {
+ new_point_counts_per_curve.fill(inputs.fallback_point_count);
+ }
+ for (const int i : IndexRange(added_curves_num)) {
+ curve_offsets[old_curves_num + i + 1] += curve_offsets[old_curves_num + i];
+ }
+
+ const int new_points_num = curves.offsets().last();
+ curves.resize(new_points_num, new_curves_num);
+ MutableSpan<float3> positions_cu = curves.positions_for_write();
+
+ /* Determine length of new curves. */
+ Array<float> new_lengths_cu(added_curves_num);
+ if (inputs.interpolate_length) {
+ interpolate_from_neighbors<float>(
+ neighbors_per_curve,
+ inputs.fallback_curve_length,
+ [&](const int curve_i) {
+ const IndexRange points = curves.points_for_curve(curve_i);
+ float length = 0.0f;
+ for (const int segment_i : points.drop_back(1)) {
+ const float3 &p1 = positions_cu[segment_i];
+ const float3 &p2 = positions_cu[segment_i + 1];
+ length += math::distance(p1, p2);
+ }
+ return length;
+ },
+ new_lengths_cu);
+ }
+ else {
+ new_lengths_cu.fill(inputs.fallback_curve_length);
+ }
+
+ /* Find surface normal at root points. */
+ Array<float3> new_normals_su(added_curves_num);
+ threading::parallel_for(IndexRange(added_curves_num), 256, [&](const IndexRange range) {
+ for (const int i : range) {
+ const int looptri_index = inputs.looptri_indices[i];
+ const float3 &bary_coord = inputs.bary_coords[i];
+ new_normals_su[i] = compute_surface_point_normal(
+ inputs.surface_looptris[looptri_index], bary_coord, inputs.corner_normals_su);
+ }
+ });
+
+ /* Propagate attachment information. */
+ if (!inputs.surface_uv_map.is_empty()) {
+ MutableSpan<float2> surface_uv_coords = curves.surface_uv_coords_for_write();
+ bke::mesh_surface_sample::sample_corner_attribute(
+ *inputs.surface,
+ inputs.looptri_indices,
+ inputs.bary_coords,
+ GVArray::ForSpan(inputs.surface_uv_map),
+ IndexRange(added_curves_num),
+ surface_uv_coords.take_back(added_curves_num));
+ }
+
+ /* Update selection arrays when available. */
+ const VArray<float> points_selection = curves.selection_point_float();
+ if (points_selection.is_span()) {
+ MutableSpan<float> points_selection_span = curves.selection_point_float_for_write();
+ points_selection_span.drop_front(old_points_num).fill(1.0f);
+ }
+ const VArray<float> curves_selection = curves.selection_curve_float();
+ if (curves_selection.is_span()) {
+ MutableSpan<float> curves_selection_span = curves.selection_curve_float_for_write();
+ curves_selection_span.drop_front(old_curves_num).fill(1.0f);
+ }
+
+ /* Initialize position attribute. */
+ if (inputs.interpolate_shape) {
+ interpolate_position_with_interpolation(curves,
+ inputs.root_positions_cu,
+ neighbors_per_curve,
+ old_curves_num,
+ new_lengths_cu,
+ new_normals_su,
+ inputs.surface_to_curves_normal_mat,
+ inputs.curves_to_surface_mat,
+ *inputs.surface_bvh,
+ inputs.surface_looptris,
+ *inputs.surface,
+ inputs.corner_normals_su);
+ }
+ else {
+ interpolate_position_without_interpolation(curves,
+ old_curves_num,
+ inputs.root_positions_cu,
+ new_lengths_cu,
+ new_normals_su,
+ inputs.surface_to_curves_normal_mat);
+ }
+
+ curves.update_curve_types();
+}
+
+} // namespace blender::geometry
diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc
index 4db4256ec8f..bd4099d37f9 100644
--- a/source/blender/geometry/intern/realize_instances.cc
+++ b/source/blender/geometry/intern/realize_instances.cc
@@ -134,6 +134,12 @@ struct RealizeCurveInfo {
* doesn't exist on some (but not all) of the input curves data-blocks.
*/
Span<float> radius;
+
+ /**
+ * The resolution attribute must be filled with the default value if it does not exist on some
+ * curves.
+ */
+ VArray<int> resolution;
};
/** Start indices in the final output curves data-block. */
@@ -185,6 +191,7 @@ struct AllCurvesInfo {
bool create_id_attribute = false;
bool create_handle_postion_attributes = false;
bool create_radius_attribute = false;
+ bool create_resolution_attribute = false;
};
/** Collects all tasks that need to be executed to realize all instances. */
@@ -1037,6 +1044,7 @@ static OrderedAttributes gather_generic_curve_attributes_to_propagate(
src_component_types, GEO_COMPONENT_TYPE_CURVE, true, attributes_to_propagate);
attributes_to_propagate.remove("position");
attributes_to_propagate.remove("radius");
+ attributes_to_propagate.remove("resolution");
attributes_to_propagate.remove("handle_right");
attributes_to_propagate.remove("handle_left");
r_create_id = attributes_to_propagate.pop_try("id").has_value();
@@ -1075,12 +1083,13 @@ static AllCurvesInfo preprocess_curves(const GeometrySet &geometry_set,
info.realize_info.reinitialize(info.order.size());
for (const int curve_index : info.realize_info.index_range()) {
RealizeCurveInfo &curve_info = info.realize_info[curve_index];
- const Curves *curves = info.order[curve_index];
- curve_info.curves = curves;
+ const Curves *curves_id = info.order[curve_index];
+ const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry);
+ curve_info.curves = curves_id;
/* Access attributes. */
CurveComponent component;
- component.replace(const_cast<Curves *>(curves), GeometryOwnershipType::ReadOnly);
+ component.replace(const_cast<Curves *>(curves_id), GeometryOwnershipType::ReadOnly);
curve_info.attributes.reinitialize(info.attributes.size());
for (const int attribute_index : info.attributes.index_range()) {
const eAttrDomain domain = info.attributes.kinds[attribute_index].domain;
@@ -1106,6 +1115,12 @@ static AllCurvesInfo preprocess_curves(const GeometrySet &geometry_set,
info.create_radius_attribute = true;
}
+ /* Retrieve the resolution attribute, if it exists. */
+ curve_info.resolution = curves.resolution();
+ if (component.attribute_exists("resolution")) {
+ info.create_resolution_attribute = true;
+ }
+
/* Retrieve handle position attributes, if they exist. */
if (component.attribute_exists("handle_right")) {
curve_info.handle_left = component
@@ -1131,7 +1146,8 @@ static void execute_realize_curve_task(const RealizeInstancesOptions &options,
MutableSpan<int> all_dst_ids,
MutableSpan<float3> all_handle_left,
MutableSpan<float3> all_handle_right,
- MutableSpan<float> all_radii)
+ MutableSpan<float> all_radii,
+ MutableSpan<int> all_resolutions)
{
const RealizeCurveInfo &curves_info = *task.curve_info;
const Curves &curves_id = *curves_info.curves;
@@ -1171,6 +1187,10 @@ static void execute_realize_curve_task(const RealizeInstancesOptions &options,
}
}
+ if (all_curves_info.create_resolution_attribute) {
+ curves_info.resolution.materialize(all_resolutions.slice(dst_curve_range));
+ }
+
/* Copy curve offsets. */
const Span<int> src_offsets = curves.offsets();
const MutableSpan<int> dst_offsets = dst_curves.offsets_for_write().slice(dst_curve_range);
@@ -1268,6 +1288,15 @@ static void execute_realize_curve_tasks(const RealizeInstancesOptions &options,
radius_span = radius.as_span();
}
+ /* Prepare resolution attribute if necessary. */
+ OutputAttribute_Typed<int> resolution;
+ MutableSpan<int> resolution_span;
+ if (all_curves_info.create_resolution_attribute) {
+ resolution = dst_component.attribute_try_get_for_output_only<int>("resolution",
+ ATTR_DOMAIN_CURVE);
+ resolution_span = resolution.as_span();
+ }
+
/* Actually execute all tasks. */
threading::parallel_for(tasks.index_range(), 100, [&](const IndexRange task_range) {
for (const int task_index : task_range) {
@@ -1281,7 +1310,8 @@ static void execute_realize_curve_tasks(const RealizeInstancesOptions &options,
point_ids_span,
handle_left_span,
handle_right_span,
- radius_span);
+ radius_span,
+ resolution_span);
}
});
@@ -1295,6 +1325,9 @@ static void execute_realize_curve_tasks(const RealizeInstancesOptions &options,
if (radius) {
radius.save();
}
+ if (resolution) {
+ resolution.save();
+ }
if (all_curves_info.create_handle_postion_attributes) {
handle_left.save();
handle_right.save();
diff --git a/source/blender/geometry/intern/uv_parametrizer.c b/source/blender/geometry/intern/uv_parametrizer.c
index 46ebe6cfdce..8863b9192ca 100644
--- a/source/blender/geometry/intern/uv_parametrizer.c
+++ b/source/blender/geometry/intern/uv_parametrizer.c
@@ -4,27 +4,18 @@
* \ingroup eduv
*/
+#include "GEO_uv_parametrizer.h"
+
#include "MEM_guardedalloc.h"
#include "BLI_boxpack_2d.h"
#include "BLI_convexhull_2d.h"
#include "BLI_ghash.h"
#include "BLI_heap.h"
-#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_polyfill_2d.h"
#include "BLI_polyfill_2d_beautify.h"
#include "BLI_rand.h"
-#include "BLI_utildefines.h"
-
-#include "GEO_uv_parametrizer.h"
-
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "BLI_sys_types.h" /* for intptr_t support */
#include "eigen_capi.h"
@@ -52,11 +43,6 @@ typedef struct PHash {
int size, cursize, cursize_id;
} PHash;
-struct PChart;
-struct PEdge;
-struct PFace;
-struct PVert;
-
/* Simplices */
typedef struct PVert {
@@ -318,54 +304,14 @@ static PHashLink *phash_next(PHash *ph, PHashKey key, PHashLink *link)
/* Geometry */
-static float p_vec_angle_cos(const float v1[3], const float v2[3], const float v3[3])
-{
- float d1[3], d2[3];
-
- d1[0] = v1[0] - v2[0];
- d1[1] = v1[1] - v2[1];
- d1[2] = v1[2] - v2[2];
-
- d2[0] = v3[0] - v2[0];
- d2[1] = v3[1] - v2[1];
- d2[2] = v3[2] - v2[2];
-
- normalize_v3(d1);
- normalize_v3(d2);
-
- return d1[0] * d2[0] + d1[1] * d2[1] + d1[2] * d2[2];
-}
-
static float p_vec_angle(const float v1[3], const float v2[3], const float v3[3])
{
- float dot = p_vec_angle_cos(v1, v2, v3);
-
- if (dot <= -1.0f) {
- return (float)M_PI;
- }
- if (dot >= 1.0f) {
- return 0.0f;
- }
- return acosf(dot);
+ return angle_v3v3v3(v1, v2, v3);
}
-
static float p_vec2_angle(const float v1[2], const float v2[2], const float v3[2])
{
- float u1[3], u2[3], u3[3];
-
- u1[0] = v1[0];
- u1[1] = v1[1];
- u1[2] = 0.0f;
- u2[0] = v2[0];
- u2[1] = v2[1];
- u2[2] = 0.0f;
- u3[0] = v3[0];
- u3[1] = v3[1];
- u3[2] = 0.0f;
-
- return p_vec_angle(u1, u2, u3);
+ return angle_v2v2v2(v1, v2, v3);
}
-
static void p_triangle_angles(
const float v1[3], const float v2[3], const float v3[3], float *r_a1, float *r_a2, float *r_a3)
{
@@ -406,25 +352,12 @@ static float p_face_uv_area_signed(PFace *f)
static float p_edge_length(PEdge *e)
{
- PVert *v1 = e->vert, *v2 = e->next->vert;
- float d[3];
-
- d[0] = v2->co[0] - v1->co[0];
- d[1] = v2->co[1] - v1->co[1];
- d[2] = v2->co[2] - v1->co[2];
-
- return sqrtf(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
+ return len_v3v3(e->vert->co, e->next->vert->co);
}
static float p_edge_uv_length(PEdge *e)
{
- PVert *v1 = e->vert, *v2 = e->next->vert;
- float d[3];
-
- d[0] = v2->uv[0] - v1->uv[0];
- d[1] = v2->uv[1] - v1->uv[1];
-
- return sqrtf(d[0] * d[0] + d[1] * d[1]);
+ return len_v2v2(e->vert->uv, e->next->vert->uv);
}
static void p_chart_uv_bbox(PChart *chart, float minv[2], float maxv[2])
@@ -498,16 +431,6 @@ static void p_chart_uv_to_array(PChart *chart, float (*points)[2])
}
}
-static void UNUSED_FUNCTION(p_chart_uv_from_array)(PChart *chart, float (*points)[2])
-{
- PVert *v;
- uint i = 0;
-
- for (v = chart->verts; v; v = v->nextlink) {
- copy_v2_v2(v->uv, points[i++]);
- }
-}
-
static bool p_intersect_line_2d_dir(const float v1[2],
const float dir1[2],
const float v2[2],
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
index f179713e8cb..8d77fb50c71 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
@@ -324,6 +324,10 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemPointerR(
row, ptr, "target_material", &obj_data_ptr, "materials", NULL, ICON_SHADING_TEXTURE);
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiItemR(col, ptr, "thickness", UI_ITEM_R_SLIDER, IFACE_("Line Thickness"), ICON_NONE);
+ uiItemR(col, ptr, "opacity", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+
gpencil_modifier_panel_end(layout, ptr);
}
@@ -398,21 +402,6 @@ static void options_panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(col, ptr, "use_back_face_culling", 0, IFACE_("Force Backface Culling"), ICON_NONE);
}
-static void style_panel_draw(const bContext *UNUSED(C), Panel *panel)
-{
- uiLayout *layout = panel->layout;
- PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL);
-
- const bool is_baked = RNA_boolean_get(ptr, "is_baked");
-
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetEnabled(layout, !is_baked);
-
- uiItemR(layout, ptr, "thickness", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
-
- uiItemR(layout, ptr, "opacity", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
-}
-
static void occlusion_panel_draw(const bContext *UNUSED(C), Panel *panel)
{
uiLayout *layout = panel->layout;
@@ -708,8 +697,6 @@ static void panelRegister(ARegionType *region_type)
region_type, "edge_types", "Edge Types", NULL, edge_types_panel_draw, panel_type);
gpencil_modifier_subpanel_register(
region_type, "geometry", "Geometry Processing", NULL, options_panel_draw, panel_type);
- gpencil_modifier_subpanel_register(
- region_type, "style", "Style", NULL, style_panel_draw, panel_type);
PanelType *occlusion_panel = gpencil_modifier_subpanel_register(
region_type, "occlusion", "Occlusion", NULL, occlusion_panel_draw, panel_type);
gpencil_modifier_subpanel_register(region_type,
diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc
index c6eaf7defdc..b7dad589395 100644
--- a/source/blender/gpu/intern/gpu_context.cc
+++ b/source/blender/gpu/intern/gpu_context.cc
@@ -177,7 +177,7 @@ void GPU_render_step()
/** \name Backend selection
* \{ */
-static GPUBackend *g_backend;
+static GPUBackend *g_backend = nullptr;
bool GPU_backend_supported(eGPUBackendType type)
{
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 808a8ccd955..5d6651c3e3a 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -669,7 +669,7 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene,
BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "GPUNodeGraph.used_libraries");
mat->refcount = 1;
#ifndef NDEBUG
- BLI_snprintf(mat->name, sizeof(mat->name), "%s", name);
+ STRNCPY(mat->name, name);
#else
UNUSED_VARS(name);
#endif
diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc
index d78dc845074..c300c0da3b2 100644
--- a/source/blender/gpu/intern/gpu_texture.cc
+++ b/source/blender/gpu/intern/gpu_texture.cc
@@ -702,7 +702,11 @@ void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *r_size)
void GPU_samplers_update()
{
- GPUBackend::get()->samplers_update();
+ /* Backend may not exist when we are updating preferences from background mode. */
+ GPUBackend *backend = GPUBackend::get();
+ if (backend) {
+ backend->samplers_update();
+ }
}
/** \} */
diff --git a/source/blender/gpu/metal/mtl_texture.hh b/source/blender/gpu/metal/mtl_texture.hh
index b820256ec36..b4b1e91c496 100644
--- a/source/blender/gpu/metal/mtl_texture.hh
+++ b/source/blender/gpu/metal/mtl_texture.hh
@@ -349,7 +349,7 @@ class MTLTexture : public Texture {
* - Per-component size matches (e.g. GPU_DATA_UBYTE)
* OR GPU_DATA_10_11_11_REV && GPU_R11G11B10 (equiv)
* OR D24S8 and GPU_DATA_UINT_24_8
- * We can Use BLIT ENCODER.
+ * We can use BLIT ENCODER.
*
* OTHERWISE TRIGGER COMPUTE:
* - Compute sizes will vary. Threads per grid WILL match 'extent'.
diff --git a/source/blender/gpu/shaders/infos/gpu_shader_3D_polyline_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_3D_polyline_info.hh
index 6840dfe25de..396ee64454c 100644
--- a/source/blender/gpu/shaders/infos/gpu_shader_3D_polyline_info.hh
+++ b/source/blender/gpu/shaders/infos/gpu_shader_3D_polyline_info.hh
@@ -37,7 +37,7 @@ GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_uniform_color)
GPU_SHADER_CREATE_INFO(gpu_shader_3D_polyline_uniform_color_clipped)
.do_static_compilation(true)
- /* TODO(fclem): Put in an UBO to fit the 128byte requirement. */
+ /* TODO(fclem): Put in a UBO to fit the 128byte requirement. */
.push_constant(Type::MAT4, "ModelMatrix")
.push_constant(Type::VEC4, "ClipPlane")
.define("CLIP")
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl
index 530907859e9..c95a41c58fc 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl
@@ -34,6 +34,13 @@ void node_eevee_specular(vec4 diffuse,
diffuse_data.N = N;
diffuse_data.sss_id = 0u;
+ /* WORKAROUND: Nasty workaround to the current interface with the closure evaluation.
+ * Ideally the occlusion input should be move to the output node or removed all-together.
+ * This is temporary to avoid a regression in 3.2 and should be removed after EEVEE-Next rewrite.
+ */
+ diffuse_data.sss_radius.r = occlusion;
+ diffuse_data.sss_radius.g = -1.0; /* Flag */
+
ClosureReflection reflection_data;
reflection_data.weight = alpha;
if (true) {
@@ -41,7 +48,7 @@ void node_eevee_specular(vec4 diffuse,
vec2 split_sum = brdf_lut(NV, roughness);
vec3 brdf = F_brdf_single_scatter(specular.rgb, vec3(1.0), split_sum);
- reflection_data.color = specular.rgb * brdf;
+ reflection_data.color = brdf;
reflection_data.N = N;
reflection_data.roughness = roughness;
}
diff --git a/source/blender/imbuf/intern/stereoimbuf.c b/source/blender/imbuf/intern/stereoimbuf.c
index 52756891f21..2a0baaf6172 100644
--- a/source/blender/imbuf/intern/stereoimbuf.c
+++ b/source/blender/imbuf/intern/stereoimbuf.c
@@ -702,21 +702,21 @@ int *IMB_stereo3d_from_rect(const ImageFormatData *im_format,
int *rect_left,
int *rect_right)
{
- int *r_rect;
+ int *rect_result;
Stereo3DData s3d_data = {{NULL}};
size_t width, height;
const bool is_float = im_format->depth > 8;
IMB_stereo3d_write_dimensions(
im_format->stereo3d_format.display_mode, false, x, y, &width, &height);
- r_rect = MEM_mallocN(channels * sizeof(int) * width * height, __func__);
+ rect_result = MEM_mallocN(channels * sizeof(int) * width * height, __func__);
imb_stereo3d_data_init(
- &s3d_data, is_float, x, y, channels, rect_left, rect_right, r_rect, NULL, NULL, NULL);
+ &s3d_data, is_float, x, y, channels, rect_left, rect_right, rect_result, NULL, NULL, NULL);
imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format);
- imb_stereo3d_squeeze_rect(r_rect, &im_format->stereo3d_format, x, y, channels);
+ imb_stereo3d_squeeze_rect(rect_result, &im_format->stereo3d_format, x, y, channels);
- return r_rect;
+ return rect_result;
}
float *IMB_stereo3d_from_rectf(const ImageFormatData *im_format,
@@ -726,21 +726,30 @@ float *IMB_stereo3d_from_rectf(const ImageFormatData *im_format,
float *rectf_left,
float *rectf_right)
{
- float *r_rectf;
+ float *rectf_result;
Stereo3DData s3d_data = {{NULL}};
size_t width, height;
const bool is_float = im_format->depth > 8;
IMB_stereo3d_write_dimensions(
im_format->stereo3d_format.display_mode, false, x, y, &width, &height);
- r_rectf = MEM_mallocN(channels * sizeof(float) * width * height, __func__);
+ rectf_result = MEM_mallocN(channels * sizeof(float) * width * height, __func__);
- imb_stereo3d_data_init(
- &s3d_data, is_float, x, y, channels, NULL, NULL, NULL, rectf_left, rectf_right, r_rectf);
+ imb_stereo3d_data_init(&s3d_data,
+ is_float,
+ x,
+ y,
+ channels,
+ NULL,
+ NULL,
+ NULL,
+ rectf_left,
+ rectf_right,
+ rectf_result);
imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format);
- imb_stereo3d_squeeze_rectf(r_rectf, &im_format->stereo3d_format, x, y, channels);
+ imb_stereo3d_squeeze_rectf(rectf_result, &im_format->stereo3d_format, x, y, channels);
- return r_rectf;
+ return rectf_result;
}
ImBuf *IMB_stereo3d_ImBuf(const ImageFormatData *im_format, ImBuf *ibuf_left, ImBuf *ibuf_right)
diff --git a/source/blender/io/alembic/intern/alembic_capi.cc b/source/blender/io/alembic/intern/alembic_capi.cc
index 0d4e1d04db0..1fb535a57f2 100644
--- a/source/blender/io/alembic/intern/alembic_capi.cc
+++ b/source/blender/io/alembic/intern/alembic_capi.cc
@@ -573,12 +573,10 @@ static void import_endjob(void *user_data)
ImportJobData *data = static_cast<ImportJobData *>(user_data);
- std::vector<AbcObjectReader *>::iterator iter;
-
/* Delete objects on cancellation. */
if (data->was_cancelled) {
- for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
- Object *ob = (*iter)->object();
+ for (AbcObjectReader *reader : data->readers) {
+ Object *ob = reader->object();
/* It's possible that cancellation occurred between the creation of
* the reader and the creation of the Blender object. */
@@ -590,7 +588,6 @@ static void import_endjob(void *user_data)
}
}
else {
- /* Add object to scene. */
Base *base;
LayerCollection *lc;
ViewLayer *view_layer = data->view_layer;
@@ -599,11 +596,17 @@ static void import_endjob(void *user_data)
lc = BKE_layer_collection_get_active(view_layer);
- for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
- Object *ob = (*iter)->object();
-
+ /* Add all objects to the collection (don't do sync for each object). */
+ BKE_layer_collection_resync_forbid();
+ for (AbcObjectReader *reader : data->readers) {
+ Object *ob = reader->object();
BKE_collection_object_add(data->bmain, lc->collection, ob);
-
+ }
+ /* Sync the collection, and do view layer operations. */
+ BKE_layer_collection_resync_allow();
+ BKE_main_collection_sync(data->bmain);
+ for (AbcObjectReader *reader : data->readers) {
+ Object *ob = reader->object();
base = BKE_view_layer_base_find(view_layer, ob);
/* TODO: is setting active needed? */
BKE_view_layer_base_select_and_set_active(view_layer, base);
@@ -625,8 +628,7 @@ static void import_endjob(void *user_data)
}
}
- for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
- AbcObjectReader *reader = *iter;
+ for (AbcObjectReader *reader : data->readers) {
reader->decref();
if (reader->refcount() == 0) {
diff --git a/source/blender/io/stl/importer/stl_import_mesh.cc b/source/blender/io/stl/importer/stl_import_mesh.cc
index 7de8239b233..b9ed441f0d9 100644
--- a/source/blender/io/stl/importer/stl_import_mesh.cc
+++ b/source/blender/io/stl/importer/stl_import_mesh.cc
@@ -63,11 +63,11 @@ void STLMeshHelper::add_triangle(const float3 &a,
Mesh *STLMeshHelper::to_mesh(Main *bmain, char *mesh_name)
{
if (degenerate_tris_num_ > 0) {
- std::cout << "STL Importer: " << degenerate_tris_num_ << "degenerate triangles were removed"
+ std::cout << "STL Importer: " << degenerate_tris_num_ << " degenerate triangles were removed"
<< std::endl;
}
if (duplicate_tris_num_ > 0) {
- std::cout << "STL Importer: " << duplicate_tris_num_ << "duplicate triangles were removed"
+ std::cout << "STL Importer: " << duplicate_tris_num_ << " duplicate triangles were removed"
<< std::endl;
}
diff --git a/source/blender/io/usd/intern/usd_capi_import.cc b/source/blender/io/usd/intern/usd_capi_import.cc
index 29b256125f0..4118205d87f 100644
--- a/source/blender/io/usd/intern/usd_capi_import.cc
+++ b/source/blender/io/usd/intern/usd_capi_import.cc
@@ -277,7 +277,6 @@ static void import_endjob(void *customdata)
}
}
else if (data->archive) {
- /* Add object to scene. */
Base *base;
LayerCollection *lc;
ViewLayer *view_layer = data->view_layer;
@@ -286,20 +285,30 @@ static void import_endjob(void *customdata)
lc = BKE_layer_collection_get_active(view_layer);
+ /* Add all objects to the collection (don't do sync for each object). */
+ BKE_layer_collection_resync_forbid();
for (USDPrimReader *reader : data->archive->readers()) {
-
if (!reader) {
continue;
}
-
Object *ob = reader->object();
-
if (!ob) {
continue;
}
-
BKE_collection_object_add(data->bmain, lc->collection, ob);
+ }
+ /* Sync the collection, and do view layer operations. */
+ BKE_layer_collection_resync_allow();
+ BKE_main_collection_sync(data->bmain);
+ for (USDPrimReader *reader : data->archive->readers()) {
+ if (!reader) {
+ continue;
+ }
+ Object *ob = reader->object();
+ if (!ob) {
+ continue;
+ }
base = BKE_view_layer_base_find(view_layer, ob);
/* TODO: is setting active needed? */
BKE_view_layer_base_select_and_set_active(view_layer, base);
diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc
index 368d0e1bab9..36e1a40953c 100644
--- a/source/blender/io/usd/intern/usd_reader_mesh.cc
+++ b/source/blender/io/usd/intern/usd_reader_mesh.cc
@@ -111,6 +111,7 @@ static void assign_materials(Main *bmain,
const std::map<pxr::SdfPath, int> &mat_index_map,
const USDImportParams &params,
pxr::UsdStageRefPtr stage,
+ std::map<std::string, Material *> &mat_name_to_mat,
std::map<std::string, std::string> &usd_path_to_mat_name)
{
if (!(stage && bmain && ob)) {
@@ -132,16 +133,12 @@ static void assign_materials(Main *bmain,
return;
}
- /* TODO(kevin): use global map? */
- std::map<std::string, Material *> mat_map;
- build_mat_map(bmain, &mat_map);
-
blender::io::usd::USDMaterialReader mat_reader(params, bmain);
for (it = mat_index_map.begin(); it != mat_index_map.end(); ++it) {
Material *assigned_mat = find_existing_material(
- it->first, params, mat_map, usd_path_to_mat_name);
+ it->first, params, mat_name_to_mat, usd_path_to_mat_name);
if (!assigned_mat) {
/* Blender material doesn't exist, so create it now. */
@@ -165,7 +162,7 @@ static void assign_materials(Main *bmain,
}
const std::string mat_name = pxr::TfMakeValidIdentifier(assigned_mat->id.name + 2);
- mat_map[mat_name] = assigned_mat;
+ mat_name_to_mat[mat_name] = assigned_mat;
if (params.mtl_name_collision_mode == USD_MTL_NAME_COLLISION_MAKE_UNIQUE) {
/* Record the name of the Blender material we created for the USD material
@@ -805,11 +802,16 @@ void USDMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, const double mot
std::map<pxr::SdfPath, int> mat_map;
assign_facesets_to_mpoly(motionSampleTime, mesh->mpoly, mesh->totpoly, &mat_map);
+ /* Build material name map if it's not built yet. */
+ if (this->settings_->mat_name_to_mat.empty()) {
+ utils::build_mat_map(bmain, &this->settings_->mat_name_to_mat);
+ }
utils::assign_materials(bmain,
object_,
mat_map,
this->import_params_,
this->prim_.GetStage(),
+ this->settings_->mat_name_to_mat,
this->settings_->usd_path_to_mat_name);
}
diff --git a/source/blender/io/usd/intern/usd_reader_prim.h b/source/blender/io/usd/intern/usd_reader_prim.h
index f2df00accf6..c44c4a14ad7 100644
--- a/source/blender/io/usd/intern/usd_reader_prim.h
+++ b/source/blender/io/usd/intern/usd_reader_prim.h
@@ -11,6 +11,7 @@
#include <string>
struct Main;
+struct Material;
struct Object;
namespace blender::io::usd {
@@ -42,6 +43,10 @@ struct ImportSettings {
* of what the importer is doing. This is necessary even
* when all the other import settings are to remain const. */
mutable std::map<std::string, std::string> usd_path_to_mat_name;
+ /* Map a material name to Blender material.
+ * This map is updated by readers during stage traversal,
+ * and is mutable similar to the map above. */
+ mutable std::map<std::string, Material *> mat_name_to_mat;
ImportSettings()
: do_convert_mat(false),
diff --git a/source/blender/io/wavefront_obj/IO_wavefront_obj.h b/source/blender/io/wavefront_obj/IO_wavefront_obj.h
index a719dff2126..b4a00deb99c 100644
--- a/source/blender/io/wavefront_obj/IO_wavefront_obj.h
+++ b/source/blender/io/wavefront_obj/IO_wavefront_obj.h
@@ -72,6 +72,7 @@ struct OBJImportParams {
float clamp_size;
eIOAxis forward_axis;
eIOAxis up_axis;
+ bool import_vertex_groups;
bool validate_meshes;
};
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
index 9cfce5c2257..3cc17e7d8e6 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
@@ -6,6 +6,7 @@
#include "BLI_map.hh"
#include "BLI_math_color.h"
+#include "BLI_math_vector.h"
#include "BLI_string_ref.hh"
#include "BLI_vector.hh"
@@ -78,7 +79,7 @@ static void geom_add_vertex(Geometry *geom,
p = parse_floats(p, end, 0.0f, vert, 3);
r_global_vertices.vertices.append(vert);
geom->vertex_count_++;
- /* OBJ extension: "xyzrgb" vertex colors, when the vertex position
+ /* OBJ extension: `xyzrgb` vertex colors, when the vertex position
* is followed by 3 more RGB color components. See
* http://paulbourke.net/dataformats/obj/colour.html */
if (p < end) {
@@ -129,6 +130,10 @@ static void geom_add_vertex_normal(Geometry *geom,
{
float3 normal;
parse_floats(p, end, 0.0f, normal, 3);
+ /* Normals can be printed with only several digits in the file,
+ * making them ever-so-slightly non unit length. Make sure they are
+ * normalized. */
+ normalize_v3(normal);
r_global_vertices.vertex_normals.append(normal);
geom->has_vertex_normals_ = true;
}
@@ -170,7 +175,7 @@ static void geom_add_polygon(Geometry *geom,
curr_face.material_index = material_index;
if (group_index >= 0) {
curr_face.vertex_group_index = group_index;
- geom->use_vertex_groups_ = true;
+ geom->has_vertex_groups_ = true;
}
const int orig_corners_size = geom->face_corners_.size();
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
index acc35ad46e1..51318331c76 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
@@ -10,6 +10,7 @@
#include "BKE_attribute.h"
#include "BKE_customdata.h"
+#include "BKE_deform.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_node_tree_update.h"
@@ -47,7 +48,7 @@ Object *MeshFromGeometry::create_mesh(Main *bmain,
obj->data = BKE_object_obdata_add_from_type(bmain, OB_MESH, ob_name.c_str());
create_vertices(mesh);
- create_polys_loops(obj, mesh);
+ create_polys_loops(obj, mesh, import_params.import_vertex_groups);
create_edges(mesh);
create_uv_verts(mesh);
create_normals(mesh);
@@ -69,6 +70,9 @@ Object *MeshFromGeometry::create_mesh(Main *bmain,
BKE_mesh_nomain_to_mesh(mesh, dst, obj, &CD_MASK_EVERYTHING, true);
dst->flag |= autosmooth;
+ /* Note: vertex groups have to be created after final mesh is assigned to the object. */
+ create_vertex_groups(obj);
+
return obj;
}
@@ -163,19 +167,13 @@ void MeshFromGeometry::create_vertices(Mesh *mesh)
}
}
-void MeshFromGeometry::create_polys_loops(Object *obj, Mesh *mesh)
+void MeshFromGeometry::create_polys_loops(Object *obj, Mesh *mesh, bool use_vertex_groups)
{
- /* Will not be used if vertex groups are not imported. */
mesh->dvert = nullptr;
- float weight = 0.0f;
const int64_t total_verts = mesh_geometry_.vertex_count_;
- if (total_verts && mesh_geometry_.use_vertex_groups_) {
+ if (use_vertex_groups && total_verts && mesh_geometry_.has_vertex_groups_) {
mesh->dvert = static_cast<MDeformVert *>(
CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, nullptr, total_verts));
- weight = 1.0f / total_verts;
- }
- else {
- UNUSED_VARS(weight);
}
const int64_t tot_face_elems{mesh->totpoly};
@@ -208,28 +206,23 @@ void MeshFromGeometry::create_polys_loops(Object *obj, Mesh *mesh)
tot_loop_idx++;
mloop.v = curr_corner.vert_index;
+ /* Setup vertex group data, if needed. */
if (!mesh->dvert) {
continue;
}
- /* Iterating over mloop results in finding the same vertex multiple times.
- * Another way is to allocate memory for dvert while creating vertices and fill them here.
- */
- MDeformVert &def_vert = mesh->dvert[mloop.v];
- if (!def_vert.dw) {
- def_vert.dw = static_cast<MDeformWeight *>(
- MEM_callocN(sizeof(MDeformWeight), "OBJ Import Deform Weight"));
- }
- /* Every vertex in a face is assigned the same deform group. */
- int group_idx = curr_face.vertex_group_index;
- /* Deform group number (def_nr) must behave like an index into the names' list. */
- *(def_vert.dw) = {static_cast<unsigned int>(group_idx), weight};
+ const int group_index = curr_face.vertex_group_index;
+ MDeformWeight *dw = BKE_defvert_ensure_index(mesh->dvert + mloop.v, group_index);
+ dw->weight = 1.0f;
}
}
+}
- if (!mesh->dvert) {
+void MeshFromGeometry::create_vertex_groups(Object *obj)
+{
+ Mesh *mesh = static_cast<Mesh *>(obj->data);
+ if (mesh->dvert == nullptr) {
return;
}
- /* Add deform group names. */
for (const std::string &name : mesh_geometry_.group_order_) {
BKE_object_defgroup_add_name(obj, name.data());
}
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.hh b/source/blender/io/wavefront_obj/importer/obj_import_mesh.hh
index 216717f3578..c6773cfa0cb 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.hh
+++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.hh
@@ -45,10 +45,9 @@ class MeshFromGeometry : NonMovable, NonCopyable {
void fixup_invalid_faces();
void create_vertices(Mesh *mesh);
/**
- * Create polygons for the Mesh, set smooth shading flags, deform group names,
- * Materials.
+ * Create polygons for the Mesh, set smooth shading flags, Materials.
*/
- void create_polys_loops(Object *obj, Mesh *mesh);
+ void create_polys_loops(Object *obj, Mesh *mesh, bool use_vertex_groups);
/**
* Add explicitly imported OBJ edges to the mesh.
*/
@@ -66,6 +65,7 @@ class MeshFromGeometry : NonMovable, NonCopyable {
Object *obj);
void create_normals(Mesh *mesh);
void create_colors(Mesh *mesh);
+ void create_vertex_groups(Object *obj);
};
} // namespace blender::io::obj
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_objects.hh b/source/blender/io/wavefront_obj/importer/obj_import_objects.hh
index 69babc26bb0..3d6733d661e 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_objects.hh
+++ b/source/blender/io/wavefront_obj/importer/obj_import_objects.hh
@@ -113,7 +113,7 @@ struct Geometry {
bool has_invalid_polys_ = false;
bool has_vertex_normals_ = false;
- bool use_vertex_groups_ = false;
+ bool has_vertex_groups_ = false;
NurbsElement nurbs_element_;
int total_loops_ = 0;
};
diff --git a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc
index b67adbc9753..eeb81f5e23e 100644
--- a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc
+++ b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc
@@ -58,6 +58,8 @@ class obj_importer_test : public BlendfileLoadingBaseTest {
params.clamp_size = 0;
params.forward_axis = IO_AXIS_NEGATIVE_Z;
params.up_axis = IO_AXIS_Y;
+ params.validate_meshes = true;
+ params.import_vertex_groups = false;
std::string obj_path = blender::tests::flags_test_asset_dir() + "/io_tests/obj/" + path;
strncpy(params.filepath, obj_path.c_str(), FILE_MAX - 1);
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 6557f35970d..8e0ce68f71a 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -105,8 +105,10 @@ typedef struct bConstraintTarget {
/* bConstraintTarget -> flag */
typedef enum eConstraintTargetFlag {
- /** temporary target-struct that needs to be freed after use */
+ /** Temporary target-struct that needs to be freed after use. */
CONSTRAINT_TAR_TEMP = (1 << 0),
+ /** Temporary target for the custom space reference. */
+ CONSTRAINT_TAR_CUSTOM_SPACE = (1 << 1),
} eConstraintTargetFlag;
/* bConstraintTarget/bConstraintOb -> type */
@@ -247,10 +249,9 @@ typedef struct bArmatureConstraint {
typedef struct bTrackToConstraint {
struct Object *tar;
/**
- * I'll be using reserved1 and reserved2 as Track and Up flags,
+ * NOTE(@theeth): I'll be using reserved1 and reserved2 as Track and Up flags,
* not sure if that's what they were intended for anyway.
* Not sure either if it would create backward incompatibility if I were to rename them.
- * - theeth
*/
int reserved1;
int reserved2;
diff --git a/source/blender/makesdna/DNA_ipo_types.h b/source/blender/makesdna/DNA_ipo_types.h
index 70ee7c99d01..ef35b72d2ab 100644
--- a/source/blender/makesdna/DNA_ipo_types.h
+++ b/source/blender/makesdna/DNA_ipo_types.h
@@ -338,7 +338,7 @@ typedef struct Ipo {
#define CAM_STA 2
#define CAM_END 3
-/* yafray aperture & focal distance curves */
+/* YAFRAY aperture & focal distance curves. */
#define CAM_YF_APERT 4
#define CAM_YF_FDIST 5
diff --git a/source/blender/makesdna/DNA_light_types.h b/source/blender/makesdna/DNA_light_types.h
index 9202d7c2d51..f1bf0580b94 100644
--- a/source/blender/makesdna/DNA_light_types.h
+++ b/source/blender/makesdna/DNA_light_types.h
@@ -120,7 +120,7 @@ typedef struct Light {
/* #define LA_NO_DIFF (1 << 11) */ /* not used anywhere */
/* #define LA_NO_SPEC (1 << 12) */ /* not used anywhere */
/* #define LA_SHAD_RAY (1 << 13) */ /* not used anywhere - cleaned */
-/* yafray: light shadowbuffer flag, softlight */
+/* YAFRAY: light shadow-buffer flag, soft-light. */
/* Since it is used with LOCAL light, can't use LA_SHAD */
/* #define LA_YF_SOFT (1 << 14) */ /* not used anymore */
/* #define LA_LAYER_SHADOW (1 << 15) */ /* not used anymore */
diff --git a/source/blender/makesdna/DNA_space_defaults.h b/source/blender/makesdna/DNA_space_defaults.h
index e826cb4c2ef..66a09bc82c3 100644
--- a/source/blender/makesdna/DNA_space_defaults.h
+++ b/source/blender/makesdna/DNA_space_defaults.h
@@ -18,6 +18,7 @@
.draw_flag = 0, \
.draw_type = MASK_DT_OUTLINE, \
.overlay_mode = MASK_OVERLAY_ALPHACHANNEL, \
+ .blend_factor = 0.7f, \
}
#define _DNA_DEFAULT_SpaceClip \
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index be073ef2c15..2905ef06833 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -732,7 +732,8 @@ typedef struct MaskSpaceInfo {
char draw_flag;
char draw_type;
char overlay_mode;
- char _pad3[5];
+ char _pad3[1];
+ float blend_factor;
} MaskSpaceInfo;
/** #SpaceSeq.gizmo_flag */
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index b725939dbab..e32d9dbe300 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -397,8 +397,7 @@ typedef struct ColorMapping {
/* return value */
#define TEX_INT 0
-#define TEX_RGB (1 << 0)
-#define TEX_NOR (1 << 1)
+#define TEX_RGB 1
/* pr_texture in material, world, light. */
#define TEX_PR_TEXTURE 0
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index cfd0c986df9..f7aaa1186db 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -463,14 +463,19 @@ typedef struct wmKeyMap {
/** #wmKeyMap.flag */
enum {
- KEYMAP_MODAL = (1 << 0), /* modal map, not using operatornames */
- KEYMAP_USER = (1 << 1), /* user keymap */
+ /** Modal map, not using operator-names. */
+ KEYMAP_MODAL = (1 << 0),
+ /** User key-map. */
+ KEYMAP_USER = (1 << 1),
KEYMAP_EXPANDED = (1 << 2),
KEYMAP_CHILDREN_EXPANDED = (1 << 3),
- KEYMAP_DIFF = (1 << 4), /* diff keymap for user preferences */
- KEYMAP_USER_MODIFIED = (1 << 5), /* keymap has user modifications */
+ /** Diff key-map for user preferences. */
+ KEYMAP_DIFF = (1 << 4),
+ /** Key-map has user modifications. */
+ KEYMAP_USER_MODIFIED = (1 << 5),
KEYMAP_UPDATE = (1 << 6),
- KEYMAP_TOOL = (1 << 7), /* keymap for active tool system */
+ /** key-map for active tool system. */
+ KEYMAP_TOOL = (1 << 7),
};
/**
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 312c0753ce7..0bc35d86490 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -6108,7 +6108,7 @@ char *RNA_path_struct_property_py(PointerRNA *ptr, PropertyRNA *prop, int index)
}
if ((index == -1) || (RNA_property_array_check(prop) == false)) {
- ret = BLI_sprintfN("%s", data_path);
+ ret = BLI_strdup(data_path);
}
else {
ret = BLI_sprintfN("%s[%d]", data_path, index);
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 8591d4abd63..4810784b3f7 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -4993,7 +4993,7 @@ static void rna_def_modifier_weightvg_mask(BlenderRNA *UNUSED(brna),
0,
"Object",
"Use local generated coordinates of another object"},
- {MOD_DISP_MAP_UV, "UV", 0, "UV", "Use coordinates from an UV layer"},
+ {MOD_DISP_MAP_UV, "UV", 0, "UV", "Use coordinates from a UV layer"},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 4108baca2fa..30df8e20e8d 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -698,16 +698,18 @@ bool rna_PoseChannel_constraints_override_apply(Main *bmain,
return true;
}
-static int rna_PoseChannel_proxy_editable(PointerRNA *ptr, const char **r_info)
+static int rna_PoseChannel_proxy_editable(PointerRNA *UNUSED(ptr), const char **UNUSED(r_info))
{
+# if 0
Object *ob = (Object *)ptr->owner_id;
bArmature *arm = ob->data;
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
- if (false && pchan->bone && (pchan->bone->layer & arm->layer_protected)) {
+ if (pchan->bone && (pchan->bone->layer & arm->layer_protected)) {
*r_info = "Can't edit property of a proxy on a protected layer";
return 0;
}
+# endif
return PROP_EDITABLE;
}
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index cae86801402..910e78e7a58 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -3493,6 +3493,13 @@ static void rna_def_space_mask_info(StructRNA *srna, int noteflag, const char *m
RNA_def_property_enum_items(prop, overlay_mode_items);
RNA_def_property_ui_text(prop, "Overlay Mode", "Overlay mode of rasterized mask");
RNA_def_property_update(prop, noteflag, NULL);
+
+ prop = RNA_def_property(srna, "blend_factor", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "mask_info.blend_factor");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_range(prop, 0, 1., 0.1, 1);
+ RNA_def_property_ui_text(prop, "Blending Factor", "Overlay blending factor of rasterized mask");
+ RNA_def_property_update(prop, noteflag, NULL);
}
static void rna_def_space_image_uv(BlenderRNA *brna)
diff --git a/source/blender/modifiers/intern/MOD_boolean.cc b/source/blender/modifiers/intern/MOD_boolean.cc
index 07504d91fea..5739de1c65c 100644
--- a/source/blender/modifiers/intern/MOD_boolean.cc
+++ b/source/blender/modifiers/intern/MOD_boolean.cc
@@ -447,7 +447,8 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd,
material_remaps,
use_self,
hole_tolerant,
- bmd->operation);
+ bmd->operation,
+ nullptr);
}
#endif
diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c
index 149cf0c0cbb..1e2224e3a65 100644
--- a/source/blender/modifiers/intern/MOD_displace.c
+++ b/source/blender/modifiers/intern/MOD_displace.c
@@ -197,7 +197,6 @@ static void displaceModifier_do_task(void *__restrict userdata,
}
if (data->tex_target) {
- texres.nor = NULL;
BKE_texture_get_value_ex(
data->scene, data->tex_target, tex_co[iter], &texres, data->pool, false);
delta = texres.tin - dmd->midlevel;
diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c
index 402d7b2c99e..9693cf0c0f2 100644
--- a/source/blender/modifiers/intern/MOD_warp.c
+++ b/source/blender/modifiers/intern/MOD_warp.c
@@ -302,7 +302,6 @@ static void warpModifier_do(WarpModifierData *wmd,
if (tex_co) {
struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
TexResult texres;
- texres.nor = NULL;
BKE_texture_get_value(scene, tex_target, tex_co[i], &texres, false);
fac *= texres.tin;
}
diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c
index 73b26dc29cd..4073f028db5 100644
--- a/source/blender/modifiers/intern/MOD_wave.c
+++ b/source/blender/modifiers/intern/MOD_wave.c
@@ -262,7 +262,6 @@ static void waveModifier_do(WaveModifierData *md,
if (tex_co) {
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
TexResult texres;
- texres.nor = NULL;
BKE_texture_get_value(scene, tex_target, tex_co[i], &texres, false);
amplit *= texres.tin;
}
diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c
index 65393370268..3302384568b 100644
--- a/source/blender/modifiers/intern/MOD_weightvg_util.c
+++ b/source/blender/modifiers/intern/MOD_weightvg_util.c
@@ -162,7 +162,6 @@ void weightvg_do_mask(const ModifierEvalContext *ctx,
do_color_manage = tex_use_channel != MOD_WVG_MASK_TEX_USE_INT;
- texres.nor = NULL;
BKE_texture_get_value(scene, texture, tex_co[idx], &texres, do_color_manage);
/* Get the good channel value... */
switch (tex_use_channel) {
diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h
index dc90073ec31..e4e4295fd3a 100644
--- a/source/blender/nodes/NOD_geometry.h
+++ b/source/blender/nodes/NOD_geometry.h
@@ -135,6 +135,7 @@ void register_node_type_geo_transform(void);
void register_node_type_geo_translate_instances(void);
void register_node_type_geo_triangulate(void);
void register_node_type_geo_viewer(void);
+void register_node_type_geo_volume_cube(void);
void register_node_type_geo_volume_to_mesh(void);
#ifdef __cplusplus
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 7ca013bf792..9793f133dd6 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -397,6 +397,7 @@ DefNode(GeometryNode, GEO_NODE_TRANSLATE_INSTANCES, 0, "TRANSLATE_INSTANCES", Tr
DefNode(GeometryNode, GEO_NODE_TRIANGULATE, def_geo_triangulate, "TRIANGULATE", Triangulate, "Triangulate", "")
DefNode(GeometryNode, GEO_NODE_TRIM_CURVE, def_geo_curve_trim, "TRIM_CURVE", TrimCurve, "Trim Curve", "")
DefNode(GeometryNode, GEO_NODE_VIEWER, def_geo_viewer, "VIEWER", Viewer, "Viewer", "")
+DefNode(GeometryNode, GEO_NODE_VOLUME_CUBE, 0, "VOLUME_CUBE", VolumeCube, "Volume Cube", "")
DefNode(GeometryNode, GEO_NODE_VOLUME_TO_MESH, def_geo_volume_to_mesh, "VOLUME_TO_MESH", VolumeToMesh, "Volume to Mesh", "")
/* undefine macros */
diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt
index 54fda328ca8..015edf2d26c 100644
--- a/source/blender/nodes/geometry/CMakeLists.txt
+++ b/source/blender/nodes/geometry/CMakeLists.txt
@@ -144,6 +144,7 @@ set(SRC
nodes/node_geo_translate_instances.cc
nodes/node_geo_triangulate.cc
nodes/node_geo_viewer.cc
+ nodes/node_geo_volume_cube.cc
nodes/node_geo_volume_to_mesh.cc
node_geometry_exec.cc
diff --git a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
index e485172d3e1..daeca311e08 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
@@ -20,6 +20,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Bool>(N_("Self Intersection"));
b.add_input<decl::Bool>(N_("Hole Tolerant"));
b.add_output<decl::Geometry>(N_("Mesh"));
+ b.add_output<decl::Bool>(N_("Intersecting Edges")).field_source();
}
static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -27,6 +28,10 @@ static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
}
+struct AttributeOutputs {
+ StrongAnonymousAttributeID intersecting_edges_id;
+};
+
static void node_update(bNodeTree *ntree, bNode *node)
{
GeometryNodeBooleanOperation operation = (GeometryNodeBooleanOperation)node->custom1;
@@ -121,13 +126,21 @@ static void node_geo_exec(GeoNodeExecParams params)
}
}
- Mesh *result = blender::meshintersect::direct_mesh_boolean(meshes,
- transforms,
- float4x4::identity(),
- material_remaps,
- use_self,
- hole_tolerant,
- operation);
+ AttributeOutputs attribute_outputs;
+ if (params.output_is_required("Intersecting Edges")) {
+ attribute_outputs.intersecting_edges_id = StrongAnonymousAttributeID("Intersecting Edges");
+ }
+
+ Vector<int> intersecting_edges;
+ Mesh *result = blender::meshintersect::direct_mesh_boolean(
+ meshes,
+ transforms,
+ float4x4::identity(),
+ material_remaps,
+ use_self,
+ hole_tolerant,
+ operation,
+ attribute_outputs.intersecting_edges_id ? &intersecting_edges : nullptr);
if (!result) {
params.set_default_remaining_outputs();
return;
@@ -138,6 +151,26 @@ static void node_geo_exec(GeoNodeExecParams params)
result->totcol = materials.size();
MutableSpan(result->mat, result->totcol).copy_from(materials);
+ /* Store intersecting edges in attribute. */
+ if (attribute_outputs.intersecting_edges_id) {
+ MeshComponent mesh_component;
+ mesh_component.replace(result, GeometryOwnershipType::Editable);
+ OutputAttribute_Typed<bool> attribute = mesh_component.attribute_try_get_for_output_only<bool>(
+ attribute_outputs.intersecting_edges_id.get(), ATTR_DOMAIN_EDGE);
+ MutableSpan<bool> selection = attribute.as_span();
+ selection.fill(false);
+ for (const int i : intersecting_edges) {
+ selection[i] = true;
+ }
+
+ attribute.save();
+
+ params.set_output(
+ "Intersecting Edges",
+ AnonymousAttributeFieldInput::Create<bool>(
+ std::move(attribute_outputs.intersecting_edges_id), params.attribute_producer_name()));
+ }
+
params.set_output("Mesh", GeometrySet::create_with_mesh(result));
#else
params.error_message_add(NodeWarningType::Error,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_volume_cube.cc b/source/blender/nodes/geometry/nodes/node_geo_volume_cube.cc
new file mode 100644
index 00000000000..d7e9e38ea0d
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_volume_cube.cc
@@ -0,0 +1,197 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifdef WITH_OPENVDB
+# include <openvdb/openvdb.h>
+# include <openvdb/tools/Dense.h>
+# include <openvdb/tools/LevelSetUtil.h>
+# include <openvdb/tools/ParticlesToLevelSet.h>
+#endif
+
+#include "node_geometry_util.hh"
+
+#include "DNA_mesh_types.h"
+
+#include "BLI_task.hh"
+
+#include "BKE_geometry_set.hh"
+#include "BKE_lib_id.h"
+#include "BKE_mesh.h"
+#include "BKE_volume.h"
+
+namespace blender::nodes::node_geo_volume_cube_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("Density"))
+ .description(N_("Volume density per voxel"))
+ .supports_field()
+ .default_value(1.0f);
+ b.add_input<decl::Float>(N_("Background"))
+ .description(N_("Value for voxels outside of the cube"));
+
+ b.add_input<decl::Vector>(N_("Min"))
+ .description(N_("Minimum boundary of volume"))
+ .default_value(float3(-1.0f));
+ b.add_input<decl::Vector>(N_("Max"))
+ .description(N_("Maximum boundary of volume"))
+ .default_value(float3(1.0f));
+
+ b.add_input<decl::Int>(N_("Resolution X"))
+ .description(N_("Number of voxels in the X axis"))
+ .default_value(32)
+ .min(2);
+ b.add_input<decl::Int>(N_("Resolution Y"))
+ .description(N_("Number of voxels in the Y axis"))
+ .default_value(32)
+ .min(2);
+ b.add_input<decl::Int>(N_("Resolution Z"))
+ .description(N_("Number of voxels in the Z axis"))
+ .default_value(32)
+ .min(2);
+
+ b.add_output<decl::Geometry>(N_("Volume"));
+}
+
+static float map(const float x,
+ const float in_min,
+ const float in_max,
+ const float out_min,
+ const float out_max)
+{
+ return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
+}
+
+class Grid3DFieldContext : public FieldContext {
+ private:
+ int3 resolution_;
+ float3 bounds_min_;
+ float3 bounds_max_;
+
+ public:
+ Grid3DFieldContext(const int3 resolution, const float3 bounds_min, const float3 bounds_max)
+ : resolution_(resolution), bounds_min_(bounds_min), bounds_max_(bounds_max)
+ {
+ }
+
+ int64_t points_num() const
+ {
+ return static_cast<int64_t>(resolution_.x) * static_cast<int64_t>(resolution_.y) *
+ static_cast<int64_t>(resolution_.z);
+ }
+
+ GVArray get_varray_for_input(const FieldInput &field_input,
+ const IndexMask UNUSED(mask),
+ ResourceScope &UNUSED(scope)) const
+ {
+ const bke::AttributeFieldInput *attribute_field_input =
+ dynamic_cast<const bke::AttributeFieldInput *>(&field_input);
+ if (attribute_field_input == nullptr) {
+ return {};
+ }
+ if (attribute_field_input->attribute_name() != "position") {
+ return {};
+ }
+
+ Array<float3> positions(this->points_num());
+
+ threading::parallel_for(IndexRange(resolution_.x), 1, [&](const IndexRange x_range) {
+ /* Start indexing at current X slice. */
+ int64_t index = x_range.start() * resolution_.y * resolution_.z;
+ for (const int64_t x_i : x_range) {
+ const float x = map(x_i, 0.0f, resolution_.x - 1, bounds_min_.x, bounds_max_.x);
+ for (const int64_t y_i : IndexRange(resolution_.y)) {
+ const float y = map(y_i, 0.0f, resolution_.y - 1, bounds_min_.y, bounds_max_.y);
+ for (const int64_t z_i : IndexRange(resolution_.z)) {
+ const float z = map(z_i, 0.0f, resolution_.z - 1, bounds_min_.z, bounds_max_.z);
+ positions[index] = float3(x, y, z);
+ index++;
+ }
+ }
+ }
+ });
+ return VArray<float3>::ForContainer(std::move(positions));
+ }
+};
+
+#ifdef WITH_OPENVDB
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ const float3 bounds_min = params.extract_input<float3>("Min");
+ const float3 bounds_max = params.extract_input<float3>("Max");
+
+ const int3 resolution = int3(params.extract_input<int>("Resolution X"),
+ params.extract_input<int>("Resolution Y"),
+ params.extract_input<int>("Resolution Z"));
+
+ if (resolution.x < 2 || resolution.y < 2 || resolution.z < 2) {
+ params.error_message_add(NodeWarningType::Error, TIP_("Resolution must be greater than 1"));
+ params.set_default_remaining_outputs();
+ return;
+ }
+
+ if (bounds_min.x == bounds_max.x || bounds_min.y == bounds_max.y ||
+ bounds_min.z == bounds_max.z) {
+ params.error_message_add(NodeWarningType::Error,
+ TIP_("Bounding box volume must be greater than 0"));
+ params.set_default_remaining_outputs();
+ return;
+ }
+
+ Field<float> input_field = params.extract_input<Field<float>>("Density");
+
+ /* Evaluate input field on a 3D grid. */
+ Grid3DFieldContext context(resolution, bounds_min, bounds_max);
+ FieldEvaluator evaluator(context, context.points_num());
+ Array<float> densities(context.points_num());
+ evaluator.add_with_destination(std::move(input_field), densities.as_mutable_span());
+ evaluator.evaluate();
+
+ /* Store resulting values in openvdb grid. */
+ const float background = params.extract_input<float>("Background");
+ openvdb::FloatGrid::Ptr grid = openvdb::FloatGrid::create(background);
+ grid->setGridClass(openvdb::GRID_FOG_VOLUME);
+
+ openvdb::tools::Dense<float, openvdb::tools::LayoutZYX> dense_grid{
+ openvdb::math::CoordBBox({0, 0, 0}, {resolution.x - 1, resolution.y - 1, resolution.z - 1}),
+ densities.data()};
+ openvdb::tools::copyFromDense(dense_grid, *grid, 0.0f);
+
+ grid->transform().preTranslate(openvdb::math::Vec3<float>(-0.5f));
+ const float3 scale_fac = (bounds_max - bounds_min) / float3(resolution - 1);
+ grid->transform().postScale(openvdb::math::Vec3<float>(scale_fac.x, scale_fac.y, scale_fac.z));
+ grid->transform().postTranslate(
+ openvdb::math::Vec3<float>(bounds_min.x, bounds_min.y, bounds_min.z));
+
+ Volume *volume = (Volume *)BKE_id_new_nomain(ID_VO, nullptr);
+ BKE_volume_init_grids(volume);
+
+ BKE_volume_grid_add_vdb(*volume, "density", std::move(grid));
+
+ GeometrySet r_geometry_set;
+ r_geometry_set.replace_volume(volume);
+ params.set_output("Volume", r_geometry_set);
+}
+
+#else
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ params.error_message_add(NodeWarningType::Error,
+ TIP_("Disabled, Blender was compiled without OpenVDB"));
+ params.set_default_remaining_outputs();
+}
+#endif /* WITH_OPENVDB */
+
+} // namespace blender::nodes::node_geo_volume_cube_cc
+
+void register_node_type_geo_volume_cube()
+{
+ namespace file_ns = blender::nodes::node_geo_volume_cube_cc;
+
+ static bNodeType ntype;
+
+ geo_node_type_base(&ntype, GEO_NODE_VOLUME_CUBE, "Volume Cube", NODE_CLASS_GEOMETRY);
+
+ ntype.declare = file_ns::node_declare;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
index e5827c24320..e1d1c67b8c8 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
@@ -41,7 +41,9 @@ static void node_declare(NodeDeclarationBuilder &b)
.make_available([](bNode &node) {
node_storage(node).resolution_mode = VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_AMOUNT;
});
- b.add_input<decl::Float>(N_("Threshold")).default_value(0.1f).min(0.0f);
+ b.add_input<decl::Float>(N_("Threshold"))
+ .default_value(0.1f)
+ .description(N_("Values larger than the threshold are inside the generated mesh"));
b.add_input<decl::Float>(N_("Adaptivity")).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
b.add_output<decl::Geometry>(N_("Mesh"));
}
@@ -151,6 +153,16 @@ static Mesh *create_mesh_from_volume(GeometrySet &geometry_set, GeoNodeExecParam
}
const bke::VolumeToMeshResolution resolution = get_resolution_param(params);
+
+ if (resolution.mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE &&
+ resolution.settings.voxel_size <= 0.0f) {
+ return nullptr;
+ }
+ if (resolution.mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_AMOUNT &&
+ resolution.settings.voxel_amount <= 0) {
+ return nullptr;
+ }
+
const Main *bmain = DEG_get_bmain(params.depsgraph());
BKE_volume_load(volume, bmain);
diff --git a/source/blender/nodes/shader/node_shader_tree.cc b/source/blender/nodes/shader/node_shader_tree.cc
index f107ec73c60..24558e4b32b 100644
--- a/source/blender/nodes/shader/node_shader_tree.cc
+++ b/source/blender/nodes/shader/node_shader_tree.cc
@@ -1007,6 +1007,7 @@ static void ntree_shader_pruned_unused(bNodeTree *ntree, bNode *output_node)
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->type == SH_NODE_OUTPUT_AOV) {
+ node->tmp_flag = 1;
nodeChainIterBackwards(ntree, node, ntree_branch_node_tag, nullptr, 0);
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc
index 94a6febe92e..d4413036555 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc
@@ -48,16 +48,36 @@ class MF_SeparateXYZ : public fn::MultiFunction {
void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
{
const VArray<float3> &vectors = params.readonly_single_input<float3>(0, "XYZ");
- MutableSpan<float> xs = params.uninitialized_single_output<float>(1, "X");
- MutableSpan<float> ys = params.uninitialized_single_output<float>(2, "Y");
- MutableSpan<float> zs = params.uninitialized_single_output<float>(3, "Z");
-
- for (int64_t i : mask) {
- float3 xyz = vectors[i];
- xs[i] = xyz.x;
- ys[i] = xyz.y;
- zs[i] = xyz.z;
+ MutableSpan<float> xs = params.uninitialized_single_output_if_required<float>(1, "X");
+ MutableSpan<float> ys = params.uninitialized_single_output_if_required<float>(2, "Y");
+ MutableSpan<float> zs = params.uninitialized_single_output_if_required<float>(3, "Z");
+
+ std::array<MutableSpan<float>, 3> outputs = {xs, ys, zs};
+ Vector<int> used_outputs;
+ if (!xs.is_empty()) {
+ used_outputs.append(0);
}
+ if (!ys.is_empty()) {
+ used_outputs.append(1);
+ }
+ if (!zs.is_empty()) {
+ used_outputs.append(2);
+ }
+
+ devirtualize_varray(vectors, [&](auto vectors) {
+ mask.to_best_mask_type([&](auto mask) {
+ const int used_outputs_num = used_outputs.size();
+ const int *used_outputs_data = used_outputs.data();
+
+ for (const int64_t i : mask) {
+ const float3 &vector = vectors[i];
+ for (const int out_i : IndexRange(used_outputs_num)) {
+ const int coordinate = used_outputs_data[out_i];
+ outputs[coordinate][i] = vector[coordinate];
+ }
+ }
+ });
+ });
}
};
diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c
index 903e293a962..03dc61af9a2 100644
--- a/source/blender/nodes/texture/node_texture_tree.c
+++ b/source/blender/nodes/texture/node_texture_tree.c
@@ -324,7 +324,6 @@ int ntreeTexExecTree(bNodeTree *ntree,
MTex *mtex)
{
TexCallData data;
- float *nor = target->nor;
int retval = TEX_INT;
bNodeThreadStack *nts = NULL;
bNodeTreeExec *exec = ntree->execdata;
@@ -356,14 +355,7 @@ int ntreeTexExecTree(bNodeTree *ntree,
ntreeExecThreadNodes(exec, nts, &data, thread);
ntreeReleaseThreadStack(nts);
- if (target->nor) {
- retval |= TEX_NOR;
- }
retval |= TEX_RGB;
- /* confusing stuff; the texture output node sets this to NULL to indicate no normal socket was
- * set however, the texture code checks this for other reasons
- * (namely, a normal is required for material). */
- target->nor = nor;
return retval;
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_output.c b/source/blender/nodes/texture/nodes/node_texture_output.c
index cf5e32cb486..b300ba9ef77 100644
--- a/source/blender/nodes/texture/nodes/node_texture_output.c
+++ b/source/blender/nodes/texture/nodes/node_texture_output.c
@@ -13,7 +13,6 @@
/* **************** COMPOSITE ******************** */
static bNodeSocketTemplate inputs[] = {
{SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, PROP_DIRECTION},
{-1, ""},
};
@@ -32,12 +31,7 @@ static void exec(void *data,
TexParams params;
params_from_cdata(&params, cdata);
- if (in[1] && in[1]->hasinput && !in[0]->hasinput) {
- tex_input_rgba(target->trgba, in[1], &params, cdata->thread);
- }
- else {
- tex_input_rgba(target->trgba, in[0], &params, cdata->thread);
- }
+ tex_input_rgba(target->trgba, in[0], &params, cdata->thread);
}
else {
/* 0 means don't care, so just use first */
@@ -49,15 +43,6 @@ static void exec(void *data,
target->tin = (target->trgba[0] + target->trgba[1] + target->trgba[2]) / 3.0f;
target->talpha = true;
-
- if (target->nor) {
- if (in[1] && in[1]->hasinput) {
- tex_input_vec(target->nor, in[1], &params, cdata->thread);
- }
- else {
- target->nor = NULL;
- }
- }
}
}
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_proc.c b/source/blender/nodes/texture/nodes/node_texture_proc.c
index fd7e6fdfc7f..d925c9f3554 100644
--- a/source/blender/nodes/texture/nodes/node_texture_proc.c
+++ b/source/blender/nodes/texture/nodes/node_texture_proc.c
@@ -14,10 +14,8 @@
* In this file: wrappers to use procedural textures as nodes
*/
-static bNodeSocketTemplate outputs_both[] = {
- {SOCK_RGBA, N_("Color"), 1.0f, 0.0f, 0.0f, 1.0f},
- {SOCK_VECTOR, N_("Normal"), 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, PROP_DIRECTION},
- {-1, ""}};
+static bNodeSocketTemplate outputs_both[] = {{SOCK_RGBA, N_("Color"), 1.0f, 0.0f, 0.0f, 1.0f},
+ {-1, ""}};
static bNodeSocketTemplate outputs_color_only[] = {{SOCK_RGBA, N_("Color")}, {-1, ""}};
/* Inputs common to all, #defined because nodes will need their own inputs too */
@@ -34,27 +32,15 @@ static void do_proc(float *result,
TexParams *p,
const float col1[4],
const float col2[4],
- char is_normal,
Tex *tex,
const short thread)
{
TexResult texres;
int textype;
- if (is_normal) {
- texres.nor = result;
- }
- else {
- texres.nor = NULL;
- }
-
textype = multitex_nodes(
tex, p->co, p->dxt, p->dyt, p->osatex, &texres, thread, 0, p->mtex, NULL);
- if (is_normal) {
- return;
- }
-
if (textype & TEX_RGB) {
copy_v4_v4(result, texres.trgba);
}
@@ -66,13 +52,8 @@ static void do_proc(float *result,
typedef void (*MapFn)(Tex *tex, bNodeStack **in, TexParams *p, const short thread);
-static void texfn(float *result,
- TexParams *p,
- bNode *node,
- bNodeStack **in,
- char is_normal,
- MapFn map_inputs,
- short thread)
+static void texfn(
+ float *result, TexParams *p, bNode *node, bNodeStack **in, MapFn map_inputs, short thread)
{
Tex tex = *((Tex *)(node->storage));
float col1[4], col2[4];
@@ -81,7 +62,7 @@ static void texfn(float *result,
map_inputs(&tex, in, p, thread);
- do_proc(result, p, col1, col2, is_normal, &tex, thread);
+ do_proc(result, p, col1, col2, &tex, thread);
}
static int count_outputs(bNode *node)
@@ -106,12 +87,7 @@ static int count_outputs(bNode *node)
static void name##_colorfn( \
float *result, TexParams *p, bNode *node, bNodeStack **in, short thread) \
{ \
- texfn(result, p, node, in, 0, &name##_map_inputs, thread); \
- } \
- static void name##_normalfn( \
- float *result, TexParams *p, bNode *node, bNodeStack **in, short thread) \
- { \
- texfn(result, p, node, in, 1, &name##_map_inputs, thread); \
+ texfn(result, p, node, in, &name##_map_inputs, thread); \
} \
static void name##_exec(void *data, \
int UNUSED(thread), \
@@ -124,9 +100,6 @@ static int count_outputs(bNode *node)
if (outs >= 1) { \
tex_output(node, execdata, in, out[0], &name##_colorfn, data); \
} \
- if (outs >= 2) { \
- tex_output(node, execdata, in, out[1], &name##_normalfn, data); \
- } \
}
/* --- VORONOI -- */
diff --git a/source/blender/nodes/texture/nodes/node_texture_texture.c b/source/blender/nodes/texture/nodes/node_texture_texture.c
index 2d2b4e06665..79cd8bbb1df 100644
--- a/source/blender/nodes/texture/nodes/node_texture_texture.c
+++ b/source/blender/nodes/texture/nodes/node_texture_texture.c
@@ -45,13 +45,11 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
else if (nodetex) {
TexResult texres;
int textype;
- float nor[] = {0, 0, 0};
float col1[4], col2[4];
tex_input_rgba(col1, in[0], p, thread);
tex_input_rgba(col2, in[1], p, thread);
- texres.nor = nor;
textype = multitex_nodes(nodetex, co, dxt, dyt, p->osatex, &texres, thread, 0, p->mtex, NULL);
if (textype & TEX_RGB) {
diff --git a/source/blender/render/RE_texture.h b/source/blender/render/RE_texture.h
index be50eacd7bf..a4e30c917d5 100644
--- a/source/blender/render/RE_texture.h
+++ b/source/blender/render/RE_texture.h
@@ -44,8 +44,6 @@ bool RE_texture_evaluate(const struct MTex *mtex,
* \param fact: Texture strength.
* \param facg: Button strength value.
*/
-void texture_rgb_blend(
- float in[3], const float tex[3], const float out[3], float fact, float facg, int blendtype);
float texture_value_blend(float tex, float out, float fact, float facg, int blendtype);
void RE_texture_rng_init(void);
@@ -89,7 +87,6 @@ typedef struct TexResult {
float trgba[4];
/* Is actually a boolean: When true -> use alpha, false -> set alpha to 1.0. */
int talpha;
- float *nor;
} TexResult;
/* This one uses nodes. */
diff --git a/source/blender/render/intern/render_result.c b/source/blender/render/intern/render_result.c
index 9f4aa642773..9992d1a507f 100644
--- a/source/blender/render/intern/render_result.c
+++ b/source/blender/render/intern/render_result.c
@@ -825,7 +825,7 @@ void render_result_merge(RenderResult *rr, RenderResult *rrpart)
if (rpass->rect == NULL || rpassp->rect == NULL) {
continue;
}
- /* Renderresult have all passes, renderpart only the active view's passes. */
+ /* Render-result have all passes, render-part only the active view's passes. */
if (!STREQ(rpassp->fullname, rpass->fullname)) {
continue;
}
diff --git a/source/blender/render/intern/texture_image.c b/source/blender/render/intern/texture_image.c
index 3b1eb293a3a..7da9e7c3d58 100644
--- a/source/blender/render/intern/texture_image.c
+++ b/source/blender/render/intern/texture_image.c
@@ -88,14 +88,13 @@ int imagewrap(Tex *tex,
struct ImagePool *pool,
const bool skip_load_image)
{
- float fx, fy, val1, val2, val3;
+ float fx, fy;
int x, y, retval;
int xi, yi; /* original values */
texres->tin = texres->trgba[3] = texres->trgba[0] = texres->trgba[1] = texres->trgba[2] = 0.0f;
- /* we need to set retval OK, otherwise texture code generates normals itself... */
- retval = texres->nor ? (TEX_RGB | TEX_NOR) : TEX_RGB;
+ retval = TEX_RGB;
/* quick tests */
if (ima == NULL) {
@@ -256,47 +255,6 @@ int imagewrap(Tex *tex,
ibuf_get_color(texres->trgba, ibuf, x, y);
}
- if (texres->nor) {
- if (tex->imaflag & TEX_NORMALMAP) {
- /* Normal from color:
- * The invert of the red channel is to make
- * the normal map compliant with the outside world.
- * It needs to be done because in Blender
- * the normal used in the renderer points inward. It is generated
- * this way in calc_vertexnormals(). Should this ever change
- * this negate must be removed. */
- texres->nor[0] = -2.0f * (texres->trgba[0] - 0.5f);
- texres->nor[1] = 2.0f * (texres->trgba[1] - 0.5f);
- texres->nor[2] = 2.0f * (texres->trgba[2] - 0.5f);
- }
- else {
- /* bump: take three samples */
- val1 = texres->trgba[0] + texres->trgba[1] + texres->trgba[2];
-
- if (x < ibuf->x - 1) {
- float col[4];
- ibuf_get_color(col, ibuf, x + 1, y);
- val2 = (col[0] + col[1] + col[2]);
- }
- else {
- val2 = val1;
- }
-
- if (y < ibuf->y - 1) {
- float col[4];
- ibuf_get_color(col, ibuf, x, y + 1);
- val3 = (col[0] + col[1] + col[2]);
- }
- else {
- val3 = val1;
- }
-
- /* do not mix up x and y here! */
- texres->nor[0] = (val1 - val2);
- texres->nor[1] = (val1 - val3);
- }
- }
-
if (texres->talpha) {
texres->tin = texres->trgba[3];
}
@@ -989,7 +947,7 @@ static int imagewraposa_aniso(Tex *tex,
{
TexResult texr;
float fx, fy, minx, maxx, miny, maxy;
- float maxd, val1, val2, val3;
+ float maxd;
int curmap, retval, intpol, extflag = 0;
afdata_t AFD;
@@ -1008,8 +966,7 @@ static int imagewraposa_aniso(Tex *tex,
texres->tin = texres->trgba[3] = texres->trgba[0] = texres->trgba[1] = texres->trgba[2] = 0.0f;
- /* we need to set retval OK, otherwise texture code generates normals itself... */
- retval = texres->nor ? (TEX_RGB | TEX_NOR) : TEX_RGB;
+ retval = TEX_RGB;
/* quick tests */
if (ibuf == NULL && ima == NULL) {
@@ -1040,7 +997,7 @@ static int imagewraposa_aniso(Tex *tex,
if (ima) {
if ((tex->imaflag & TEX_USEALPHA) && (ima->alpha_mode != IMA_ALPHA_IGNORE)) {
if ((tex->imaflag & TEX_CALCALPHA) == 0) {
- texres->talpha = 1;
+ texres->talpha = true;
}
}
}
@@ -1301,48 +1258,17 @@ static int imagewraposa_aniso(Tex *tex,
}
/* filter functions take care of interpolation themselves, no need to modify dxt/dyt here */
-
- if (texres->nor && ((tex->imaflag & TEX_NORMALMAP) == 0)) {
- /* color & normal */
- filterfunc(texres, curibuf, fx, fy, &AFD);
- val1 = texres->trgba[0] + texres->trgba[1] + texres->trgba[2];
- filterfunc(&texr, curibuf, fx + dxt[0], fy + dxt[1], &AFD);
- val2 = texr.trgba[0] + texr.trgba[1] + texr.trgba[2];
- filterfunc(&texr, curibuf, fx + dyt[0], fy + dyt[1], &AFD);
- val3 = texr.trgba[0] + texr.trgba[1] + texr.trgba[2];
- /* don't switch x or y! */
- texres->nor[0] = val1 - val2;
- texres->nor[1] = val1 - val3;
- if (previbuf != curibuf) { /* interpolate */
- filterfunc(&texr, previbuf, fx, fy, &AFD);
- /* rgb */
- texres->trgba[0] += levf * (texr.trgba[0] - texres->trgba[0]);
- texres->trgba[1] += levf * (texr.trgba[1] - texres->trgba[1]);
- texres->trgba[2] += levf * (texr.trgba[2] - texres->trgba[2]);
- texres->trgba[3] += levf * (texr.trgba[3] - texres->trgba[3]);
- /* normal */
- val1 += levf * ((texr.trgba[0] + texr.trgba[1] + texr.trgba[2]) - val1);
- filterfunc(&texr, previbuf, fx + dxt[0], fy + dxt[1], &AFD);
- val2 += levf * ((texr.trgba[0] + texr.trgba[1] + texr.trgba[2]) - val2);
- filterfunc(&texr, previbuf, fx + dyt[0], fy + dyt[1], &AFD);
- val3 += levf * ((texr.trgba[0] + texr.trgba[1] + texr.trgba[2]) - val3);
- texres->nor[0] = val1 - val2; /* vals have been interpolated above! */
- texres->nor[1] = val1 - val3;
- }
+ filterfunc(texres, curibuf, fx, fy, &AFD);
+ if (previbuf != curibuf) { /* interpolate */
+ filterfunc(&texr, previbuf, fx, fy, &AFD);
+ texres->trgba[0] += levf * (texr.trgba[0] - texres->trgba[0]);
+ texres->trgba[1] += levf * (texr.trgba[1] - texres->trgba[1]);
+ texres->trgba[2] += levf * (texr.trgba[2] - texres->trgba[2]);
+ texres->trgba[3] += levf * (texr.trgba[3] - texres->trgba[3]);
}
- else { /* color */
- filterfunc(texres, curibuf, fx, fy, &AFD);
- if (previbuf != curibuf) { /* interpolate */
- filterfunc(&texr, previbuf, fx, fy, &AFD);
- texres->trgba[0] += levf * (texr.trgba[0] - texres->trgba[0]);
- texres->trgba[1] += levf * (texr.trgba[1] - texres->trgba[1]);
- texres->trgba[2] += levf * (texr.trgba[2] - texres->trgba[2]);
- texres->trgba[3] += levf * (texr.trgba[3] - texres->trgba[3]);
- }
- if (tex->texfilter != TXF_EWA) {
- alpha_clip_aniso(ibuf, fx - minx, fy - miny, fx + minx, fy + miny, extflag, texres);
- }
+ if (tex->texfilter != TXF_EWA) {
+ alpha_clip_aniso(ibuf, fx - minx, fy - miny, fx + minx, fy + miny, extflag, texres);
}
}
else { /* no mipmap */
@@ -1372,23 +1298,9 @@ static int imagewraposa_aniso(Tex *tex,
AFD.dusc = 1.0f / ff;
AFD.dvsc = ff / (float)ibuf->y;
}
- if (texres->nor && ((tex->imaflag & TEX_NORMALMAP) == 0)) {
- /* color & normal */
- filterfunc(texres, ibuf, fx, fy, &AFD);
- val1 = texres->trgba[0] + texres->trgba[1] + texres->trgba[2];
- filterfunc(&texr, ibuf, fx + dxt[0], fy + dxt[1], &AFD);
- val2 = texr.trgba[0] + texr.trgba[1] + texr.trgba[2];
- filterfunc(&texr, ibuf, fx + dyt[0], fy + dyt[1], &AFD);
- val3 = texr.trgba[0] + texr.trgba[1] + texr.trgba[2];
- /* don't switch x or y! */
- texres->nor[0] = val1 - val2;
- texres->nor[1] = val1 - val3;
- }
- else {
- filterfunc(texres, ibuf, fx, fy, &AFD);
- if (tex->texfilter != TXF_EWA) {
- alpha_clip_aniso(ibuf, fx - minx, fy - miny, fx + minx, fy + miny, extflag, texres);
- }
+ filterfunc(texres, ibuf, fx, fy, &AFD);
+ if (tex->texfilter != TXF_EWA) {
+ alpha_clip_aniso(ibuf, fx - minx, fy - miny, fx + minx, fy + miny, extflag, texres);
}
}
@@ -1403,18 +1315,6 @@ static int imagewraposa_aniso(Tex *tex,
texres->trgba[3] = 1.0f - texres->trgba[3];
}
- if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) { /* normal from color */
- /* The invert of the red channel is to make
- * the normal map compliant with the outside world.
- * It needs to be done because in Blender
- * the normal used in the renderer points inward. It is generated
- * this way in calc_vertexnormals(). Should this ever change
- * this negate must be removed. */
- texres->nor[0] = -2.0f * (texres->trgba[0] - 0.5f);
- texres->nor[1] = 2.0f * (texres->trgba[1] - 0.5f);
- texres->nor[2] = 2.0f * (texres->trgba[2] - 0.5f);
- }
-
/* de-premul, this is being pre-multiplied in shade_input_do_shade()
* TXF: this currently does not (yet?) work properly, destroys edge AA in clip/checker mode,
* so for now commented out also disabled in imagewraposa()
@@ -1451,7 +1351,7 @@ int imagewraposa(Tex *tex,
{
TexResult texr;
float fx, fy, minx, maxx, miny, maxy, dx, dy, dxt[2], dyt[2];
- float maxd, pixsize, val1, val2, val3;
+ float maxd, pixsize;
int curmap, retval, imaprepeat, imapextend;
/* TXF: since dxt/dyt might be modified here and since they might be needed after imagewraposa()
@@ -1466,8 +1366,7 @@ int imagewraposa(Tex *tex,
texres->tin = texres->trgba[3] = texres->trgba[0] = texres->trgba[1] = texres->trgba[2] = 0.0f;
- /* we need to set retval OK, otherwise texture code generates normals itself... */
- retval = texres->nor ? (TEX_RGB | TEX_NOR) : TEX_RGB;
+ retval = TEX_RGB;
/* quick tests */
if (ibuf == NULL && ima == NULL) {
@@ -1762,118 +1661,30 @@ int imagewraposa(Tex *tex,
}
}
- if (texres->nor && (tex->imaflag & TEX_NORMALMAP) == 0) {
- /* a bit extra filter */
- // minx*= 1.35f;
- // miny*= 1.35f;
-
- boxsample(
- curibuf, fx - minx, fy - miny, fx + minx, fy + miny, texres, imaprepeat, imapextend);
- val1 = texres->trgba[0] + texres->trgba[1] + texres->trgba[2];
- boxsample(curibuf,
- fx - minx + dxt[0],
- fy - miny + dxt[1],
- fx + minx + dxt[0],
- fy + miny + dxt[1],
- &texr,
- imaprepeat,
- imapextend);
- val2 = texr.trgba[0] + texr.trgba[1] + texr.trgba[2];
- boxsample(curibuf,
- fx - minx + dyt[0],
- fy - miny + dyt[1],
- fx + minx + dyt[0],
- fy + miny + dyt[1],
- &texr,
- imaprepeat,
- imapextend);
- val3 = texr.trgba[0] + texr.trgba[1] + texr.trgba[2];
-
- /* don't switch x or y! */
- texres->nor[0] = (val1 - val2);
- texres->nor[1] = (val1 - val3);
-
- if (previbuf != curibuf) { /* interpolate */
-
- boxsample(
- previbuf, fx - minx, fy - miny, fx + minx, fy + miny, &texr, imaprepeat, imapextend);
-
- /* calc rgb */
- dx = 2.0f * (pixsize - maxd) / pixsize;
- if (dx >= 1.0f) {
- texres->trgba[3] = texr.trgba[3];
- texres->trgba[2] = texr.trgba[2];
- texres->trgba[1] = texr.trgba[1];
- texres->trgba[0] = texr.trgba[0];
- }
- else {
- dy = 1.0f - dx;
- texres->trgba[2] = dy * texres->trgba[2] + dx * texr.trgba[2];
- texres->trgba[1] = dy * texres->trgba[1] + dx * texr.trgba[1];
- texres->trgba[0] = dy * texres->trgba[0] + dx * texr.trgba[0];
- texres->trgba[3] = dy * texres->trgba[3] + dx * texr.trgba[3];
- }
-
- val1 = dy * val1 + dx * (texr.trgba[0] + texr.trgba[1] + texr.trgba[2]);
- boxsample(previbuf,
- fx - minx + dxt[0],
- fy - miny + dxt[1],
- fx + minx + dxt[0],
- fy + miny + dxt[1],
- &texr,
- imaprepeat,
- imapextend);
- val2 = dy * val2 + dx * (texr.trgba[0] + texr.trgba[1] + texr.trgba[2]);
- boxsample(previbuf,
- fx - minx + dyt[0],
- fy - miny + dyt[1],
- fx + minx + dyt[0],
- fy + miny + dyt[1],
- &texr,
- imaprepeat,
- imapextend);
- val3 = dy * val3 + dx * (texr.trgba[0] + texr.trgba[1] + texr.trgba[2]);
-
- texres->nor[0] = (val1 - val2); /* vals have been interpolated above! */
- texres->nor[1] = (val1 - val3);
-
- if (dx < 1.0f) {
- dy = 1.0f - dx;
- texres->trgba[2] = dy * texres->trgba[2] + dx * texr.trgba[2];
- texres->trgba[1] = dy * texres->trgba[1] + dx * texr.trgba[1];
- texres->trgba[0] = dy * texres->trgba[0] + dx * texr.trgba[0];
- texres->trgba[3] = dy * texres->trgba[3] + dx * texr.trgba[3];
- }
- }
- texres->nor[0] *= bumpscale;
- texres->nor[1] *= bumpscale;
- }
- else {
- maxx = fx + minx;
- minx = fx - minx;
- maxy = fy + miny;
- miny = fy - miny;
+ maxx = fx + minx;
+ minx = fx - minx;
+ maxy = fy + miny;
+ miny = fy - miny;
- boxsample(curibuf, minx, miny, maxx, maxy, texres, imaprepeat, imapextend);
+ boxsample(curibuf, minx, miny, maxx, maxy, texres, imaprepeat, imapextend);
- if (previbuf != curibuf) { /* interpolate */
- boxsample(previbuf, minx, miny, maxx, maxy, &texr, imaprepeat, imapextend);
+ if (previbuf != curibuf) { /* interpolate */
+ boxsample(previbuf, minx, miny, maxx, maxy, &texr, imaprepeat, imapextend);
- fx = 2.0f * (pixsize - maxd) / pixsize;
+ fx = 2.0f * (pixsize - maxd) / pixsize;
- if (fx >= 1.0f) {
- texres->trgba[3] = texr.trgba[3];
- texres->trgba[2] = texr.trgba[2];
- texres->trgba[1] = texr.trgba[1];
- texres->trgba[0] = texr.trgba[0];
- }
- else {
- fy = 1.0f - fx;
- texres->trgba[2] = fy * texres->trgba[2] + fx * texr.trgba[2];
- texres->trgba[1] = fy * texres->trgba[1] + fx * texr.trgba[1];
- texres->trgba[0] = fy * texres->trgba[0] + fx * texr.trgba[0];
- texres->trgba[3] = fy * texres->trgba[3] + fx * texr.trgba[3];
- }
+ if (fx >= 1.0f) {
+ texres->trgba[3] = texr.trgba[3];
+ texres->trgba[2] = texr.trgba[2];
+ texres->trgba[1] = texr.trgba[1];
+ texres->trgba[0] = texr.trgba[0];
+ }
+ else {
+ fy = 1.0f - fx;
+ texres->trgba[2] = fy * texres->trgba[2] + fx * texr.trgba[2];
+ texres->trgba[1] = fy * texres->trgba[1] + fx * texr.trgba[1];
+ texres->trgba[0] = fy * texres->trgba[0] + fx * texr.trgba[0];
+ texres->trgba[3] = fy * texres->trgba[3] + fx * texr.trgba[3];
}
}
}
@@ -1889,35 +1700,7 @@ int imagewraposa(Tex *tex,
}
}
- if (texres->nor && (tex->imaflag & TEX_NORMALMAP) == 0) {
- boxsample(ibuf, fx - minx, fy - miny, fx + minx, fy + miny, texres, imaprepeat, imapextend);
- val1 = texres->trgba[0] + texres->trgba[1] + texres->trgba[2];
- boxsample(ibuf,
- fx - minx + dxt[0],
- fy - miny + dxt[1],
- fx + minx + dxt[0],
- fy + miny + dxt[1],
- &texr,
- imaprepeat,
- imapextend);
- val2 = texr.trgba[0] + texr.trgba[1] + texr.trgba[2];
- boxsample(ibuf,
- fx - minx + dyt[0],
- fy - miny + dyt[1],
- fx + minx + dyt[0],
- fy + miny + dyt[1],
- &texr,
- imaprepeat,
- imapextend);
- val3 = texr.trgba[0] + texr.trgba[1] + texr.trgba[2];
-
- /* don't switch x or y! */
- texres->nor[0] = (val1 - val2);
- texres->nor[1] = (val1 - val3);
- }
- else {
- boxsample(ibuf, fx - minx, fy - miny, fx + minx, fy + miny, texres, imaprepeat, imapextend);
- }
+ boxsample(ibuf, fx - minx, fy - miny, fx + minx, fy + miny, texres, imaprepeat, imapextend);
}
if (tex->imaflag & TEX_CALCALPHA) {
@@ -1932,17 +1715,6 @@ int imagewraposa(Tex *tex,
texres->trgba[3] = 1.0f - texres->trgba[3];
}
- if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) {
- /* Normal from color:
- * The invert of the red channel is to make the normal map compliant with the outside world.
- * It needs to be done because in Blender the normal used in the renderer points inward.
- * It is generated this way in #calc_vertexnormals().
- * Should this ever change this negate must be removed. */
- texres->nor[0] = -2.0f * (texres->trgba[0] - 0.5f);
- texres->nor[1] = 2.0f * (texres->trgba[1] - 0.5f);
- texres->nor[2] = 2.0f * (texres->trgba[2] - 0.5f);
- }
-
/* de-premul, this is being pre-multiplied in shade_input_do_shade() */
/* do not de-premul for generated alpha, it is already in straight */
if (texres->trgba[3] != 1.0f && texres->trgba[3] > 1e-4f && !(tex->imaflag & TEX_CALCALPHA)) {
diff --git a/source/blender/render/intern/texture_procedural.c b/source/blender/render/intern/texture_procedural.c
index ce58993b7cf..37605236738 100644
--- a/source/blender/render/intern/texture_procedural.c
+++ b/source/blender/render/intern/texture_procedural.c
@@ -61,34 +61,6 @@ void RE_texture_rng_exit(void)
/* ------------------------------------------------------------------------- */
-/* This allows color-banded textures to control normals as well. */
-static void tex_normal_derivate(const Tex *tex, TexResult *texres)
-{
- if (tex->flag & TEX_COLORBAND) {
- float col[4];
- if (BKE_colorband_evaluate(tex->coba, texres->tin, col)) {
- float fac0, fac1, fac2, fac3;
-
- fac0 = (col[0] + col[1] + col[2]);
- BKE_colorband_evaluate(tex->coba, texres->nor[0], col);
- fac1 = (col[0] + col[1] + col[2]);
- BKE_colorband_evaluate(tex->coba, texres->nor[1], col);
- fac2 = (col[0] + col[1] + col[2]);
- BKE_colorband_evaluate(tex->coba, texres->nor[2], col);
- fac3 = (col[0] + col[1] + col[2]);
-
- texres->nor[0] = (fac0 - fac1) / 3.0f;
- texres->nor[1] = (fac0 - fac2) / 3.0f;
- texres->nor[2] = (fac0 - fac3) / 3.0f;
-
- return;
- }
- }
- texres->nor[0] = texres->tin - texres->nor[0];
- texres->nor[1] = texres->tin - texres->nor[1];
- texres->nor[2] = texres->tin - texres->nor[2];
-}
-
static int blend(const Tex *tex, const float texvec[3], TexResult *texres)
{
float x, y, t;
@@ -165,37 +137,7 @@ static int clouds(const Tex *tex, const float texvec[3], TexResult *texres)
(tex->noisetype != TEX_NOISESOFT),
tex->noisebasis);
- if (texres->nor != NULL) {
- /* calculate bumpnormal */
- texres->nor[0] = BLI_noise_generic_turbulence(tex->noisesize,
- texvec[0] + tex->nabla,
- texvec[1],
- texvec[2],
- tex->noisedepth,
- (tex->noisetype != TEX_NOISESOFT),
- tex->noisebasis);
- texres->nor[1] = BLI_noise_generic_turbulence(tex->noisesize,
- texvec[0],
- texvec[1] + tex->nabla,
- texvec[2],
- tex->noisedepth,
- (tex->noisetype != TEX_NOISESOFT),
- tex->noisebasis);
- texres->nor[2] = BLI_noise_generic_turbulence(tex->noisesize,
- texvec[0],
- texvec[1],
- texvec[2] + tex->nabla,
- tex->noisedepth,
- (tex->noisetype != TEX_NOISESOFT),
- tex->noisebasis);
-
- tex_normal_derivate(tex, texres);
- rv |= TEX_NOR;
- }
-
if (tex->stype == TEX_COLOR) {
- /* in this case, int. value should really be computed from color,
- * and bumpnormal from that, would be too slow, looks ok as is */
texres->trgba[0] = texres->tin;
texres->trgba[1] = BLI_noise_generic_turbulence(tex->noisesize,
texvec[1],
@@ -298,15 +240,6 @@ static int wood(const Tex *tex, const float texvec[3], TexResult *texres)
int rv = TEX_INT;
texres->tin = wood_int(tex, texvec[0], texvec[1], texvec[2]);
- if (texres->nor != NULL) {
- /* calculate bumpnormal */
- texres->nor[0] = wood_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]);
- texres->nor[1] = wood_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]);
- texres->nor[2] = wood_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla);
-
- tex_normal_derivate(tex, texres);
- rv |= TEX_NOR;
- }
BRICONT;
@@ -358,17 +291,6 @@ static int marble(const Tex *tex, const float texvec[3], TexResult *texres)
texres->tin = marble_int(tex, texvec[0], texvec[1], texvec[2]);
- if (texres->nor != NULL) {
- /* calculate bumpnormal */
- texres->nor[0] = marble_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]);
- texres->nor[1] = marble_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]);
- texres->nor[2] = marble_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla);
-
- tex_normal_derivate(tex, texres);
-
- rv |= TEX_NOR;
- }
-
BRICONT;
return rv;
@@ -454,7 +376,7 @@ static int magic(const Tex *tex, const float texvec[3], TexResult *texres)
/* newnoise: stucci also modified to use different noisebasis */
static int stucci(const Tex *tex, const float texvec[3], TexResult *texres)
{
- float nor[3], b2, ofs;
+ float b2, ofs;
int retval = TEX_INT;
b2 = BLI_noise_generic_noise(tex->noisesize,
@@ -469,40 +391,13 @@ static int stucci(const Tex *tex, const float texvec[3], TexResult *texres)
if (tex->stype) {
ofs *= (b2 * b2);
}
- nor[0] = BLI_noise_generic_noise(tex->noisesize,
- texvec[0] + ofs,
- texvec[1],
- texvec[2],
- (tex->noisetype != TEX_NOISESOFT),
- tex->noisebasis);
- nor[1] = BLI_noise_generic_noise(tex->noisesize,
- texvec[0],
- texvec[1] + ofs,
- texvec[2],
- (tex->noisetype != TEX_NOISESOFT),
- tex->noisebasis);
- nor[2] = BLI_noise_generic_noise(tex->noisesize,
- texvec[0],
- texvec[1],
- texvec[2] + ofs,
- (tex->noisetype != TEX_NOISESOFT),
- tex->noisebasis);
-
- texres->tin = nor[2];
-
- if (texres->nor) {
-
- copy_v3_v3(texres->nor, nor);
- tex_normal_derivate(tex, texres);
-
- if (tex->stype == TEX_WALLOUT) {
- texres->nor[0] = -texres->nor[0];
- texres->nor[1] = -texres->nor[1];
- texres->nor[2] = -texres->nor[2];
- }
- retval |= TEX_NOR;
- }
+ texres->tin = BLI_noise_generic_noise(tex->noisesize,
+ texvec[0],
+ texvec[1],
+ texvec[2] + ofs,
+ (tex->noisetype != TEX_NOISESOFT),
+ tex->noisebasis);
if (tex->stype == TEX_WALLOUT) {
texres->tin = 1.0f - texres->tin;
@@ -538,36 +433,6 @@ static int mg_mFractalOrfBmTex(const Tex *tex, const float texvec[3], TexResult
tex->mg_octaves,
tex->noisebasis);
- if (texres->nor != NULL) {
- float ofs = tex->nabla / tex->noisesize; /* also scaling of texvec */
-
- /* calculate bumpnormal */
- texres->nor[0] = tex->ns_outscale * mgravefunc(texvec[0] + ofs,
- texvec[1],
- texvec[2],
- tex->mg_H,
- tex->mg_lacunarity,
- tex->mg_octaves,
- tex->noisebasis);
- texres->nor[1] = tex->ns_outscale * mgravefunc(texvec[0],
- texvec[1] + ofs,
- texvec[2],
- tex->mg_H,
- tex->mg_lacunarity,
- tex->mg_octaves,
- tex->noisebasis);
- texres->nor[2] = tex->ns_outscale * mgravefunc(texvec[0],
- texvec[1],
- texvec[2] + ofs,
- tex->mg_H,
- tex->mg_lacunarity,
- tex->mg_octaves,
- tex->noisebasis);
-
- tex_normal_derivate(tex, texres);
- rv |= TEX_NOR;
- }
-
BRICONT;
return rv;
@@ -595,42 +460,6 @@ static int mg_ridgedOrHybridMFTex(const Tex *tex, const float texvec[3], TexResu
tex->mg_gain,
tex->noisebasis);
- if (texres->nor != NULL) {
- float ofs = tex->nabla / tex->noisesize; /* also scaling of texvec */
-
- /* calculate bumpnormal */
- texres->nor[0] = tex->ns_outscale * mgravefunc(texvec[0] + ofs,
- texvec[1],
- texvec[2],
- tex->mg_H,
- tex->mg_lacunarity,
- tex->mg_octaves,
- tex->mg_offset,
- tex->mg_gain,
- tex->noisebasis);
- texres->nor[1] = tex->ns_outscale * mgravefunc(texvec[0],
- texvec[1] + ofs,
- texvec[2],
- tex->mg_H,
- tex->mg_lacunarity,
- tex->mg_octaves,
- tex->mg_offset,
- tex->mg_gain,
- tex->noisebasis);
- texres->nor[2] = tex->ns_outscale * mgravefunc(texvec[0],
- texvec[1],
- texvec[2] + ofs,
- tex->mg_H,
- tex->mg_lacunarity,
- tex->mg_octaves,
- tex->mg_offset,
- tex->mg_gain,
- tex->noisebasis);
-
- tex_normal_derivate(tex, texres);
- rv |= TEX_NOR;
- }
-
BRICONT;
return rv;
@@ -649,39 +478,6 @@ static int mg_HTerrainTex(const Tex *tex, const float texvec[3], TexResult *texr
tex->mg_offset,
tex->noisebasis);
- if (texres->nor != NULL) {
- float ofs = tex->nabla / tex->noisesize; /* also scaling of texvec */
-
- /* calculate bumpnormal */
- texres->nor[0] = tex->ns_outscale * BLI_noise_mg_hetero_terrain(texvec[0] + ofs,
- texvec[1],
- texvec[2],
- tex->mg_H,
- tex->mg_lacunarity,
- tex->mg_octaves,
- tex->mg_offset,
- tex->noisebasis);
- texres->nor[1] = tex->ns_outscale * BLI_noise_mg_hetero_terrain(texvec[0],
- texvec[1] + ofs,
- texvec[2],
- tex->mg_H,
- tex->mg_lacunarity,
- tex->mg_octaves,
- tex->mg_offset,
- tex->noisebasis);
- texres->nor[2] = tex->ns_outscale * BLI_noise_mg_hetero_terrain(texvec[0],
- texvec[1],
- texvec[2] + ofs,
- tex->mg_H,
- tex->mg_lacunarity,
- tex->mg_octaves,
- tex->mg_offset,
- tex->noisebasis);
-
- tex_normal_derivate(tex, texres);
- rv |= TEX_NOR;
- }
-
BRICONT;
return rv;
@@ -694,33 +490,6 @@ static int mg_distNoiseTex(const Tex *tex, const float texvec[3], TexResult *tex
texres->tin = BLI_noise_mg_variable_lacunarity(
texvec[0], texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2);
- if (texres->nor != NULL) {
- float ofs = tex->nabla / tex->noisesize; /* also scaling of texvec */
-
- /* calculate bumpnormal */
- texres->nor[0] = BLI_noise_mg_variable_lacunarity(texvec[0] + ofs,
- texvec[1],
- texvec[2],
- tex->dist_amount,
- tex->noisebasis,
- tex->noisebasis2);
- texres->nor[1] = BLI_noise_mg_variable_lacunarity(texvec[0],
- texvec[1] + ofs,
- texvec[2],
- tex->dist_amount,
- tex->noisebasis,
- tex->noisebasis2);
- texres->nor[2] = BLI_noise_mg_variable_lacunarity(texvec[0],
- texvec[1],
- texvec[2] + ofs,
- tex->dist_amount,
- tex->noisebasis,
- tex->noisebasis2);
-
- tex_normal_derivate(tex, texres);
- rv |= TEX_NOR;
- }
-
BRICONT;
return rv;
@@ -788,21 +557,6 @@ static int voronoiTex(const Tex *tex, const float texvec[3], TexResult *texres)
}
}
- if (texres->nor != NULL) {
- float ofs = tex->nabla / tex->noisesize; /* also scaling of texvec */
-
- /* calculate bumpnormal */
- BLI_noise_voronoi(texvec[0] + ofs, texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm);
- texres->nor[0] = sc * fabsf(dot_v4v4(&tex->vn_w1, da));
- BLI_noise_voronoi(texvec[0], texvec[1] + ofs, texvec[2], da, pa, tex->vn_mexp, tex->vn_distm);
- texres->nor[1] = sc * fabsf(dot_v4v4(&tex->vn_w1, da));
- BLI_noise_voronoi(texvec[0], texvec[1], texvec[2] + ofs, da, pa, tex->vn_mexp, tex->vn_distm);
- texres->nor[2] = sc * fabsf(dot_v4v4(&tex->vn_w1, da));
-
- tex_normal_derivate(tex, texres);
- rv |= TEX_NOR;
- }
-
if (tex->vn_coltype) {
BRICONTRGB;
texres->trgba[3] = 1.0;
@@ -1148,7 +902,7 @@ static int multitex(Tex *tex,
const bool use_nodes)
{
float tmpvec[3];
- int retval = 0; /* return value, int:0, col:1, nor:2, everything:3 */
+ int retval = 0; /* return value, TEX_INT or TEX_RGB. */
texres->talpha = false; /* is set when image texture returns alpha (considered premul) */
@@ -1283,14 +1037,14 @@ static int multitex_nodes_intern(Tex *tex,
}
if (tex->type == TEX_IMAGE) {
- int rgbnor;
+ int retval;
if (mtex) {
float texvec_l[3];
copy_v3_v3(texvec_l, texvec);
/* we have mtex, use it for 2d mapping images only */
do_2d_mapping(mtex, texvec_l, NULL, dxt, dyt);
- rgbnor = multitex(tex,
+ retval = multitex(tex,
texvec_l,
dxt,
dyt,
@@ -1307,7 +1061,7 @@ static int multitex_nodes_intern(Tex *tex,
ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool);
/* don't linearize float buffers, assumed to be linear */
- if (ibuf != NULL && ibuf->rect_float == NULL && (rgbnor & TEX_RGB) && scene_color_manage) {
+ if (ibuf != NULL && ibuf->rect_float == NULL && (retval & TEX_RGB) && scene_color_manage) {
IMB_colormanagement_colorspace_to_scene_linear_v3(texres->trgba, ibuf->rect_colorspace);
}
@@ -1335,7 +1089,7 @@ static int multitex_nodes_intern(Tex *tex,
}
do_2d_mapping(&localmtex, texvec_l, NULL, dxt_l, dyt_l);
- rgbnor = multitex(tex,
+ retval = multitex(tex,
texvec_l,
dxt_l,
dyt_l,
@@ -1352,7 +1106,7 @@ static int multitex_nodes_intern(Tex *tex,
ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool);
/* don't linearize float buffers, assumed to be linear */
- if (ibuf != NULL && ibuf->rect_float == NULL && (rgbnor & TEX_RGB) && scene_color_manage) {
+ if (ibuf != NULL && ibuf->rect_float == NULL && (retval & TEX_RGB) && scene_color_manage) {
IMB_colormanagement_colorspace_to_scene_linear_v3(texres->trgba, ibuf->rect_colorspace);
}
@@ -1360,7 +1114,7 @@ static int multitex_nodes_intern(Tex *tex,
}
}
- return rgbnor;
+ return retval;
}
return multitex(tex,
@@ -1456,145 +1210,6 @@ int multitex_ext_safe(Tex *tex,
/* ------------------------------------------------------------------------- */
-void texture_rgb_blend(
- float in[3], const float tex[3], const float out[3], float fact, float facg, int blendtype)
-{
- float facm;
-
- switch (blendtype) {
- case MTEX_BLEND:
- fact *= facg;
- facm = 1.0f - fact;
-
- in[0] = (fact * tex[0] + facm * out[0]);
- in[1] = (fact * tex[1] + facm * out[1]);
- in[2] = (fact * tex[2] + facm * out[2]);
- break;
-
- case MTEX_MUL:
- fact *= facg;
- facm = 1.0f - fact;
- in[0] = (facm + fact * tex[0]) * out[0];
- in[1] = (facm + fact * tex[1]) * out[1];
- in[2] = (facm + fact * tex[2]) * out[2];
- break;
-
- case MTEX_SCREEN:
- fact *= facg;
- facm = 1.0f - fact;
- in[0] = 1.0f - (facm + fact * (1.0f - tex[0])) * (1.0f - out[0]);
- in[1] = 1.0f - (facm + fact * (1.0f - tex[1])) * (1.0f - out[1]);
- in[2] = 1.0f - (facm + fact * (1.0f - tex[2])) * (1.0f - out[2]);
- break;
-
- case MTEX_OVERLAY:
- fact *= facg;
- facm = 1.0f - fact;
-
- if (out[0] < 0.5f) {
- in[0] = out[0] * (facm + 2.0f * fact * tex[0]);
- }
- else {
- in[0] = 1.0f - (facm + 2.0f * fact * (1.0f - tex[0])) * (1.0f - out[0]);
- }
- if (out[1] < 0.5f) {
- in[1] = out[1] * (facm + 2.0f * fact * tex[1]);
- }
- else {
- in[1] = 1.0f - (facm + 2.0f * fact * (1.0f - tex[1])) * (1.0f - out[1]);
- }
- if (out[2] < 0.5f) {
- in[2] = out[2] * (facm + 2.0f * fact * tex[2]);
- }
- else {
- in[2] = 1.0f - (facm + 2.0f * fact * (1.0f - tex[2])) * (1.0f - out[2]);
- }
- break;
-
- case MTEX_SUB:
- fact = -fact;
- ATTR_FALLTHROUGH;
- case MTEX_ADD:
- fact *= facg;
- in[0] = (fact * tex[0] + out[0]);
- in[1] = (fact * tex[1] + out[1]);
- in[2] = (fact * tex[2] + out[2]);
- break;
-
- case MTEX_DIV:
- fact *= facg;
- facm = 1.0f - fact;
-
- if (tex[0] != 0.0f) {
- in[0] = facm * out[0] + fact * out[0] / tex[0];
- }
- if (tex[1] != 0.0f) {
- in[1] = facm * out[1] + fact * out[1] / tex[1];
- }
- if (tex[2] != 0.0f) {
- in[2] = facm * out[2] + fact * out[2] / tex[2];
- }
-
- break;
-
- case MTEX_DIFF:
- fact *= facg;
- facm = 1.0f - fact;
- in[0] = facm * out[0] + fact * fabsf(tex[0] - out[0]);
- in[1] = facm * out[1] + fact * fabsf(tex[1] - out[1]);
- in[2] = facm * out[2] + fact * fabsf(tex[2] - out[2]);
- break;
-
- case MTEX_DARK:
- fact *= facg;
- facm = 1.0f - fact;
-
- in[0] = min_ff(out[0], tex[0]) * fact + out[0] * facm;
- in[1] = min_ff(out[1], tex[1]) * fact + out[1] * facm;
- in[2] = min_ff(out[2], tex[2]) * fact + out[2] * facm;
- break;
-
- case MTEX_LIGHT:
- fact *= facg;
-
- in[0] = max_ff(fact * tex[0], out[0]);
- in[1] = max_ff(fact * tex[1], out[1]);
- in[2] = max_ff(fact * tex[2], out[2]);
- break;
-
- case MTEX_BLEND_HUE:
- fact *= facg;
- copy_v3_v3(in, out);
- ramp_blend(MA_RAMP_HUE, in, fact, tex);
- break;
- case MTEX_BLEND_SAT:
- fact *= facg;
- copy_v3_v3(in, out);
- ramp_blend(MA_RAMP_SAT, in, fact, tex);
- break;
- case MTEX_BLEND_VAL:
- fact *= facg;
- copy_v3_v3(in, out);
- ramp_blend(MA_RAMP_VAL, in, fact, tex);
- break;
- case MTEX_BLEND_COLOR:
- fact *= facg;
- copy_v3_v3(in, out);
- ramp_blend(MA_RAMP_COLOR, in, fact, tex);
- break;
- case MTEX_SOFT_LIGHT:
- fact *= facg;
- copy_v3_v3(in, out);
- ramp_blend(MA_RAMP_SOFT, in, fact, tex);
- break;
- case MTEX_LIN_LIGHT:
- fact *= facg;
- copy_v3_v3(in, out);
- ramp_blend(MA_RAMP_LINEAR, in, fact, tex);
- break;
- }
-}
-
float texture_value_blend(float tex, float out, float fact, float facg, int blendtype)
{
float in = 0.0, facm, col, scf;
@@ -1703,7 +1318,6 @@ bool RE_texture_evaluate(const MTex *mtex,
if (tex == NULL) {
return 0;
}
- texr.nor = NULL;
/* placement */
if (mtex->projx) {
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 63a7fb5ddaa..aaa28b1fd85 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -41,6 +41,7 @@
#include "GPU_debug.h"
#include "GPU_framebuffer.h"
#include "GPU_immediate.h"
+#include "GPU_matrix.h"
#include "GPU_state.h"
#include "GPU_texture.h"
#include "GPU_viewport.h"
@@ -158,9 +159,13 @@ static bool wm_software_cursor_needed_for_window(const wmWindow *win, struct Gra
if (GHOST_GetCursorVisibility(win->ghostwin)) {
/* NOTE: The value in `win->grabcursor` can't be used as it
* doesn't always match GHOST's value in the case of tablet events. */
- GHOST_GetCursorGrabState(
- win->ghostwin, &grab_state->mode, &grab_state->wrap_axis, grab_state->bounds);
- if (grab_state->mode == GHOST_kGrabWrap) {
+ bool use_software_cursor;
+ GHOST_GetCursorGrabState(win->ghostwin,
+ &grab_state->mode,
+ &grab_state->wrap_axis,
+ grab_state->bounds,
+ &use_software_cursor);
+ if (use_software_cursor) {
return true;
}
}
@@ -189,27 +194,69 @@ static void wm_software_cursor_motion_clear(void)
g_software_cursor.xy[1] = -1;
}
-static void wm_software_cursor_draw(wmWindow *win, const struct GrabState *grab_state)
+static void wm_software_cursor_draw_bitmap(const int event_xy[2],
+ const GHOST_CursorBitmapRef *bitmap)
{
- int x = win->eventstate->xy[0];
- int y = win->eventstate->xy[1];
+ GPU_blend(GPU_BLEND_ALPHA);
- if (grab_state->wrap_axis & GHOST_kAxisX) {
- const int min = grab_state->bounds[0];
- const int max = grab_state->bounds[2];
- if (min != max) {
- x = mod_i(x - min, max - min) + min;
- }
- }
- if (grab_state->wrap_axis & GHOST_kGrabAxisY) {
- const int height = WM_window_pixels_y(win);
- const int min = height - grab_state->bounds[1];
- const int max = height - grab_state->bounds[3];
- if (min != max) {
- y = mod_i(y - max, min - max) + max;
- }
- }
+ float gl_matrix[4][4];
+ GPUTexture *texture = GPU_texture_create_2d(
+ "softeare_cursor", bitmap->data_size[0], bitmap->data_size[1], 1, GPU_RGBA8, NULL);
+ GPU_texture_update(texture, GPU_DATA_UBYTE, bitmap->data);
+ GPU_texture_filter_mode(texture, false);
+
+ GPU_matrix_push();
+
+ const int scale = (int)U.pixelsize;
+
+ unit_m4(gl_matrix);
+
+ gl_matrix[3][0] = event_xy[0] - (bitmap->hot_spot[0] * scale);
+ gl_matrix[3][1] = event_xy[1] - ((bitmap->data_size[1] - bitmap->hot_spot[1]) * scale);
+
+ gl_matrix[0][0] = bitmap->data_size[0] * scale;
+ gl_matrix[1][1] = bitmap->data_size[1] * scale;
+
+ GPU_matrix_mul(gl_matrix);
+
+ GPUVertFormat *imm_format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ uint texCoord = GPU_vertformat_attr_add(
+ imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ /* Use 3D image for correct display of planar tracked images. */
+ immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA);
+
+ immBindTexture("image", texture);
+ immUniform1f("alpha", 1.0f);
+
+ immBegin(GPU_PRIM_TRI_FAN, 4);
+
+ immAttr2f(texCoord, 0.0f, 1.0f);
+ immVertex3f(pos, 0.0f, 0.0f, 0.0f);
+
+ immAttr2f(texCoord, 1.0f, 1.0f);
+ immVertex3f(pos, 1.0f, 0.0f, 0.0f);
+
+ immAttr2f(texCoord, 1.0f, 0.0f);
+ immVertex3f(pos, 1.0f, 1.0f, 0.0f);
+
+ immAttr2f(texCoord, 0.0f, 0.0f);
+ immVertex3f(pos, 0.0f, 1.0f, 0.0f);
+
+ immEnd();
+ immUnbindProgram();
+
+ GPU_matrix_pop();
+ GPU_texture_unbind(texture);
+ GPU_texture_free(texture);
+
+ GPU_blend(GPU_BLEND_NONE);
+}
+
+static void wm_software_cursor_draw_crosshair(const int event_xy[2])
+{
/* Draw a primitive cross-hair cursor.
* NOTE: the `win->cursor` could be used for drawing although it's complicated as some cursors
* are set by the operating-system, where the pixel information isn't easily available. */
@@ -222,19 +269,64 @@ static void wm_software_cursor_draw(wmWindow *win, const struct GrabState *grab_
{
const int ofs_line = (8 * unit);
const int ofs_size = (2 * unit);
- immRecti(pos, x - ofs_line, y - ofs_size, x + ofs_line, y + ofs_size);
- immRecti(pos, x - ofs_size, y - ofs_line, x + ofs_size, y + ofs_line);
+ immRecti(pos,
+ event_xy[0] - ofs_line,
+ event_xy[1] - ofs_size,
+ event_xy[0] + ofs_line,
+ event_xy[1] + ofs_size);
+ immRecti(pos,
+ event_xy[0] - ofs_size,
+ event_xy[1] - ofs_line,
+ event_xy[0] + ofs_size,
+ event_xy[1] + ofs_line);
}
immUniformColor4f(0, 0, 0, 1);
{
const int ofs_line = (7 * unit);
const int ofs_size = (1 * unit);
- immRecti(pos, x - ofs_line, y - ofs_size, x + ofs_line, y + ofs_size);
- immRecti(pos, x - ofs_size, y - ofs_line, x + ofs_size, y + ofs_line);
+ immRecti(pos,
+ event_xy[0] - ofs_line,
+ event_xy[1] - ofs_size,
+ event_xy[0] + ofs_line,
+ event_xy[1] + ofs_size);
+ immRecti(pos,
+ event_xy[0] - ofs_size,
+ event_xy[1] - ofs_line,
+ event_xy[0] + ofs_size,
+ event_xy[1] + ofs_line);
}
immUnbindProgram();
}
+static void wm_software_cursor_draw(wmWindow *win, const struct GrabState *grab_state)
+{
+ int event_xy[2] = {UNPACK2(win->eventstate->xy)};
+
+ if (grab_state->wrap_axis & GHOST_kAxisX) {
+ const int min = grab_state->bounds[0];
+ const int max = grab_state->bounds[2];
+ if (min != max) {
+ event_xy[0] = mod_i(event_xy[0] - min, max - min) + min;
+ }
+ }
+ if (grab_state->wrap_axis & GHOST_kGrabAxisY) {
+ const int height = WM_window_pixels_y(win);
+ const int min = height - grab_state->bounds[1];
+ const int max = height - grab_state->bounds[3];
+ if (min != max) {
+ event_xy[1] = mod_i(event_xy[1] - max, min - max) + max;
+ }
+ }
+
+ GHOST_CursorBitmapRef bitmap = {0};
+ if (GHOST_GetCursorBitmap(win->ghostwin, &bitmap) == GHOST_kSuccess) {
+ wm_software_cursor_draw_bitmap(event_xy, &bitmap);
+ }
+ else {
+ wm_software_cursor_draw_crosshair(event_xy);
+ }
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 330231f3f18..f77aad24719 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -338,10 +338,10 @@ void WM_init(bContext *C, int argc, const char **argv)
if (!G.background) {
if (wm_start_with_console) {
- setConsoleWindowState(GHOST_kConsoleWindowStateShow);
+ GHOST_setConsoleWindowState(GHOST_kConsoleWindowStateShow);
}
else {
- setConsoleWindowState(GHOST_kConsoleWindowStateHideForNonConsoleLaunch);
+ GHOST_setConsoleWindowState(GHOST_kConsoleWindowStateHideForNonConsoleLaunch);
}
}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 9f21e952850..33c69a23558 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -2072,7 +2072,7 @@ static void WM_OT_quit_blender(wmOperatorType *ot)
static int wm_console_toggle_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
{
- setConsoleWindowState(GHOST_kConsoleWindowStateToggle);
+ GHOST_setConsoleWindowState(GHOST_kConsoleWindowStateToggle);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index b3268cf1701..9c97b05f79b 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -212,7 +212,7 @@ static void playanim_gl_matrix(void)
/* implementation */
static void playanim_event_qual_update(void)
{
- int val;
+ bool val;
/* Shift */
GHOST_GetModifierKeyState(g_WS.ghost_system, GHOST_kModifierKeyLeftShift, &val);
@@ -871,7 +871,7 @@ static void change_frame(PlayState *ps)
ps->need_frame_update = false;
}
-static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
+static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
{
PlayState *ps = (PlayState *)ps_void;
const GHOST_TEventType type = GHOST_GetEventType(evt);
@@ -902,7 +902,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
default:
break;
}
- return 1;
+ return true;
}
if (ps->wait2 && ps->stopped == false) {
@@ -1335,7 +1335,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
break;
}
- return 1;
+ return true;
}
static void playanim_window_open(const char *title, int posx, int posy, int sizex, int sizey)
@@ -1555,6 +1555,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
/* initialize the font */
BLF_init();
+ BLF_load_font_stack();
ps.fontid = BLF_load_mono_default(false);
BLF_size(ps.fontid, 11.0f, 72);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index ef609b740c5..91ec45da6d4 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -983,7 +983,7 @@ static int query_qual(modifierKeyType qual)
break;
}
- int val = 0;
+ bool val = false;
GHOST_GetModifierKeyState(g_system, left, &val);
if (!val) {
GHOST_GetModifierKeyState(g_system, right, &val);
@@ -1053,7 +1053,7 @@ void wm_window_reset_drawable(void)
*
* Mouse coordinate conversion happens here.
*/
-static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr)
+static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr)
{
bContext *C = C_void_ptr;
wmWindowManager *wm = CTX_wm_manager(C);
@@ -1091,17 +1091,17 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
* but it should return if WM didn't initialize yet.
* Can happen on file read (especially full size window). */
if ((wm->initialized & WM_WINDOW_IS_INIT) == 0) {
- return 1;
+ return true;
}
if (!ghostwin) {
/* XXX: should be checked, why are we getting an event here, and what is it? */
puts("<!> event has no window");
- return 1;
+ return true;
}
if (!GHOST_ValidWindow(g_system, ghostwin)) {
/* XXX: should be checked, why are we getting an event here, and what is it? */
puts("<!> event has invalid window");
- return 1;
+ return true;
}
wmWindow *win = GHOST_GetWindowUserData(ghostwin);
@@ -1444,7 +1444,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
}
}
}
- return 1;
+ return true;
}
/**
@@ -1872,11 +1872,10 @@ wmWindow *WM_window_find_under_cursor(wmWindow *win, const int mval[2], int r_mv
return NULL;
}
- wmWindow *r_win = GHOST_GetWindowUserData(ghostwin);
- wm_cursor_position_from_ghost(r_win, &tmp[0], &tmp[1]);
+ wmWindow *win_other = GHOST_GetWindowUserData(ghostwin);
+ wm_cursor_position_from_ghost(win_other, &tmp[0], &tmp[1]);
copy_v2_v2_int(r_mval, tmp);
-
- return r_win;
+ return win_other;
}
void WM_window_pixel_sample_read(const wmWindowManager *wm,