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:
authorDalai Felinto <dalai@blender.org>2020-12-10 13:05:49 +0300
committerDalai Felinto <dalai@blender.org>2020-12-10 13:05:49 +0300
commitc5a17d5ea1ff786cb91cbcf3f12cd02f730c4143 (patch)
treef03a5935ee7dbc4c7ddabaee1c06570a26f698f9
parent390c4efa0c15b39e2d1971bc81464cffae56d102 (diff)
parente795ba1529a28ec276a5178fda2025e5ec071bbf (diff)
Merge remote-tracking branch 'origin/master' into geometry-nodes
-rw-r--r--.clang-tidy3
-rw-r--r--CMakeLists.txt4
-rw-r--r--build_files/build_environment/cmake/clang.cmake34
-rw-r--r--build_files/build_environment/cmake/harvest.cmake4
-rw-r--r--build_files/build_environment/cmake/versions.cmake3
-rw-r--r--build_files/cmake/platform/platform_win32.cmake17
-rw-r--r--doc/doxygen/Doxyfile4
-rw-r--r--doc/python_api/examples/bpy.types.bpy_struct.is_property_set.py30
-rw-r--r--doc/python_api/sphinx_doc_gen.py9
-rw-r--r--extern/audaspace/README.blender5
-rw-r--r--extern/bullet2/README.blender5
-rw-r--r--extern/ceres/README.blender1
-rw-r--r--extern/curve_fit_nd/README.blender2
-rw-r--r--extern/draco/CMakeLists.txt16
-rw-r--r--extern/draco/README.blender5
-rw-r--r--extern/draco/draco/AUTHORS (renamed from extern/draco/dracoenc/AUTHORS)0
-rw-r--r--extern/draco/draco/CMakeLists.txt (renamed from extern/draco/dracoenc/CMakeLists.txt)107
-rw-r--r--extern/draco/draco/LICENSE (renamed from extern/draco/dracoenc/LICENSE)0
-rw-r--r--extern/draco/draco/src/draco/animation/keyframe_animation.cc (renamed from extern/draco/dracoenc/src/draco/animation/keyframe_animation.cc)9
-rw-r--r--extern/draco/draco/src/draco/animation/keyframe_animation.h (renamed from extern/draco/dracoenc/src/draco/animation/keyframe_animation.h)17
-rw-r--r--extern/draco/draco/src/draco/animation/keyframe_animation_decoder.cc (renamed from extern/draco/dracoenc/src/draco/animation/keyframe_animation_decoder.cc)3
-rw-r--r--extern/draco/draco/src/draco/animation/keyframe_animation_decoder.h (renamed from extern/draco/dracoenc/src/draco/animation/keyframe_animation_decoder.h)0
-rw-r--r--extern/draco/draco/src/draco/animation/keyframe_animation_encoder.cc (renamed from extern/draco/dracoenc/src/draco/animation/keyframe_animation_encoder.cc)0
-rw-r--r--extern/draco/draco/src/draco/animation/keyframe_animation_encoder.h (renamed from extern/draco/dracoenc/src/draco/animation/keyframe_animation_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/attributes/attribute_octahedron_transform.cc (renamed from extern/draco/dracoenc/src/draco/attributes/attribute_octahedron_transform.cc)6
-rw-r--r--extern/draco/draco/src/draco/attributes/attribute_octahedron_transform.h (renamed from extern/draco/dracoenc/src/draco/attributes/attribute_octahedron_transform.h)0
-rw-r--r--extern/draco/draco/src/draco/attributes/attribute_quantization_transform.cc (renamed from extern/draco/dracoenc/src/draco/attributes/attribute_quantization_transform.cc)19
-rw-r--r--extern/draco/draco/src/draco/attributes/attribute_quantization_transform.h (renamed from extern/draco/dracoenc/src/draco/attributes/attribute_quantization_transform.h)0
-rw-r--r--extern/draco/draco/src/draco/attributes/attribute_transform.cc (renamed from extern/draco/dracoenc/src/draco/attributes/attribute_transform.cc)0
-rw-r--r--extern/draco/draco/src/draco/attributes/attribute_transform.h (renamed from extern/draco/dracoenc/src/draco/attributes/attribute_transform.h)0
-rw-r--r--extern/draco/draco/src/draco/attributes/attribute_transform_data.h (renamed from extern/draco/dracoenc/src/draco/attributes/attribute_transform_data.h)0
-rw-r--r--extern/draco/draco/src/draco/attributes/attribute_transform_type.h (renamed from extern/draco/dracoenc/src/draco/attributes/attribute_transform_type.h)0
-rw-r--r--extern/draco/draco/src/draco/attributes/geometry_attribute.cc (renamed from extern/draco/dracoenc/src/draco/attributes/geometry_attribute.cc)27
-rw-r--r--extern/draco/draco/src/draco/attributes/geometry_attribute.h (renamed from extern/draco/dracoenc/src/draco/attributes/geometry_attribute.h)37
-rw-r--r--extern/draco/draco/src/draco/attributes/geometry_indices.h (renamed from extern/draco/dracoenc/src/draco/attributes/geometry_indices.h)0
-rw-r--r--extern/draco/draco/src/draco/attributes/point_attribute.cc (renamed from extern/draco/dracoenc/src/draco/attributes/point_attribute.cc)30
-rw-r--r--extern/draco/draco/src/draco/attributes/point_attribute.h (renamed from extern/draco/dracoenc/src/draco/attributes/point_attribute.h)36
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/attributes_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/attributes/attributes_decoder.cc)34
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/attributes_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/attributes_decoder.h)15
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/attributes_decoder_interface.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/attributes_decoder_interface.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/attributes_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/attributes/attributes_encoder.cc)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/attributes_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/attributes_encoder.h)15
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/attributes/kd_tree_attributes_decoder.cc)98
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/kd_tree_attributes_decoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/attributes/kd_tree_attributes_encoder.cc)31
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/kd_tree_attributes_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_shared.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/kd_tree_attributes_shared.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/linear_sequencer.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/linear_sequencer.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/mesh_attribute_indices_encoding_data.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/mesh_attribute_indices_encoding_data.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/normal_compression_utils.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/normal_compression_utils.h)18
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/point_d_vector.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/point_d_vector.h)10
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/points_sequencer.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/points_sequencer.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h)16
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h)12
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h)31
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h)15
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h)6
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_decoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h)33
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h)13
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h)28
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h)12
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h)12
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h)9
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc)6
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h)6
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h)6
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h)15
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h)9
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h)17
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h)13
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h)14
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_attribute_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_decoder.cc)13
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_attribute_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_decoder.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_attribute_decoders_controller.cc (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_decoders_controller.cc)27
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_attribute_decoders_controller.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_decoders_controller.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_encoder.cc)12
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_encoder.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.cc (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_encoders_controller.cc)30
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_encoders_controller.h)15
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_integer_attribute_decoder.cc)60
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_integer_attribute_decoder.h)6
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_integer_attribute_encoder.cc)15
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_integer_attribute_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_normal_attribute_decoder.cc)13
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_normal_attribute_decoder.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_normal_attribute_encoder.cc)7
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_normal_attribute_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc)24
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_quantization_attribute_decoder.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc)15
-rw-r--r--extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/attributes/sequential_quantization_attribute_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.cc)9
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.cc)0
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/direct_bit_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/direct_bit_decoder.cc)12
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/direct_bit_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/direct_bit_decoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/direct_bit_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/direct_bit_encoder.cc)0
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/direct_bit_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/direct_bit_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/folded_integer_bit_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/folded_integer_bit_decoder.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/folded_integer_bit_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/folded_integer_bit_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/rans_bit_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/rans_bit_decoder.cc)15
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/rans_bit_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/rans_bit_decoder.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/rans_bit_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/rans_bit_encoder.cc)6
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/rans_bit_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/rans_bit_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/symbol_bit_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/symbol_bit_decoder.cc)6
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/symbol_bit_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/symbol_bit_decoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/symbol_bit_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/symbol_bit_encoder.cc)0
-rw-r--r--extern/draco/draco/src/draco/compression/bit_coders/symbol_bit_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/bit_coders/symbol_bit_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/config/compression_shared.h (renamed from extern/draco/dracoenc/src/draco/compression/config/compression_shared.h)1
-rw-r--r--extern/draco/draco/src/draco/compression/config/decoder_options.h (renamed from extern/draco/dracoenc/src/draco/compression/config/decoder_options.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/config/draco_options.h (renamed from extern/draco/dracoenc/src/draco/compression/config/draco_options.h)15
-rw-r--r--extern/draco/draco/src/draco/compression/config/encoder_options.h (renamed from extern/draco/dracoenc/src/draco/compression/config/encoder_options.h)6
-rw-r--r--extern/draco/draco/src/draco/compression/config/encoding_features.h (renamed from extern/draco/dracoenc/src/draco/compression/config/encoding_features.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/decode.cc (renamed from extern/draco/dracoenc/src/draco/compression/decode.cc)0
-rw-r--r--extern/draco/draco/src/draco/compression/decode.h (renamed from extern/draco/dracoenc/src/draco/compression/decode.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/encode.cc (renamed from extern/draco/dracoenc/src/draco/compression/encode.cc)3
-rw-r--r--extern/draco/draco/src/draco/compression/encode.h (renamed from extern/draco/dracoenc/src/draco/compression/encode.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/encode_base.h (renamed from extern/draco/dracoenc/src/draco/compression/encode_base.h)15
-rw-r--r--extern/draco/draco/src/draco/compression/entropy/ans.h (renamed from extern/draco/dracoenc/src/draco/compression/entropy/ans.h)34
-rw-r--r--extern/draco/draco/src/draco/compression/entropy/rans_symbol_coding.h (renamed from extern/draco/dracoenc/src/draco/compression/entropy/rans_symbol_coding.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/entropy/rans_symbol_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/entropy/rans_symbol_decoder.h)41
-rw-r--r--extern/draco/draco/src/draco/compression/entropy/rans_symbol_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/entropy/rans_symbol_encoder.h)30
-rw-r--r--extern/draco/draco/src/draco/compression/entropy/shannon_entropy.cc (renamed from extern/draco/dracoenc/src/draco/compression/entropy/shannon_entropy.cc)12
-rw-r--r--extern/draco/draco/src/draco/compression/entropy/shannon_entropy.h (renamed from extern/draco/dracoenc/src/draco/compression/entropy/shannon_entropy.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/entropy/symbol_decoding.cc (renamed from extern/draco/dracoenc/src/draco/compression/entropy/symbol_decoding.cc)30
-rw-r--r--extern/draco/draco/src/draco/compression/entropy/symbol_decoding.h (renamed from extern/draco/dracoenc/src/draco/compression/entropy/symbol_decoding.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/entropy/symbol_encoding.cc (renamed from extern/draco/dracoenc/src/draco/compression/entropy/symbol_encoding.cc)18
-rw-r--r--extern/draco/draco/src/draco/compression/entropy/symbol_encoding.h (renamed from extern/draco/dracoenc/src/draco/compression/entropy/symbol_encoding.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/expert_encode.cc (renamed from extern/draco/dracoenc/src/draco/compression/expert_encode.cc)15
-rw-r--r--extern/draco/draco/src/draco/compression/expert_encode.h (renamed from extern/draco/dracoenc/src/draco/compression/expert_encode.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_decoder.cc)6
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_decoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_decoder.cc)7
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_decoder.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc)200
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h)14
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoder.cc)37
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.cc (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.cc)72
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl_interface.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl_interface.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_shared.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_shared.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_decoder.h)30
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_decoder.h)12
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_encoder.h)3
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h)30
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_encoder.h)9
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_encoder.cc)3
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_sequential_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_sequential_decoder.cc)42
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_sequential_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_sequential_decoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_sequential_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_sequential_encoder.cc)3
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/mesh_sequential_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/mesh_sequential_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/traverser/depth_first_traverser.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/traverser/depth_first_traverser.h)9
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/traverser/max_prediction_degree_traverser.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/traverser/max_prediction_degree_traverser.h)9
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/traverser/mesh_attribute_indices_encoding_observer.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/traverser/mesh_attribute_indices_encoding_observer.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h)11
-rw-r--r--extern/draco/draco/src/draco/compression/mesh/traverser/traverser_base.h (renamed from extern/draco/dracoenc/src/draco/compression/mesh/traverser/traverser_base.h)6
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.cc)0
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h)56
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.cc)0
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h)18
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.cc)20
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.h)24
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.cc)0
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.h)6
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.cc)0
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.h)41
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.cc)0
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.h)21
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/point_cloud_compression_method.h (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/point_cloud_compression_method.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/point_cloud_types.h (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/point_cloud_types.h)1
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/quantize_points_3.h (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/quantize_points_3.h)1
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/algorithms/queuing_policy.h (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/queuing_policy.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/point_cloud_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_decoder.cc)66
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/point_cloud_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_decoder.h)6
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/point_cloud_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_encoder.cc)63
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/point_cloud_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.cc)6
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.cc)1
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/point_cloud_sequential_decoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_sequential_decoder.cc)3
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/point_cloud_sequential_decoder.h (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_sequential_decoder.h)0
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/point_cloud_sequential_encoder.cc (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_sequential_encoder.cc)0
-rw-r--r--extern/draco/draco/src/draco/compression/point_cloud/point_cloud_sequential_encoder.h (renamed from extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_sequential_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/core/bit_utils.cc (renamed from extern/draco/dracoenc/src/draco/core/bit_utils.cc)0
-rw-r--r--extern/draco/draco/src/draco/core/bit_utils.h (renamed from extern/draco/dracoenc/src/draco/core/bit_utils.h)1
-rw-r--r--extern/draco/draco/src/draco/core/bounding_box.cc (renamed from extern/draco/dracoenc/src/draco/core/bounding_box.cc)0
-rw-r--r--extern/draco/draco/src/draco/core/bounding_box.h (renamed from extern/draco/dracoenc/src/draco/core/bounding_box.h)6
-rw-r--r--extern/draco/draco/src/draco/core/cycle_timer.cc (renamed from extern/draco/dracoenc/src/draco/core/cycle_timer.cc)4
-rw-r--r--extern/draco/draco/src/draco/core/cycle_timer.h (renamed from extern/draco/dracoenc/src/draco/core/cycle_timer.h)0
-rw-r--r--extern/draco/draco/src/draco/core/data_buffer.cc (renamed from extern/draco/dracoenc/src/draco/core/data_buffer.cc)13
-rw-r--r--extern/draco/draco/src/draco/core/data_buffer.h (renamed from extern/draco/dracoenc/src/draco/core/data_buffer.h)0
-rw-r--r--extern/draco/draco/src/draco/core/decoder_buffer.cc (renamed from extern/draco/dracoenc/src/draco/core/decoder_buffer.cc)6
-rw-r--r--extern/draco/draco/src/draco/core/decoder_buffer.h (renamed from extern/draco/dracoenc/src/draco/core/decoder_buffer.h)22
-rw-r--r--extern/draco/draco/src/draco/core/divide.cc (renamed from extern/draco/dracoenc/src/draco/core/divide.cc)0
-rw-r--r--extern/draco/draco/src/draco/core/divide.h (renamed from extern/draco/dracoenc/src/draco/core/divide.h)1
-rw-r--r--extern/draco/draco/src/draco/core/draco_index_type.h (renamed from extern/draco/dracoenc/src/draco/core/draco_index_type.h)0
-rw-r--r--extern/draco/draco/src/draco/core/draco_index_type_vector.h (renamed from extern/draco/dracoenc/src/draco/core/draco_index_type_vector.h)8
-rw-r--r--extern/draco/draco/src/draco/core/draco_types.cc (renamed from extern/draco/dracoenc/src/draco/core/draco_types.cc)0
-rw-r--r--extern/draco/draco/src/draco/core/draco_types.h (renamed from extern/draco/dracoenc/src/draco/core/draco_types.h)1
-rw-r--r--extern/draco/draco/src/draco/core/draco_version.h (renamed from extern/draco/dracoenc/src/draco/core/draco_version.h)2
-rw-r--r--extern/draco/draco/src/draco/core/encoder_buffer.cc (renamed from extern/draco/dracoenc/src/draco/core/encoder_buffer.cc)9
-rw-r--r--extern/draco/draco/src/draco/core/encoder_buffer.h (renamed from extern/draco/dracoenc/src/draco/core/encoder_buffer.h)12
-rw-r--r--extern/draco/draco/src/draco/core/hash_utils.cc (renamed from extern/draco/dracoenc/src/draco/core/hash_utils.cc)3
-rw-r--r--extern/draco/draco/src/draco/core/hash_utils.h (renamed from extern/draco/dracoenc/src/draco/core/hash_utils.h)4
-rw-r--r--extern/draco/draco/src/draco/core/macros.h (renamed from extern/draco/dracoenc/src/draco/core/macros.h)1
-rw-r--r--extern/draco/draco/src/draco/core/math_utils.h (renamed from extern/draco/dracoenc/src/draco/core/math_utils.h)3
-rw-r--r--extern/draco/draco/src/draco/core/options.cc (renamed from extern/draco/dracoenc/src/draco/core/options.cc)15
-rw-r--r--extern/draco/draco/src/draco/core/options.h (renamed from extern/draco/dracoenc/src/draco/core/options.h)17
-rw-r--r--extern/draco/draco/src/draco/core/quantization_utils.cc (renamed from extern/draco/dracoenc/src/draco/core/quantization_utils.cc)3
-rw-r--r--extern/draco/draco/src/draco/core/quantization_utils.h (renamed from extern/draco/dracoenc/src/draco/core/quantization_utils.h)1
-rw-r--r--extern/draco/draco/src/draco/core/status.h (renamed from extern/draco/dracoenc/src/draco/core/status.h)4
-rw-r--r--extern/draco/draco/src/draco/core/status_or.h (renamed from extern/draco/dracoenc/src/draco/core/status_or.h)0
-rw-r--r--extern/draco/draco/src/draco/core/varint_decoding.h (renamed from extern/draco/dracoenc/src/draco/core/varint_decoding.h)53
-rw-r--r--extern/draco/draco/src/draco/core/varint_encoding.h (renamed from extern/draco/dracoenc/src/draco/core/varint_encoding.h)12
-rw-r--r--extern/draco/draco/src/draco/core/vector_d.h (renamed from extern/draco/dracoenc/src/draco/core/vector_d.h)60
-rw-r--r--extern/draco/draco/src/draco/draco_features.h10
-rw-r--r--extern/draco/draco/src/draco/mesh/corner_table.cc (renamed from extern/draco/dracoenc/src/draco/mesh/corner_table.cc)63
-rw-r--r--extern/draco/draco/src/draco/mesh/corner_table.h (renamed from extern/draco/dracoenc/src/draco/mesh/corner_table.h)59
-rw-r--r--extern/draco/draco/src/draco/mesh/corner_table_iterators.h (renamed from extern/draco/dracoenc/src/draco/mesh/corner_table_iterators.h)10
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh.cc (renamed from extern/draco/dracoenc/src/draco/mesh/mesh.cc)3
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh.h (renamed from extern/draco/dracoenc/src/draco/mesh/mesh.h)3
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh_are_equivalent.cc (renamed from extern/draco/dracoenc/src/draco/mesh/mesh_are_equivalent.cc)39
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh_are_equivalent.h (renamed from extern/draco/dracoenc/src/draco/mesh/mesh_are_equivalent.h)0
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh_attribute_corner_table.cc (renamed from extern/draco/dracoenc/src/draco/mesh/mesh_attribute_corner_table.cc)21
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh_attribute_corner_table.h (renamed from extern/draco/dracoenc/src/draco/mesh/mesh_attribute_corner_table.h)27
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh_cleanup.cc (renamed from extern/draco/dracoenc/src/draco/mesh/mesh_cleanup.cc)9
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh_cleanup.h (renamed from extern/draco/dracoenc/src/draco/mesh/mesh_cleanup.h)0
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh_misc_functions.cc (renamed from extern/draco/dracoenc/src/draco/mesh/mesh_misc_functions.cc)13
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh_misc_functions.h (renamed from extern/draco/dracoenc/src/draco/mesh/mesh_misc_functions.h)28
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh_stripifier.cc (renamed from extern/draco/dracoenc/src/draco/mesh/mesh_stripifier.cc)9
-rw-r--r--extern/draco/draco/src/draco/mesh/mesh_stripifier.h (renamed from extern/draco/dracoenc/src/draco/mesh/mesh_stripifier.h)24
-rw-r--r--extern/draco/draco/src/draco/mesh/triangle_soup_mesh_builder.cc (renamed from extern/draco/dracoenc/src/draco/mesh/triangle_soup_mesh_builder.cc)6
-rw-r--r--extern/draco/draco/src/draco/mesh/triangle_soup_mesh_builder.h (renamed from extern/draco/dracoenc/src/draco/mesh/triangle_soup_mesh_builder.h)1
-rw-r--r--extern/draco/draco/src/draco/mesh/valence_cache.h (renamed from extern/draco/dracoenc/src/draco/mesh/valence_cache.h)18
-rw-r--r--extern/draco/draco/src/draco/metadata/geometry_metadata.cc (renamed from extern/draco/dracoenc/src/draco/metadata/geometry_metadata.cc)10
-rw-r--r--extern/draco/draco/src/draco/metadata/geometry_metadata.h (renamed from extern/draco/dracoenc/src/draco/metadata/geometry_metadata.h)22
-rw-r--r--extern/draco/draco/src/draco/metadata/metadata.cc (renamed from extern/draco/dracoenc/src/draco/metadata/metadata.cc)4
-rw-r--r--extern/draco/draco/src/draco/metadata/metadata.h (renamed from extern/draco/dracoenc/src/draco/metadata/metadata.h)18
-rw-r--r--extern/draco/draco/src/draco/metadata/metadata_decoder.cc (renamed from extern/draco/dracoenc/src/draco/metadata/metadata_decoder.cc)91
-rw-r--r--extern/draco/draco/src/draco/metadata/metadata_decoder.h (renamed from extern/draco/dracoenc/src/draco/metadata/metadata_decoder.h)0
-rw-r--r--extern/draco/draco/src/draco/metadata/metadata_encoder.cc (renamed from extern/draco/dracoenc/src/draco/metadata/metadata_encoder.cc)15
-rw-r--r--extern/draco/draco/src/draco/metadata/metadata_encoder.h (renamed from extern/draco/dracoenc/src/draco/metadata/metadata_encoder.h)0
-rw-r--r--extern/draco/draco/src/draco/point_cloud/point_cloud.cc (renamed from extern/draco/dracoenc/src/draco/point_cloud/point_cloud.cc)47
-rw-r--r--extern/draco/draco/src/draco/point_cloud/point_cloud.h (renamed from extern/draco/dracoenc/src/draco/point_cloud/point_cloud.h)21
-rw-r--r--extern/draco/draco/src/draco/point_cloud/point_cloud_builder.cc (renamed from extern/draco/dracoenc/src/draco/point_cloud/point_cloud_builder.cc)3
-rw-r--r--extern/draco/draco/src/draco/point_cloud/point_cloud_builder.h (renamed from extern/draco/dracoenc/src/draco/point_cloud/point_cloud_builder.h)0
-rw-r--r--extern/draco/dracoenc/cmake/DracoConfig.cmake3
-rw-r--r--extern/draco/dracoenc/cmake/FindDraco.cmake58
-rw-r--r--extern/draco/dracoenc/cmake/compiler_flags.cmake216
-rw-r--r--extern/draco/dracoenc/cmake/compiler_tests.cmake124
-rw-r--r--extern/draco/dracoenc/cmake/draco_features.cmake57
-rw-r--r--extern/draco/dracoenc/cmake/draco_test_config.h.cmake13
-rw-r--r--extern/draco/dracoenc/cmake/draco_version.cc.cmake21
-rw-r--r--extern/draco/dracoenc/cmake/draco_version.h.cmake21
-rw-r--r--extern/draco/dracoenc/cmake/msvc_runtime.cmake14
-rw-r--r--extern/draco/dracoenc/cmake/sanitizers.cmake19
-rw-r--r--extern/draco/dracoenc/cmake/toolchains/arm-ios-common.cmake13
-rw-r--r--extern/draco/dracoenc/cmake/toolchains/arm64-android-ndk-libcpp.cmake12
-rw-r--r--extern/draco/dracoenc/cmake/toolchains/arm64-ios.cmake14
-rw-r--r--extern/draco/dracoenc/cmake/toolchains/arm64-linux-gcc.cmake18
-rw-r--r--extern/draco/dracoenc/cmake/toolchains/armv7-android-ndk-libcpp.cmake12
-rw-r--r--extern/draco/dracoenc/cmake/toolchains/armv7-ios.cmake14
-rw-r--r--extern/draco/dracoenc/cmake/toolchains/armv7-linux-gcc.cmake24
-rw-r--r--extern/draco/dracoenc/cmake/toolchains/armv7s-ios.cmake14
-rw-r--r--extern/draco/dracoenc/cmake/toolchains/x86-android-ndk-libcpp.cmake12
-rw-r--r--extern/draco/dracoenc/cmake/toolchains/x86_64-android-ndk-libcpp.cmake12
-rw-r--r--extern/draco/dracoenc/cmake/util.cmake73
-rw-r--r--extern/draco/dracoenc/src/draco/animation/keyframe_animation_encoding_test.cc168
-rw-r--r--extern/draco/dracoenc/src/draco/animation/keyframe_animation_test.cc102
-rw-r--r--extern/draco/dracoenc/src/draco/attributes/point_attribute_test.cc129
-rw-r--r--extern/draco/dracoenc/src/draco/compression/attributes/point_d_vector_test.cc359
-rw-r--r--extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_test.cc192
-rw-r--r--extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_test.cc71
-rw-r--r--extern/draco/dracoenc/src/draco/compression/attributes/sequential_integer_attribute_encoding_test.cc67
-rw-r--r--extern/draco/dracoenc/src/draco/compression/bit_coders/rans_coding_test.cc9
-rw-r--r--extern/draco/dracoenc/src/draco/compression/config/decoder_options_test.cc67
-rw-r--r--extern/draco/dracoenc/src/draco/compression/decode_test.cc196
-rw-r--r--extern/draco/dracoenc/src/draco/compression/encode_test.cc293
-rw-r--r--extern/draco/dracoenc/src/draco/compression/entropy/shannon_entropy_test.cc56
-rw-r--r--extern/draco/dracoenc/src/draco/compression/entropy/symbol_coding_test.cc170
-rw-r--r--extern/draco/dracoenc/src/draco/compression/mesh/mesh_decoder_helpers.h84
-rw-r--r--extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoding_test.cc247
-rw-r--r--extern/draco/dracoenc/src/draco/compression/mesh/mesh_encoder_helpers.h81
-rw-r--r--extern/draco/dracoenc/src/draco/compression/mesh/mesh_encoder_test.cc93
-rw-r--r--extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_kd_tree_encoding_test.cc456
-rw-r--r--extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_sequential_encoding_test.cc90
-rw-r--r--extern/draco/dracoenc/src/draco/core/buffer_bit_coding_test.cc116
-rw-r--r--extern/draco/dracoenc/src/draco/core/draco_test_base.h11
-rw-r--r--extern/draco/dracoenc/src/draco/core/draco_test_utils.cc83
-rw-r--r--extern/draco/dracoenc/src/draco/core/draco_test_utils.h70
-rw-r--r--extern/draco/dracoenc/src/draco/core/draco_tests.cc6
-rw-r--r--extern/draco/dracoenc/src/draco/core/math_utils_test.cc22
-rw-r--r--extern/draco/dracoenc/src/draco/core/quantization_utils_test.cc91
-rw-r--r--extern/draco/dracoenc/src/draco/core/status_test.cc38
-rw-r--r--extern/draco/dracoenc/src/draco/core/statusor.h81
-rw-r--r--extern/draco/dracoenc/src/draco/core/vector_d_test.cc235
-rw-r--r--extern/draco/dracoenc/src/draco/draco_features.h8
-rw-r--r--extern/draco/dracoenc/src/draco/io/mesh_io.cc69
-rw-r--r--extern/draco/dracoenc/src/draco/io/mesh_io.h102
-rw-r--r--extern/draco/dracoenc/src/draco/io/obj_decoder.cc689
-rw-r--r--extern/draco/dracoenc/src/draco/io/obj_decoder.h130
-rw-r--r--extern/draco/dracoenc/src/draco/io/obj_decoder_test.cc190
-rw-r--r--extern/draco/dracoenc/src/draco/io/obj_encoder.cc314
-rw-r--r--extern/draco/dracoenc/src/draco/io/obj_encoder.h92
-rw-r--r--extern/draco/dracoenc/src/draco/io/obj_encoder_test.cc106
-rw-r--r--extern/draco/dracoenc/src/draco/io/parser_utils.cc232
-rw-r--r--extern/draco/dracoenc/src/draco/io/parser_utils.h64
-rw-r--r--extern/draco/dracoenc/src/draco/io/ply_decoder.cc295
-rw-r--r--extern/draco/dracoenc/src/draco/io/ply_decoder.h69
-rw-r--r--extern/draco/dracoenc/src/draco/io/ply_decoder_test.cc90
-rw-r--r--extern/draco/dracoenc/src/draco/io/ply_encoder.cc201
-rw-r--r--extern/draco/dracoenc/src/draco/io/ply_encoder.h54
-rw-r--r--extern/draco/dracoenc/src/draco/io/ply_property_reader.h96
-rw-r--r--extern/draco/dracoenc/src/draco/io/ply_property_writer.h94
-rw-r--r--extern/draco/dracoenc/src/draco/io/ply_reader.cc295
-rw-r--r--extern/draco/dracoenc/src/draco/io/ply_reader.h152
-rw-r--r--extern/draco/dracoenc/src/draco/io/ply_reader_test.cc147
-rw-r--r--extern/draco/dracoenc/src/draco/io/point_cloud_io.cc58
-rw-r--r--extern/draco/dracoenc/src/draco/io/point_cloud_io.h89
-rw-r--r--extern/draco/dracoenc/src/draco/io/point_cloud_io_test.cc115
-rw-r--r--extern/draco/dracoenc/src/draco/mesh/mesh_are_equivalent_test.cc99
-rw-r--r--extern/draco/dracoenc/src/draco/mesh/mesh_cleanup_test.cc131
-rw-r--r--extern/draco/dracoenc/src/draco/mesh/triangle_soup_mesh_builder_test.cc197
-rw-r--r--extern/draco/dracoenc/src/draco/metadata/metadata_encoder_test.cc165
-rw-r--r--extern/draco/dracoenc/src/draco/metadata/metadata_test.cc156
-rw-r--r--extern/draco/dracoenc/src/draco/point_cloud/point_cloud_builder_test.cc171
-rw-r--r--extern/draco/dracoenc/src/draco/point_cloud/point_cloud_test.cc131
-rw-r--r--extern/draco/dracoenc/src/draco/tools/draco_decoder.cc178
-rw-r--r--extern/draco/dracoenc/src/draco/tools/draco_encoder.cc373
-rw-r--r--extern/draco/src/common.cpp77
-rw-r--r--extern/draco/src/common.h50
-rw-r--r--extern/draco/src/decoder.cpp222
-rw-r--r--extern/draco/src/decoder.h53
-rw-r--r--extern/draco/src/draco-compressor.cpp277
-rw-r--r--extern/draco/src/draco-compressor.h173
-rw-r--r--extern/draco/src/encoder.cpp247
-rw-r--r--extern/draco/src/encoder.h51
-rw-r--r--extern/gflags/README.blender2
-rw-r--r--extern/glew-es/LICENSE.txt73
-rw-r--r--extern/glew-es/README.blender5
-rw-r--r--extern/glew/LICENSE.txt73
-rw-r--r--extern/glew/README.blender5
-rw-r--r--extern/glog/README.blender2
-rw-r--r--extern/gmock/README.blender2
-rw-r--r--extern/gtest/README.blender2
-rw-r--r--extern/lzma/README.blender5
-rw-r--r--extern/lzo/README.blender5
-rw-r--r--extern/mantaflow/README.blender5
-rw-r--r--extern/mantaflow/preprocessed/gitinfo.h2
-rw-r--r--extern/mantaflow/preprocessed/plugin/advection.cpp8
-rw-r--r--extern/mantaflow/preprocessed/plugin/pressure.cpp14
-rw-r--r--intern/atomic/atomic_ops.h3
-rw-r--r--intern/atomic/intern/atomic_ops_msvc.h14
-rw-r--r--intern/atomic/intern/atomic_ops_unix.h19
-rw-r--r--intern/atomic/tests/atomic_test.cc33
-rw-r--r--intern/cycles/blender/addon/engine.py8
-rw-r--r--intern/cycles/blender/addon/properties.py36
-rw-r--r--intern/cycles/blender/addon/ui.py30
-rw-r--r--intern/cycles/blender/addon/version_update.py12
-rw-r--r--intern/cycles/blender/blender_mesh.cpp2
-rw-r--r--intern/cycles/blender/blender_sync.cpp10
-rw-r--r--intern/cycles/device/device_optix.cpp161
-rw-r--r--intern/cycles/kernel/CMakeLists.txt15
-rw-r--r--intern/cycles/kernel/kernel_subsurface.h29
-rw-r--r--intern/cycles/kernel/kernel_types.h2
-rw-r--r--intern/cycles/kernel/kernel_volume.h23
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h1
-rw-r--r--intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h2
-rw-r--r--intern/cycles/kernel/kernels/optix/kernel_optix.cu8
-rw-r--r--intern/cycles/kernel/svm/svm.h26
-rw-r--r--intern/cycles/render/mesh.cpp25
-rw-r--r--intern/cycles/render/mesh.h1
-rw-r--r--intern/ghost/CMakeLists.txt6
-rw-r--r--release/datafiles/blender_logo.pngbin0 -> 19535 bytes
m---------release/datafiles/locale0
-rw-r--r--release/license/ISC.txt14
-rw-r--r--release/lts/README.md41
-rwxr-xr-xrelease/lts/create_download_urls.py78
-rwxr-xr-xrelease/lts/create_release_notes.py166
-rw-r--r--release/lts/requirements.txt1
m---------release/scripts/addons0
-rw-r--r--release/scripts/modules/bl_i18n_utils/settings.py12
-rw-r--r--release/scripts/modules/bl_i18n_utils/utils.py74
-rw-r--r--release/scripts/modules/bl_i18n_utils/utils_cli.py145
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/utils_languages_menu.py2
-rw-r--r--release/scripts/modules/bl_i18n_utils/utils_spell_check.py6
-rw-r--r--release/scripts/modules/bpy/utils/__init__.py2
-rw-r--r--release/scripts/modules/rna_prop_ui.py2
-rw-r--r--release/scripts/presets/keyconfig/blender.py1
-rw-r--r--release/scripts/presets/keyconfig/blender_27x.py10
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py7
-rw-r--r--release/scripts/startup/bl_operators/anim.py13
-rw-r--r--release/scripts/startup/bl_operators/clip.py4
-rw-r--r--release/scripts/startup/bl_operators/image.py2
-rw-r--r--release/scripts/startup/bl_operators/wm.py66
-rw-r--r--release/scripts/startup/bl_ui/properties_constraint.py23
-rw-r--r--release/scripts/startup/bl_ui/properties_data_curve.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py8
-rw-r--r--release/scripts/startup/bl_ui/properties_view_layer.py79
-rw-r--r--release/scripts/startup/bl_ui/space_dopesheet.py2
-rw-r--r--release/scripts/startup/bl_ui/space_graph.py6
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py12
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py23
-rw-r--r--release/scripts/startup/keyingsets_builtins.py2
-rw-r--r--release/scripts/startup/nodeitems_builtins.py7
-rw-r--r--source/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/BKE_appdir.h1
-rw-r--r--source/blender/blenkernel/BKE_attribute_access.hh31
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/BKE_constraint.h7
-rw-r--r--source/blender/blenkernel/BKE_cryptomatte.h42
-rw-r--r--source/blender/blenkernel/BKE_geometry_set.hh8
-rw-r--r--source/blender/blenkernel/BKE_gpencil_modifier.h3
-rw-r--r--source/blender/blenkernel/BKE_layer.h10
-rw-r--r--source/blender/blenkernel/BKE_modifier.h2
-rw-r--r--source/blender/blenkernel/BKE_nla.h18
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/anim_data.c12
-rw-r--r--source/blender/blenkernel/intern/appdir.c8
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc35
-rw-r--r--source/blender/blenkernel/intern/brush.c1
-rw-r--r--source/blender/blenkernel/intern/constraint.c318
-rw-r--r--source/blender/blenkernel/intern/cryptomatte.c87
-rw-r--r--source/blender/blenkernel/intern/curve.c21
-rw-r--r--source/blender/blenkernel/intern/fcurve_driver.c8
-rw-r--r--source/blender/blenkernel/intern/gpencil.c2
-rw-r--r--source/blender/blenkernel/intern/gpencil_modifier.c13
-rw-r--r--source/blender/blenkernel/intern/ipo.c6
-rw-r--r--source/blender/blenkernel/intern/layer.c166
-rw-r--r--source/blender/blenkernel/intern/layer_test.cc177
-rw-r--r--source/blender/blenkernel/intern/linestyle.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.cc4
-rw-r--r--source/blender/blenkernel/intern/modifier.c12
-rw-r--r--source/blender/blenkernel/intern/nla.c52
-rw-r--r--source/blender/blenkernel/intern/node.c2
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c15
-rw-r--r--source/blender/blenkernel/intern/screen.c7
-rw-r--r--source/blender/blenkernel/intern/tracking.c12
-rw-r--r--source/blender/blenkernel/intern/tracking_auto.c10
-rw-r--r--source/blender/blenkernel/intern/tracking_util.c114
-rw-r--r--source/blender/blenkernel/tracking_private.h2
-rw-r--r--source/blender/blenlib/BLI_string.h5
-rw-r--r--source/blender/blenlib/intern/mesh_intersect.cc24
-rw-r--r--source/blender/blenlib/intern/path_util.c5
-rw-r--r--source/blender/blenlib/intern/rand.cc8
-rw-r--r--source/blender/blenlib/intern/string.c167
-rw-r--r--source/blender/blenlib/intern/task_pool.cc6
-rw-r--r--source/blender/blenlib/intern/task_range.cc2
-rw-r--r--source/blender/blenlib/intern/threads.cc10
-rw-r--r--source/blender/blenlib/tests/BLI_array_store_test.cc8
-rw-r--r--source/blender/blenlib/tests/BLI_expr_pylike_eval_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_heap_simple_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_heap_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_linklist_lockfree_test.cc4
-rw-r--r--source/blender/blenlib/tests/BLI_math_rotation_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_stack_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_string_test.cc181
-rw-r--r--source/blender/blenlib/tests/BLI_task_test.cc2
-rw-r--r--source/blender/blenloader/intern/blend_validate.c2
-rw-r--r--source/blender/blenloader/intern/readblenentry.c8
-rw-r--r--source/blender/blenloader/intern/readfile.c6
-rw-r--r--source/blender/blenloader/intern/versioning_290.c46
-rw-r--r--source/blender/blenloader/intern/versioning_userdef.c23
-rw-r--r--source/blender/blenloader/tests/blendfile_loading_base_test.cc2
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c187
-rw-r--r--source/blender/bmesh/tools/bmesh_boolean.cc20
-rw-r--r--source/blender/compositor/intern/COM_ChunkOrderHotspot.cpp2
-rw-r--r--source/blender/compositor/intern/COM_CompositorContext.cpp2
-rw-r--r--source/blender/compositor/intern/COM_Converter.cpp2
-rw-r--r--source/blender/compositor/intern/COM_ExecutionGroup.cpp4
-rw-r--r--source/blender/compositor/intern/COM_Node.cpp2
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.cpp2
-rw-r--r--source/blender/compositor/intern/COM_NodeOperationBuilder.cpp4
-rw-r--r--source/blender/compositor/intern/COM_OpenCLDevice.cpp2
-rw-r--r--source/blender/compositor/intern/COM_WorkScheduler.cpp2
-rw-r--r--source/blender/compositor/operations/COM_DilateErodeOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_OutputFileOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_VectorBlurOperation.cpp11
-rw-r--r--source/blender/compositor/operations/COM_WrapOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_WriteBufferOperation.cpp2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc7
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc7
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_all_objects.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_from_ids.cc8
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query.cc6
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_foreach.cc4
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.cc2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node.cc2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_component.cc2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_id.cc2
-rw-r--r--source/blender/draw/CMakeLists.txt2
-rw-r--r--source/blender/draw/engines/eevee/eevee_cryptomatte.c654
-rw-r--r--source/blender/draw/engines/eevee/eevee_data.c3
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c119
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h55
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c90
-rw-r--r--source/blender/draw/engines/eevee/eevee_renderpasses.c62
-rw-r--r--source/blender/draw/engines/eevee/eevee_shaders.c32
-rw-r--r--source/blender/draw/engines/eevee/shaders/cryptomatte_frag.glsl7
-rw-r--r--source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl13
-rw-r--r--source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl37
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c4
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_shader_fx.c2
-rw-r--r--source/blender/draw/engines/image/image_private.h2
-rw-r--r--source/blender/draw/tests/shaders_test.cc2
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c52
-rw-r--r--source/blender/editors/animation/anim_deps.c8
-rw-r--r--source/blender/editors/animation/anim_filter.c19
-rw-r--r--source/blender/editors/animation/anim_ipo_utils.c3
-rw-r--r--source/blender/editors/animation/keyframes_general.c13
-rw-r--r--source/blender/editors/animation/keyframing.c23
-rw-r--r--source/blender/editors/armature/armature_add.c17
-rw-r--r--source/blender/editors/armature/pose_select.c4
-rw-r--r--source/blender/editors/datafiles/CMakeLists.txt1
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c102
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c7
-rw-r--r--source/blender/editors/gpencil/gpencil_data.c5
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c157
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_ops.c576
-rw-r--r--source/blender/editors/include/ED_datafiles.h3
-rw-r--r--source/blender/editors/include/ED_fileselect.h4
-rw-r--r--source/blender/editors/include/UI_interface.h10
-rw-r--r--source/blender/editors/interface/interface.c2
-rw-r--r--source/blender/editors/interface/interface_context_menu.c248
-rw-r--r--source/blender/editors/interface/interface_handlers.c1
-rw-r--r--source/blender/editors/interface/interface_layout.c42
-rw-r--r--source/blender/editors/interface/interface_ops.c16
-rw-r--r--source/blender/editors/interface/interface_panel.c3
-rw-r--r--source/blender/editors/mesh/editmesh_select.c2
-rw-r--r--source/blender/editors/object/object_add.c5
-rw-r--r--source/blender/editors/object/object_constraint.c9
-rw-r--r--source/blender/editors/object/object_gpencil_modifier.c34
-rw-r--r--source/blender/editors/object/object_modifier.c9
-rw-r--r--source/blender/editors/render/render_intern.h2
-rw-r--r--source/blender/editors/render/render_ops.c2
-rw-r--r--source/blender/editors/render/render_shading.c88
-rw-r--r--source/blender/editors/screen/screen_context.c5
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c9
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c55
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mesh.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h32
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_paint_color.c3
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_pose.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_transform.c4
-rw-r--r--source/blender/editors/sound/sound_ops.c32
-rw-r--r--source/blender/editors/space_action/action_data.c11
-rw-r--r--source/blender/editors/space_file/file_draw.c42
-rw-r--r--source/blender/editors/space_file/file_ops.c299
-rw-r--r--source/blender/editors/space_file/file_panels.c2
-rw-r--r--source/blender/editors/space_file/filelist.c11
-rw-r--r--source/blender/editors/space_file/filesel.c106
-rw-r--r--source/blender/editors/space_file/space_file.c6
-rw-r--r--source/blender/editors/space_graph/graph_edit.c178
-rw-r--r--source/blender/editors/space_graph/graph_select.c1
-rw-r--r--source/blender/editors/space_image/image_ops.c4
-rw-r--r--source/blender/editors/space_info/info_stats.c23
-rw-r--r--source/blender/editors/space_nla/nla_channels.c17
-rw-r--r--source/blender/editors/space_nla/nla_edit.c99
-rw-r--r--source/blender/editors/space_outliner/CMakeLists.txt13
-rw-r--r--source/blender/editors/space_outliner/outliner_dragdrop.c6
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c12
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c16
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h17
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c324
-rw-r--r--source/blender/editors/space_outliner/outliner_utils.c5
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c15
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display.cc6
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display.hh66
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_data.cc56
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_orphaned.cc97
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_scenes.cc63
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_sequencer.cc122
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element.cc88
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element.h45
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element.hh53
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_anim_data.cc70
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_anim_data.hh42
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_driver_base.cc68
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_driver_base.hh38
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_nla.cc78
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_nla.hh53
-rw-r--r--source/blender/editors/space_text/text_draw.c2
-rw-r--r--source/blender/editors/space_text/text_header.c98
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_ruler.c9
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h2
-rw-r--r--source/blender/editors/space_view3d/view3d_placement.c11
-rw-r--r--source/blender/editors/space_view3d/view3d_utils.c10
-rw-r--r--source/blender/editors/transform/transform.c206
-rw-r--r--source/blender/editors/transform/transform.h3
-rw-r--r--source/blender/editors/transform/transform_constraints.c10
-rw-r--r--source/blender/editors/transform/transform_convert.c2
-rw-r--r--source/blender/editors/transform/transform_convert_armature.c28
-rw-r--r--source/blender/editors/transform/transform_convert_nla.c16
-rw-r--r--source/blender/editors/transform/transform_convert_node.c40
-rw-r--r--source/blender/editors/transform/transform_generics.c44
-rw-r--r--source/blender/editors/transform/transform_mode_edge_seq_slide.c30
-rw-r--r--source/blender/editors/transform/transform_mode_shrink_fatten.c28
-rw-r--r--source/blender/editors/transform/transform_mode_translate.c30
-rw-r--r--source/blender/editors/transform/transform_ops.c4
-rw-r--r--source/blender/editors/uvedit/uvedit_islands.c22
-rw-r--r--source/blender/freestyle/intern/application/Controller.cpp4
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp2
-rw-r--r--source/blender/freestyle/intern/geometry/FitCurve.cpp6
-rw-r--r--source/blender/freestyle/intern/geometry/GeomCleaner.cpp4
-rw-r--r--source/blender/freestyle/intern/geometry/Noise.cpp8
-rw-r--r--source/blender/freestyle/intern/image/GaussianFilter.cpp2
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeCamera.cpp4
-rw-r--r--source/blender/freestyle/intern/stroke/Curve.cpp2
-rw-r--r--source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp2
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMap.cpp2
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp6
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapIO.cpp2
-rw-r--r--source/blender/freestyle/intern/winged_edge/Curvature.cpp2
-rw-r--r--source/blender/gpu/CMakeLists.txt1
-rw-r--r--source/blender/gpu/GPU_material.h1
-rw-r--r--source/blender/gpu/intern/gpu_batch.cc6
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c37
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.cc52
-rw-r--r--source/blender/gpu/intern/gpu_material.c8
-rw-r--r--source/blender/gpu/intern/gpu_material_library.c7
-rw-r--r--source/blender/gpu/intern/gpu_matrix.cc12
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.c4
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.h10
-rw-r--r--source/blender/gpu/intern/gpu_select_sample_query.cc6
-rw-r--r--source/blender/gpu/intern/gpu_shader.cc6
-rw-r--r--source/blender/gpu/intern/gpu_uniform_buffer.cc2
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format.cc4
-rw-r--r--source/blender/gpu/opengl/gl_backend.cc30
-rw-r--r--source/blender/gpu/opengl/gl_debug.cc2
-rw-r--r--source/blender/gpu/opengl/gl_debug_layer.cc2
-rw-r--r--source/blender/gpu/opengl/gl_drawlist.cc10
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_output_aov.glsl13
-rw-r--r--source/blender/ikplugin/intern/itasc_plugin.cpp18
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.c33
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.h5
-rw-r--r--source/blender/imbuf/intern/dds/BlockDXT.cpp4
-rw-r--r--source/blender/imbuf/intern/dds/ColorBlock.cpp16
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.cpp6
-rw-r--r--source/blender/imbuf/intern/dds/FlipDXT.cpp4
-rw-r--r--source/blender/imbuf/intern/dds/Image.cpp2
-rw-r--r--source/blender/imbuf/intern/dds/Stream.cpp4
-rw-r--r--source/blender/imbuf/intern/dds/dds_api.cpp4
-rw-r--r--source/blender/imbuf/intern/oiio/CMakeLists.txt1
-rw-r--r--source/blender/imbuf/intern/oiio/openimageio_api.cpp2
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp107
-rw-r--r--source/blender/imbuf/intern/thumbs_blend.c4
-rw-r--r--source/blender/io/alembic/exporter/abc_subdiv_disabler.cc2
-rw-r--r--source/blender/io/alembic/intern/abc_reader_mesh.cc4
-rw-r--r--source/blender/io/alembic/tests/abc_export_test.cc4
-rw-r--r--source/blender/io/collada/AnimationImporter.cpp11
-rw-r--r--source/blender/io/collada/BCAnimationCurve.cpp10
-rw-r--r--source/blender/io/collada/BCAnimationSampler.cpp1
-rw-r--r--source/blender/io/collada/BCMath.cpp14
-rw-r--r--source/blender/io/collada/BlenderContext.cpp4
-rw-r--r--source/blender/io/collada/ControllerExporter.cpp14
-rw-r--r--source/blender/io/collada/DocumentExporter.cpp8
-rw-r--r--source/blender/io/collada/DocumentImporter.cpp15
-rw-r--r--source/blender/io/collada/ErrorHandler.cpp2
-rw-r--r--source/blender/io/collada/ExtraHandler.cpp2
-rw-r--r--source/blender/io/collada/ExtraTags.cpp4
-rw-r--r--source/blender/io/collada/MeshImporter.cpp11
-rw-r--r--source/blender/io/collada/SceneExporter.cpp3
-rw-r--r--source/blender/io/collada/SkinInfo.cpp2
-rw-r--r--source/blender/io/collada/collada_internal.cpp5
-rw-r--r--source/blender/io/collada/collada_utils.cpp23
-rw-r--r--source/blender/io/collada/collada_utils.h2
-rw-r--r--source/blender/io/common/intern/abstract_hierarchy_iterator.cc4
-rw-r--r--source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc6
-rw-r--r--source/blender/io/common/intern/object_identifier.cc2
-rw-r--r--source/blender/makesdna/DNA_anim_types.h4
-rw-r--r--source/blender/makesdna/DNA_brush_defaults.h1
-rw-r--r--source/blender/makesdna/DNA_brush_types.h9
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h13
-rw-r--r--source/blender/makesdna/DNA_layer_types.h44
-rw-r--r--source/blender/makesdna/DNA_mesh_types.h2
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h2
-rw-r--r--source/blender/makesdna/DNA_modifier_defaults.h1
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h11
-rw-r--r--source/blender/makesdna/DNA_node_types.h7
-rw-r--r--source/blender/makesdna/DNA_outliner_types.h2
-rw-r--r--source/blender/makesdna/DNA_space_types.h23
-rw-r--r--source/blender/makesdna/DNA_vfont_types.h2
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h1
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/rna_ID.c4
-rw-r--r--source/blender/makesrna/intern/rna_access.c86
-rw-r--r--source/blender/makesrna/intern/rna_access_compare_override.c14
-rw-r--r--source/blender/makesrna/intern/rna_animation.c70
-rw-r--r--source/blender/makesrna/intern/rna_armature.c2
-rw-r--r--source/blender/makesrna/intern/rna_attribute.c8
-rw-r--r--source/blender/makesrna/intern/rna_boid.c2
-rw-r--r--source/blender/makesrna/intern/rna_brush.c29
-rw-r--r--source/blender/makesrna/intern/rna_cloth.c4
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c35
-rw-r--r--source/blender/makesrna/intern/rna_dynamicpaint.c8
-rw-r--r--source/blender/makesrna/intern/rna_fluid.c6
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c6
-rw-r--r--source/blender/makesrna/intern/rna_gpencil_modifier.c4
-rw-r--r--source/blender/makesrna/intern/rna_image.c2
-rw-r--r--source/blender/makesrna/intern/rna_internal.h4
-rw-r--r--source/blender/makesrna/intern/rna_key.c4
-rw-r--r--source/blender/makesrna/intern/rna_layer.c14
-rw-r--r--source/blender/makesrna/intern/rna_linestyle.c8
-rw-r--r--source/blender/makesrna/intern/rna_mask.c2
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c30
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c13
-rw-r--r--source/blender/makesrna/intern/rna_nla.c14
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c6
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c21
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c18
-rw-r--r--source/blender/makesrna/intern/rna_particle.c4
-rw-r--r--source/blender/makesrna/intern/rna_pose.c2
-rw-r--r--source/blender/makesrna/intern/rna_rna.c4
-rw-r--r--source/blender/makesrna/intern/rna_scene.c165
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c16
-rw-r--r--source/blender/makesrna/intern/rna_shader_fx.c2
-rw-r--r--source/blender/makesrna/intern/rna_space.c113
-rw-r--r--source/blender/makesrna/intern/rna_texture.c11
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c13
-rw-r--r--source/blender/makesrna/intern/rna_volume.c4
-rw-r--r--source/blender/modifiers/intern/MOD_boolean.c32
-rw-r--r--source/blender/modifiers/intern/MOD_weld.c82
-rw-r--r--source/blender/nodes/NOD_geometry_exec.hh22
-rw-r--r--source/blender/nodes/geometry/node_geometry_tree.cc2
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.cc21
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.hh6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_common.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc6
-rw-r--r--source/blender/nodes/intern/node_geometry_exec.cc41
-rw-r--r--source/blender/nodes/intern/node_socket.cc2
-rw-r--r--source/blender/nodes/intern/node_tree_multi_function.cc4
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c15
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_aov.c19
-rw-r--r--source/blender/python/generic/idprop_py_api.c11
-rw-r--r--source/blender/python/intern/CMakeLists.txt6
-rw-r--r--source/blender/python/intern/bpy.c63
-rw-r--r--source/blender/python/intern/bpy_library_load.c4
-rw-r--r--source/blender/python/intern/bpy_props.c1
-rw-r--r--source/blender/sequencer/intern/sequencer.c2
-rw-r--r--source/blender/simulation/intern/hair_volume.cpp8
-rw-r--r--source/blender/windowmanager/WM_api.h7
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c39
-rw-r--r--source/blender/windowmanager/intern/wm_files.c61
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c5
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c57
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c181
-rw-r--r--source/blender/windowmanager/intern/wm_operator_type.c4
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c3
-rw-r--r--source/blender/windowmanager/intern/wm_splash_screen.c77
-rw-r--r--source/blender/windowmanager/intern/wm_surface.c3
-rw-r--r--source/blender/windowmanager/intern/wm_window.c11
-rw-r--r--source/creator/creator_args.c3
m---------source/tools0
-rw-r--r--tests/python/bl_blendfile_io.py4
-rw-r--r--tests/python/bl_blendfile_liblink.py1
-rw-r--r--tests/python/bl_constraints.py74
-rw-r--r--tests/python/eevee_render_tests.py2
804 files changed, 10919 insertions, 14549 deletions
diff --git a/.clang-tidy b/.clang-tidy
index 49b238d8708..d65027687bb 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -34,17 +34,14 @@ Checks: >
modernize-*,
-modernize-use-auto,
-modernize-use-trailing-return-type,
- -modernize-deprecated-headers,
-modernize-avoid-c-arrays,
-modernize-use-equals-default,
-modernize-use-nodiscard,
- -modernize-use-using,
-modernize-loop-convert,
-modernize-pass-by-value,
-modernize-use-default-member-init,
-modernize-raw-string-literal,
-modernize-avoid-bind,
- -modernize-use-override,
-modernize-use-transparent-functors,
WarningsAsErrors: '*'
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 81fe4739da4..0d7cf4e325c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -427,8 +427,8 @@ mark_as_advanced(WITH_CXX_GUARDEDALLOC)
option(WITH_ASSERT_ABORT "Call abort() when raising an assertion through BLI_assert()" ON)
mark_as_advanced(WITH_ASSERT_ABORT)
-if(UNIX AND NOT APPLE)
- option(WITH_CLANG_TIDY "Use Clang Tidy to analyze the source code (only enable for development on Linux using Clang)" OFF)
+if((UNIX AND NOT APPLE) OR (CMAKE_GENERATOR MATCHES "^Visual Studio.+"))
+ option(WITH_CLANG_TIDY "Use Clang Tidy to analyze the source code (only enable for development on Linux using Clang, or Windows using the Visual Studio IDE)" OFF)
mark_as_advanced(WITH_CLANG_TIDY)
endif()
diff --git a/build_files/build_environment/cmake/clang.cmake b/build_files/build_environment/cmake/clang.cmake
index 9de0ec1b182..d8d83619e1a 100644
--- a/build_files/build_environment/cmake/clang.cmake
+++ b/build_files/build_environment/cmake/clang.cmake
@@ -17,13 +17,14 @@
# ***** END GPL LICENSE BLOCK *****
set(CLANG_EXTRA_ARGS
- -DCLANG_PATH_TO_LLVM_SOURCE=${BUILD_DIR}/ll/src/ll
- -DCLANG_PATH_TO_LLVM_BUILD=${LIBDIR}/llvm
+ -DLLVM_DIR="${LIBDIR}/llvm/lib/cmake/llvm/"
-DLLVM_USE_CRT_RELEASE=MD
-DLLVM_USE_CRT_DEBUG=MDd
-DLLVM_CONFIG=${LIBDIR}/llvm/bin/llvm-config
)
+set(BUILD_CLANG_TOOLS OFF)
+
if(WIN32)
set(CLANG_GENERATOR "Ninja")
else()
@@ -31,11 +32,32 @@ else()
endif()
if(APPLE)
+ set(BUILD_CLANG_TOOLS ON)
set(CLANG_EXTRA_ARGS ${CLANG_EXTRA_ARGS}
-DLIBXML2_LIBRARY=${LIBDIR}/xml2/lib/libxml2.a
)
endif()
+if(BUILD_CLANG_TOOLS)
+ # ExternalProject_Add does not allow multiple tarballs to be
+ # downloaded. Work around this by having an empty build action
+ # for the extra tools, and referring the clang build to the location
+ # of the clang-tools-extra source.
+ ExternalProject_Add(external_clang_tools
+ URL ${CLANG_TOOLS_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${CLANG_TOOLS_HASH}
+ INSTALL_DIR ${LIBDIR}/clang_tools
+ PREFIX ${BUILD_DIR}/clang_tools
+ CONFIGURE_COMMAND echo "."
+ BUILD_COMMAND echo "."
+ INSTALL_COMMAND echo "."
+ )
+ list(APPEND CLANG_EXTRA_ARGS
+ -DLLVM_EXTERNAL_CLANG_TOOLS_EXTRA_SOURCE_DIR=${BUILD_DIR}/clang_tools/src/external_clang_tools/
+ )
+endif()
+
ExternalProject_Add(external_clang
URL ${CLANG_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
@@ -65,6 +87,14 @@ add_dependencies(
ll
)
+if(BUILD_CLANG_TOOLS)
+ # `external_clang_tools` is for downloading the source, not compiling it.
+ add_dependencies(
+ external_clang
+ external_clang_tools
+ )
+endif()
+
# We currently do not build libxml2 on Windows.
if(NOT WIN32)
add_dependencies(
diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake
index 0f9b67a3d44..536907f563d 100644
--- a/build_files/build_environment/cmake/harvest.cmake
+++ b/build_files/build_environment/cmake/harvest.cmake
@@ -98,6 +98,10 @@ harvest(jpg/include jpeg/include "*.h")
harvest(jpg/lib jpeg/lib "libjpeg.a")
harvest(lame/lib ffmpeg/lib "*.a")
harvest(clang/bin llvm/bin "clang-format")
+if(BUILD_CLANG_TOOLS)
+ harvest(clang/bin llvm/bin "clang-tidy")
+ harvest(clang/share/clang llvm/share "run-clang-tidy.py")
+endif()
harvest(clang/include llvm/include "*")
harvest(llvm/include llvm/include "*")
harvest(llvm/bin llvm/bin "llvm-config")
diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake
index 653db9f740c..d4a2c715ecc 100644
--- a/build_files/build_environment/cmake/versions.cmake
+++ b/build_files/build_environment/cmake/versions.cmake
@@ -120,6 +120,9 @@ set(LLVM_HASH 31eb9ce73dd2a0f8dcab8319fb03f8fc)
set(CLANG_URI https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/clang-${LLVM_VERSION}.src.tar.xz)
set(CLANG_HASH 13468e4a44940efef1b75e8641752f90)
+set(CLANG_TOOLS_URI https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/clang-tools-extra-${LLVM_VERSION}.src.tar.xz)
+set(CLANG_TOOLS_HASH c76293870b564c6a7968622b475b7646)
+
set(OPENMP_URI https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/openmp-${LLVM_VERSION}.src.tar.xz)
set(OPENMP_HASH 6eade16057edbdecb3c4eef9daa2bfcf)
diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake
index 3954a5f143c..dd8b286c689 100644
--- a/build_files/cmake/platform/platform_win32.cmake
+++ b/build_files/cmake/platform/platform_win32.cmake
@@ -239,9 +239,24 @@ if(NOT EXISTS "${LIBDIR}/")
message(FATAL_ERROR "\n\nWindows requires pre-compiled libs at: '${LIBDIR}'. Please run `make update` in the blender source folder to obtain them.")
endif()
+if(CMAKE_GENERATOR MATCHES "^Visual Studio.+" AND # Only supported in the VS IDE
+ MSVC_VERSION GREATER_EQUAL 1924 AND # Supported for 16.4+
+ WITH_CLANG_TIDY # And Clang Tidy needs to be on
+ )
+ set(CMAKE_VS_GLOBALS
+ "RunCodeAnalysis=false"
+ "EnableMicrosoftCodeAnalysis=false"
+ "EnableClangTidyCodeAnalysis=true"
+ )
+ set(VS_CLANG_TIDY On)
+endif()
+
# Mark libdir as system headers with a lower warn level, to resolve some warnings
# that we have very little control over
-if(MSVC_VERSION GREATER_EQUAL 1914 AND NOT MSVC_CLANG AND NOT WITH_WINDOWS_SCCACHE)
+if(MSVC_VERSION GREATER_EQUAL 1914 AND # Available with 15.7+
+ NOT MSVC_CLANG AND # But not for clang
+ NOT WITH_WINDOWS_SCCACHE AND # And not when sccache is enabled
+ NOT VS_CLANG_TIDY) # Clang-tidy does not like these options
add_compile_options(/experimental:external /external:templates- /external:I "${LIBDIR}" /external:W0)
endif()
diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile
index ca545eec4ca..772fac56f63 100644
--- a/doc/doxygen/Doxyfile
+++ b/doc/doxygen/Doxyfile
@@ -453,7 +453,7 @@ TYPEDEF_HIDES_STRUCT = NO
# the optimal cache size from a speed point of view.
# Minimum value: 0, maximum value: 9, default value: 0.
-LOOKUP_CACHE_SIZE = 0
+LOOKUP_CACHE_SIZE = 3
#---------------------------------------------------------------------------
# Build related configuration options
@@ -1321,7 +1321,7 @@ DOCSET_PUBLISHER_NAME = Publisher
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
-GENERATE_HTMLHELP = YES
+GENERATE_HTMLHELP = NO
# The CHM_FILE tag can be used to specify the file name of the resulting .chm
# file. You can add a path in front of the file if the result should not be
diff --git a/doc/python_api/examples/bpy.types.bpy_struct.is_property_set.py b/doc/python_api/examples/bpy.types.bpy_struct.is_property_set.py
new file mode 100644
index 00000000000..ed566fc3ea8
--- /dev/null
+++ b/doc/python_api/examples/bpy.types.bpy_struct.is_property_set.py
@@ -0,0 +1,30 @@
+"""
+.. note::
+
+ Properties defined at run-time store the values of the properties as custom-properties.
+
+ This method checks if the underlying data exists, causing the property to be considered *set*.
+
+ A common pattern for operators is to calculate a value for the properties
+ that have not had their values explicitly set by the caller
+ (where the caller could be a key-binding, menu-items or Python script for example).
+
+ In the case of executing operators multiple times, values are re-used from the previous execution.
+
+ For example: subdividing a mesh with a smooth value of 1.0 will keep using
+ that value on subsequent calls to subdivision, unless the operator is called with
+ that property set to a different value.
+
+ This behavior can be disabled using the ``SKIP_SAVE`` option when the property is declared (see: :mod:`bpy.props`).
+
+ The ``ghost`` argument allows detecting how a value from a previous execution is handled.
+
+ - When true: The property is considered unset even if the value from a previous call is used.
+ - When false: The existence of any values causes ``is_property_set`` to return true.
+
+ While this argument should typically be omitted, there are times when
+ it's important to know if a value is anything besides the default.
+
+ For example, the previous value may have been scaled by the scene's unit scale.
+ In this case scaling the value multiple times would cause problems, so the ``ghost`` argument should be false.
+"""
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index b148f4c6a46..930e5b88911 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -551,7 +551,7 @@ def example_extract_docstring(filepath):
file.close()
return "", 0
- for line in file.readlines():
+ for line in file:
line_no += 1
if line.startswith('"""'):
break
@@ -559,6 +559,13 @@ def example_extract_docstring(filepath):
text.append(line.rstrip())
line_no += 1
+
+ # Skip over blank lines so the Python code doesn't have blank lines at the top.
+ for line in file:
+ if line.strip():
+ break
+ line_no += 1
+
file.close()
return "\n".join(text), line_no
diff --git a/extern/audaspace/README.blender b/extern/audaspace/README.blender
new file mode 100644
index 00000000000..97c0dd8c768
--- /dev/null
+++ b/extern/audaspace/README.blender
@@ -0,0 +1,5 @@
+Project: Audaspace
+URL: https://audaspace.github.io/
+License: Apache 2.0
+Upstream version: 1.3 (Last Release)
+Local modifications: None
diff --git a/extern/bullet2/README.blender b/extern/bullet2/README.blender
new file mode 100644
index 00000000000..48b71fe06df
--- /dev/null
+++ b/extern/bullet2/README.blender
@@ -0,0 +1,5 @@
+Project: Bullet Continuous Collision Detection and Physics Library
+URL: http://bulletphysics.org
+License: zlib
+Upstream version: 3.07
+Local modifications: Fixed inertia
diff --git a/extern/ceres/README.blender b/extern/ceres/README.blender
index 0b6063c9703..20e5dda6f57 100644
--- a/extern/ceres/README.blender
+++ b/extern/ceres/README.blender
@@ -1,4 +1,5 @@
Project: Ceres Solver
URL: http://ceres-solver.org/
+License: BSD 3-Clause
Upstream version 2.0.0
Local modifications: None
diff --git a/extern/curve_fit_nd/README.blender b/extern/curve_fit_nd/README.blender
index db520ea524e..8e70fd796bb 100644
--- a/extern/curve_fit_nd/README.blender
+++ b/extern/curve_fit_nd/README.blender
@@ -1,5 +1,5 @@
Project: Curve-Fit-nD
URL: https://github.com/ideasman42/curve-fit-nd
License: BSD 3-Clause
-Upstream version: Unknown (Last Release)
+Upstream version: ddcd5bd (Last Release)
Local modifications: None
diff --git a/extern/draco/CMakeLists.txt b/extern/draco/CMakeLists.txt
index 6961fa8a769..d4cfeea4bee 100644
--- a/extern/draco/CMakeLists.txt
+++ b/extern/draco/CMakeLists.txt
@@ -19,20 +19,24 @@
# ***** END GPL LICENSE BLOCK *****
# Build Draco library.
-add_subdirectory(dracoenc)
+add_subdirectory(draco)
-# Build blender-draco-exporter module.
+# Build Draco-Blender bridging module.
set(SRC
- src/draco-compressor.cpp
- src/draco-compressor.h
+ src/common.cpp
+ src/common.h
+ src/decoder.cpp
+ src/decoder.h
+ src/encoder.cpp
+ src/encoder.h
)
set(INC
- dracoenc/src
+ draco/src
)
set(LIB
- dracoenc
+ draco
)
add_library(extern_draco SHARED "${SRC}")
diff --git a/extern/draco/README.blender b/extern/draco/README.blender
new file mode 100644
index 00000000000..b9c3bbb967d
--- /dev/null
+++ b/extern/draco/README.blender
@@ -0,0 +1,5 @@
+Project: Draco
+URL: https://google.github.io/draco/
+License: Apache 2.0
+Upstream version: 1.3.6
+Local modifications: None
diff --git a/extern/draco/dracoenc/AUTHORS b/extern/draco/draco/AUTHORS
index 67f63a67129..67f63a67129 100644
--- a/extern/draco/dracoenc/AUTHORS
+++ b/extern/draco/draco/AUTHORS
diff --git a/extern/draco/dracoenc/CMakeLists.txt b/extern/draco/draco/CMakeLists.txt
index 3d33bdb74c2..6f9ffce6b48 100644
--- a/extern/draco/dracoenc/CMakeLists.txt
+++ b/extern/draco/draco/CMakeLists.txt
@@ -2,103 +2,165 @@ remove_strict_flags()
set(SRC
src/draco/animation/keyframe_animation.cc
+ src/draco/animation/keyframe_animation.h
+ src/draco/animation/keyframe_animation_decoder.cc
+ src/draco/animation/keyframe_animation_decoder.h
src/draco/animation/keyframe_animation_encoder.cc
src/draco/animation/keyframe_animation_encoder.h
- src/draco/animation/keyframe_animation.h
src/draco/attributes/attribute_octahedron_transform.cc
src/draco/attributes/attribute_octahedron_transform.h
src/draco/attributes/attribute_quantization_transform.cc
src/draco/attributes/attribute_quantization_transform.h
src/draco/attributes/attribute_transform.cc
- src/draco/attributes/attribute_transform_data.h
src/draco/attributes/attribute_transform.h
+ src/draco/attributes/attribute_transform_data.h
src/draco/attributes/attribute_transform_type.h
src/draco/attributes/geometry_attribute.cc
src/draco/attributes/geometry_attribute.h
src/draco/attributes/geometry_indices.h
src/draco/attributes/point_attribute.cc
src/draco/attributes/point_attribute.h
+ src/draco/compression/attributes/attributes_decoder.cc
+ src/draco/compression/attributes/attributes_decoder.h
+ src/draco/compression/attributes/attributes_decoder_interface.h
src/draco/compression/attributes/attributes_encoder.cc
src/draco/compression/attributes/attributes_encoder.h
+ src/draco/compression/attributes/kd_tree_attributes_decoder.cc
+ src/draco/compression/attributes/kd_tree_attributes_decoder.h
src/draco/compression/attributes/kd_tree_attributes_encoder.cc
src/draco/compression/attributes/kd_tree_attributes_encoder.h
+ src/draco/compression/attributes/kd_tree_attributes_shared.h
src/draco/compression/attributes/linear_sequencer.h
+ src/draco/compression/attributes/mesh_attribute_indices_encoding_data.h
+ src/draco/compression/attributes/normal_compression_utils.h
+ src/draco/compression/attributes/point_d_vector.h
src/draco/compression/attributes/points_sequencer.h
+ src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h
+ src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h
+ src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h
+ src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h
+ src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h
+ src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h
+ src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h
+ src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h
+ src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h
+ src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h
+ src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h
+ src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h
+ src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h
- src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h
+ src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h
+ src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h
+ src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h
+ src/draco/compression/attributes/sequential_attribute_decoder.cc
+ src/draco/compression/attributes/sequential_attribute_decoder.h
+ src/draco/compression/attributes/sequential_attribute_decoders_controller.cc
+ src/draco/compression/attributes/sequential_attribute_decoders_controller.h
src/draco/compression/attributes/sequential_attribute_encoder.cc
src/draco/compression/attributes/sequential_attribute_encoder.h
src/draco/compression/attributes/sequential_attribute_encoders_controller.cc
src/draco/compression/attributes/sequential_attribute_encoders_controller.h
+ src/draco/compression/attributes/sequential_integer_attribute_decoder.cc
+ src/draco/compression/attributes/sequential_integer_attribute_decoder.h
src/draco/compression/attributes/sequential_integer_attribute_encoder.cc
src/draco/compression/attributes/sequential_integer_attribute_encoder.h
+ src/draco/compression/attributes/sequential_normal_attribute_decoder.cc
+ src/draco/compression/attributes/sequential_normal_attribute_decoder.h
src/draco/compression/attributes/sequential_normal_attribute_encoder.cc
src/draco/compression/attributes/sequential_normal_attribute_encoder.h
+ src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc
+ src/draco/compression/attributes/sequential_quantization_attribute_decoder.h
src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc
src/draco/compression/attributes/sequential_quantization_attribute_encoder.h
src/draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h
+ src/draco/compression/bit_coders/adaptive_rans_bit_decoder.cc
+ src/draco/compression/bit_coders/adaptive_rans_bit_decoder.h
src/draco/compression/bit_coders/adaptive_rans_bit_encoder.cc
src/draco/compression/bit_coders/adaptive_rans_bit_encoder.h
+ src/draco/compression/bit_coders/direct_bit_decoder.cc
+ src/draco/compression/bit_coders/direct_bit_decoder.h
src/draco/compression/bit_coders/direct_bit_encoder.cc
src/draco/compression/bit_coders/direct_bit_encoder.h
+ src/draco/compression/bit_coders/folded_integer_bit_decoder.h
src/draco/compression/bit_coders/folded_integer_bit_encoder.h
+ src/draco/compression/bit_coders/rans_bit_decoder.cc
+ src/draco/compression/bit_coders/rans_bit_decoder.h
src/draco/compression/bit_coders/rans_bit_encoder.cc
src/draco/compression/bit_coders/rans_bit_encoder.h
+ src/draco/compression/bit_coders/symbol_bit_decoder.cc
+ src/draco/compression/bit_coders/symbol_bit_decoder.h
src/draco/compression/bit_coders/symbol_bit_encoder.cc
src/draco/compression/bit_coders/symbol_bit_encoder.h
src/draco/compression/config/compression_shared.h
+ src/draco/compression/config/decoder_options.h
src/draco/compression/config/draco_options.h
src/draco/compression/config/encoder_options.h
src/draco/compression/config/encoding_features.h
- src/draco/compression/encode_base.h
+ src/draco/compression/decode.cc
+ src/draco/compression/decode.h
src/draco/compression/encode.cc
src/draco/compression/encode.h
+ src/draco/compression/encode_base.h
src/draco/compression/entropy/ans.h
src/draco/compression/entropy/rans_symbol_coding.h
+ src/draco/compression/entropy/rans_symbol_decoder.h
src/draco/compression/entropy/rans_symbol_encoder.h
src/draco/compression/entropy/shannon_entropy.cc
src/draco/compression/entropy/shannon_entropy.h
+ src/draco/compression/entropy/symbol_decoding.cc
+ src/draco/compression/entropy/symbol_decoding.h
src/draco/compression/entropy/symbol_encoding.cc
src/draco/compression/entropy/symbol_encoding.h
src/draco/compression/expert_encode.cc
src/draco/compression/expert_encode.h
+ src/draco/compression/mesh/mesh_decoder.cc
+ src/draco/compression/mesh/mesh_decoder.h
+ src/draco/compression/mesh/mesh_edgebreaker_decoder.cc
+ src/draco/compression/mesh/mesh_edgebreaker_decoder.h
+ src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc
+ src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h
+ src/draco/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h
src/draco/compression/mesh/mesh_edgebreaker_encoder.cc
src/draco/compression/mesh/mesh_edgebreaker_encoder.h
src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.cc
src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h
src/draco/compression/mesh/mesh_edgebreaker_encoder_impl_interface.h
src/draco/compression/mesh/mesh_edgebreaker_shared.h
+ src/draco/compression/mesh/mesh_edgebreaker_traversal_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_encoder.h
+ src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_encoder.h
+ src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_encoder.h
src/draco/compression/mesh/mesh_encoder.cc
src/draco/compression/mesh/mesh_encoder.h
- src/draco/compression/mesh/mesh_encoder_helpers.h
+ src/draco/compression/mesh/mesh_sequential_decoder.cc
+ src/draco/compression/mesh/mesh_sequential_decoder.h
src/draco/compression/mesh/mesh_sequential_encoder.cc
src/draco/compression/mesh/mesh_sequential_encoder.h
src/draco/compression/mesh/traverser/depth_first_traverser.h
@@ -106,18 +168,32 @@ set(SRC
src/draco/compression/mesh/traverser/mesh_attribute_indices_encoding_observer.h
src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h
src/draco/compression/mesh/traverser/traverser_base.h
+ src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.cc
+ src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h
src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.cc
src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h
+ src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.cc
+ src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.h
src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.cc
src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.h
+ src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.cc
+ src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.h
+ src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.cc
+ src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.h
src/draco/compression/point_cloud/algorithms/point_cloud_compression_method.h
src/draco/compression/point_cloud/algorithms/point_cloud_types.h
src/draco/compression/point_cloud/algorithms/quantize_points_3.h
src/draco/compression/point_cloud/algorithms/queuing_policy.h
+ src/draco/compression/point_cloud/point_cloud_decoder.cc
+ src/draco/compression/point_cloud/point_cloud_decoder.h
src/draco/compression/point_cloud/point_cloud_encoder.cc
src/draco/compression/point_cloud/point_cloud_encoder.h
+ src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.cc
+ src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.h
src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.cc
src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.h
+ src/draco/compression/point_cloud/point_cloud_sequential_decoder.cc
+ src/draco/compression/point_cloud/point_cloud_sequential_decoder.h
src/draco/compression/point_cloud/point_cloud_sequential_encoder.cc
src/draco/compression/point_cloud/point_cloud_sequential_encoder.h
src/draco/core/bit_utils.cc
@@ -128,12 +204,15 @@ set(SRC
src/draco/core/cycle_timer.h
src/draco/core/data_buffer.cc
src/draco/core/data_buffer.h
+ src/draco/core/decoder_buffer.cc
+ src/draco/core/decoder_buffer.h
src/draco/core/divide.cc
src/draco/core/divide.h
src/draco/core/draco_index_type.h
src/draco/core/draco_index_type_vector.h
src/draco/core/draco_types.cc
src/draco/core/draco_types.h
+ src/draco/core/draco_version.h
src/draco/core/encoder_buffer.cc
src/draco/core/encoder_buffer.h
src/draco/core/hash_utils.cc
@@ -145,20 +224,21 @@ set(SRC
src/draco/core/quantization_utils.cc
src/draco/core/quantization_utils.h
src/draco/core/status.h
- src/draco/core/statusor.h
+ src/draco/core/status_or.h
+ src/draco/core/varint_decoding.h
src/draco/core/varint_encoding.h
src/draco/core/vector_d.h
src/draco/mesh/corner_table.cc
src/draco/mesh/corner_table.h
src/draco/mesh/corner_table_iterators.h
+ src/draco/mesh/mesh.cc
+ src/draco/mesh/mesh.h
src/draco/mesh/mesh_are_equivalent.cc
src/draco/mesh/mesh_are_equivalent.h
src/draco/mesh/mesh_attribute_corner_table.cc
src/draco/mesh/mesh_attribute_corner_table.h
- src/draco/mesh/mesh.cc
src/draco/mesh/mesh_cleanup.cc
src/draco/mesh/mesh_cleanup.h
- src/draco/mesh/mesh.h
src/draco/mesh/mesh_misc_functions.cc
src/draco/mesh/mesh_misc_functions.h
src/draco/mesh/mesh_stripifier.cc
@@ -169,13 +249,15 @@ set(SRC
src/draco/metadata/geometry_metadata.cc
src/draco/metadata/geometry_metadata.h
src/draco/metadata/metadata.cc
+ src/draco/metadata/metadata.h
+ src/draco/metadata/metadata_decoder.cc
+ src/draco/metadata/metadata_decoder.h
src/draco/metadata/metadata_encoder.cc
src/draco/metadata/metadata_encoder.h
- src/draco/metadata/metadata.h
- src/draco/point_cloud/point_cloud_builder.cc
- src/draco/point_cloud/point_cloud_builder.h
src/draco/point_cloud/point_cloud.cc
src/draco/point_cloud/point_cloud.h
+ src/draco/point_cloud/point_cloud_builder.cc
+ src/draco/point_cloud/point_cloud_builder.h
)
set(LIB
@@ -185,4 +267,5 @@ set(INC
src
)
-blender_add_lib(dracoenc "${SRC}" "${INC}" "" "${LIB}")
+blender_add_lib(draco "${SRC}" "${INC}" "" "${LIB}")
+
diff --git a/extern/draco/dracoenc/LICENSE b/extern/draco/draco/LICENSE
index 7a4a3ea2424..7a4a3ea2424 100644
--- a/extern/draco/dracoenc/LICENSE
+++ b/extern/draco/draco/LICENSE
diff --git a/extern/draco/dracoenc/src/draco/animation/keyframe_animation.cc b/extern/draco/draco/src/draco/animation/keyframe_animation.cc
index 05ae3b1184e..eaf94a3305d 100644
--- a/extern/draco/dracoenc/src/draco/animation/keyframe_animation.cc
+++ b/extern/draco/draco/src/draco/animation/keyframe_animation.cc
@@ -29,8 +29,9 @@ bool KeyframeAnimation::SetTimestamps(
} else {
// Check if the number of frames is consistent with
// the existing keyframes.
- if (num_frames != num_points())
+ if (num_frames != num_points()) {
return false;
+ }
}
} else {
// This is the first attribute.
@@ -40,10 +41,8 @@ bool KeyframeAnimation::SetTimestamps(
// Add attribute for time stamp data.
std::unique_ptr<PointAttribute> timestamp_att =
std::unique_ptr<PointAttribute>(new PointAttribute());
- timestamp_att->Init(GeometryAttribute::GENERIC, nullptr, 1, DT_FLOAT32, false,
- sizeof(float), 0);
- timestamp_att->SetIdentityMapping();
- timestamp_att->Reset(num_frames);
+ timestamp_att->Init(GeometryAttribute::GENERIC, 1, DT_FLOAT32, false,
+ num_frames);
for (PointIndex i(0); i < num_frames; ++i) {
timestamp_att->SetAttributeValue(timestamp_att->mapped_index(i),
&timestamp[i.value()]);
diff --git a/extern/draco/dracoenc/src/draco/animation/keyframe_animation.h b/extern/draco/draco/src/draco/animation/keyframe_animation.h
index 0e8b111aaea..a7afb2b81be 100644
--- a/extern/draco/dracoenc/src/draco/animation/keyframe_animation.h
+++ b/extern/draco/draco/src/draco/animation/keyframe_animation.h
@@ -71,30 +71,29 @@ int32_t KeyframeAnimation::AddKeyframes(DataType data_type,
uint32_t num_components,
const std::vector<T> &data) {
// TODO(draco-eng): Verify T is consistent with |data_type|.
- if (num_components == 0)
+ if (num_components == 0) {
return -1;
+ }
// If timestamps is not added yet, then reserve attribute 0 for timestamps.
if (!num_attributes()) {
// Add a temporary attribute with 0 points to fill attribute id 0.
std::unique_ptr<PointAttribute> temp_att =
std::unique_ptr<PointAttribute>(new PointAttribute());
- temp_att->Init(GeometryAttribute::GENERIC, nullptr, num_components,
- data_type, false, DataTypeLength(data_type), 0);
- temp_att->Reset(0);
+ temp_att->Init(GeometryAttribute::GENERIC, num_components, data_type, false,
+ 0);
this->AddAttribute(std::move(temp_att));
set_num_frames(data.size() / num_components);
}
- if (data.size() != num_components * num_frames())
+ if (data.size() != num_components * num_frames()) {
return -1;
+ }
std::unique_ptr<PointAttribute> keyframe_att =
std::unique_ptr<PointAttribute>(new PointAttribute());
- keyframe_att->Init(GeometryAttribute::GENERIC, nullptr, num_components,
- data_type, false, DataTypeLength(data_type), 0);
- keyframe_att->SetIdentityMapping();
- keyframe_att->Reset(num_frames());
+ keyframe_att->Init(GeometryAttribute::GENERIC, num_components, data_type,
+ false, num_frames());
const size_t stride = num_components;
for (PointIndex i(0); i < num_frames(); ++i) {
keyframe_att->SetAttributeValue(keyframe_att->mapped_index(i),
diff --git a/extern/draco/dracoenc/src/draco/animation/keyframe_animation_decoder.cc b/extern/draco/draco/src/draco/animation/keyframe_animation_decoder.cc
index 8c0e71f62fa..20659468d94 100644
--- a/extern/draco/dracoenc/src/draco/animation/keyframe_animation_decoder.cc
+++ b/extern/draco/draco/src/draco/animation/keyframe_animation_decoder.cc
@@ -21,8 +21,9 @@ Status KeyframeAnimationDecoder::Decode(const DecoderOptions &options,
KeyframeAnimation *animation) {
const auto status = PointCloudSequentialDecoder::Decode(
options, in_buffer, static_cast<PointCloud *>(animation));
- if (!status.ok())
+ if (!status.ok()) {
return status;
+ }
return OkStatus();
}
diff --git a/extern/draco/dracoenc/src/draco/animation/keyframe_animation_decoder.h b/extern/draco/draco/src/draco/animation/keyframe_animation_decoder.h
index fdf086b3a38..fdf086b3a38 100644
--- a/extern/draco/dracoenc/src/draco/animation/keyframe_animation_decoder.h
+++ b/extern/draco/draco/src/draco/animation/keyframe_animation_decoder.h
diff --git a/extern/draco/dracoenc/src/draco/animation/keyframe_animation_encoder.cc b/extern/draco/draco/src/draco/animation/keyframe_animation_encoder.cc
index f7d84f3106a..f7d84f3106a 100644
--- a/extern/draco/dracoenc/src/draco/animation/keyframe_animation_encoder.cc
+++ b/extern/draco/draco/src/draco/animation/keyframe_animation_encoder.cc
diff --git a/extern/draco/dracoenc/src/draco/animation/keyframe_animation_encoder.h b/extern/draco/draco/src/draco/animation/keyframe_animation_encoder.h
index 6096c79fa12..6096c79fa12 100644
--- a/extern/draco/dracoenc/src/draco/animation/keyframe_animation_encoder.h
+++ b/extern/draco/draco/src/draco/animation/keyframe_animation_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/attributes/attribute_octahedron_transform.cc b/extern/draco/draco/src/draco/attributes/attribute_octahedron_transform.cc
index e1180a48dda..283a21251f4 100644
--- a/extern/draco/dracoenc/src/draco/attributes/attribute_octahedron_transform.cc
+++ b/extern/draco/draco/src/draco/attributes/attribute_octahedron_transform.cc
@@ -25,8 +25,9 @@ bool AttributeOctahedronTransform::InitFromAttribute(
const AttributeTransformData *const transform_data =
attribute.GetAttributeTransformData();
if (!transform_data ||
- transform_data->transform_type() != ATTRIBUTE_OCTAHEDRON_TRANSFORM)
+ transform_data->transform_type() != ATTRIBUTE_OCTAHEDRON_TRANSFORM) {
return false; // Wrong transform type.
+ }
quantization_bits_ = transform_data->GetParameterValue<int32_t>(0);
return true;
}
@@ -68,8 +69,9 @@ AttributeOctahedronTransform::GeneratePortableAttribute(
float att_val[3];
int32_t dst_index = 0;
OctahedronToolBox converter;
- if (!converter.SetQuantizationBits(quantization_bits_))
+ if (!converter.SetQuantizationBits(quantization_bits_)) {
return nullptr;
+ }
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);
diff --git a/extern/draco/dracoenc/src/draco/attributes/attribute_octahedron_transform.h b/extern/draco/draco/src/draco/attributes/attribute_octahedron_transform.h
index 6e4e74284f0..6e4e74284f0 100644
--- a/extern/draco/dracoenc/src/draco/attributes/attribute_octahedron_transform.h
+++ b/extern/draco/draco/src/draco/attributes/attribute_octahedron_transform.h
diff --git a/extern/draco/dracoenc/src/draco/attributes/attribute_quantization_transform.cc b/extern/draco/draco/src/draco/attributes/attribute_quantization_transform.cc
index 237becefc61..daa634ed03f 100644
--- a/extern/draco/dracoenc/src/draco/attributes/attribute_quantization_transform.cc
+++ b/extern/draco/draco/src/draco/attributes/attribute_quantization_transform.cc
@@ -25,8 +25,9 @@ bool AttributeQuantizationTransform::InitFromAttribute(
const AttributeTransformData *const transform_data =
attribute.GetAttributeTransformData();
if (!transform_data ||
- transform_data->transform_type() != ATTRIBUTE_QUANTIZATION_TRANSFORM)
+ transform_data->transform_type() != ATTRIBUTE_QUANTIZATION_TRANSFORM) {
return false; // Wrong transform type.
+ }
int32_t byte_offset = 0;
quantization_bits_ = transform_data->GetParameterValue<int32_t>(byte_offset);
byte_offset += 4;
@@ -80,22 +81,30 @@ bool AttributeQuantizationTransform::ComputeParameters(
++i) {
attribute.GetValue(i, att_val.get());
for (int c = 0; c < num_components; ++c) {
- if (min_values_[c] > att_val[c])
+ if (min_values_[c] > att_val[c]) {
min_values_[c] = att_val[c];
- if (max_values[c] < att_val[c])
+ }
+ if (max_values[c] < att_val[c]) {
max_values[c] = att_val[c];
+ }
}
}
for (int c = 0; c < num_components; ++c) {
+ if (std::isnan(min_values_[c]) || std::isinf(min_values_[c]) ||
+ std::isnan(max_values[c]) || std::isinf(max_values[c])) {
+ return false;
+ }
const float dif = max_values[c] - min_values_[c];
- if (dif > range_)
+ if (dif > range_) {
range_ = dif;
+ }
}
// In case all values are the same, initialize the range to unit length. This
// will ensure that all values are quantized properly to the same value.
- if (range_ == 0.f)
+ if (range_ == 0.f) {
range_ = 1.f;
+ }
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/attributes/attribute_quantization_transform.h b/extern/draco/draco/src/draco/attributes/attribute_quantization_transform.h
index 934856f2db7..934856f2db7 100644
--- a/extern/draco/dracoenc/src/draco/attributes/attribute_quantization_transform.h
+++ b/extern/draco/draco/src/draco/attributes/attribute_quantization_transform.h
diff --git a/extern/draco/dracoenc/src/draco/attributes/attribute_transform.cc b/extern/draco/draco/src/draco/attributes/attribute_transform.cc
index 55af630ac07..55af630ac07 100644
--- a/extern/draco/dracoenc/src/draco/attributes/attribute_transform.cc
+++ b/extern/draco/draco/src/draco/attributes/attribute_transform.cc
diff --git a/extern/draco/dracoenc/src/draco/attributes/attribute_transform.h b/extern/draco/draco/src/draco/attributes/attribute_transform.h
index d746fbf6eea..d746fbf6eea 100644
--- a/extern/draco/dracoenc/src/draco/attributes/attribute_transform.h
+++ b/extern/draco/draco/src/draco/attributes/attribute_transform.h
diff --git a/extern/draco/dracoenc/src/draco/attributes/attribute_transform_data.h b/extern/draco/draco/src/draco/attributes/attribute_transform_data.h
index 96ed073200d..96ed073200d 100644
--- a/extern/draco/dracoenc/src/draco/attributes/attribute_transform_data.h
+++ b/extern/draco/draco/src/draco/attributes/attribute_transform_data.h
diff --git a/extern/draco/dracoenc/src/draco/attributes/attribute_transform_type.h b/extern/draco/draco/src/draco/attributes/attribute_transform_type.h
index 51ce6f333b4..51ce6f333b4 100644
--- a/extern/draco/dracoenc/src/draco/attributes/attribute_transform_type.h
+++ b/extern/draco/draco/src/draco/attributes/attribute_transform_type.h
diff --git a/extern/draco/dracoenc/src/draco/attributes/geometry_attribute.cc b/extern/draco/draco/src/draco/attributes/geometry_attribute.cc
index 914a85d9dc2..f7ed6a86915 100644
--- a/extern/draco/dracoenc/src/draco/attributes/geometry_attribute.cc
+++ b/extern/draco/draco/src/draco/attributes/geometry_attribute.cc
@@ -14,8 +14,6 @@
//
#include "draco/attributes/geometry_attribute.h"
-using std::array;
-
namespace draco {
GeometryAttribute::GeometryAttribute()
@@ -45,8 +43,9 @@ void GeometryAttribute::Init(GeometryAttribute::Type attribute_type,
}
bool GeometryAttribute::CopyFrom(const GeometryAttribute &src_att) {
- if (buffer_ == nullptr || src_att.buffer_ == nullptr)
+ 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_;
@@ -55,27 +54,35 @@ bool GeometryAttribute::CopyFrom(const GeometryAttribute &src_att) {
byte_offset_ = src_att.byte_offset_;
attribute_type_ = src_att.attribute_type_;
buffer_descriptor_ = src_att.buffer_descriptor_;
+ unique_id_ = src_att.unique_id_;
return true;
}
bool GeometryAttribute::operator==(const GeometryAttribute &va) const {
- if (attribute_type_ != va.attribute_type_)
+ if (attribute_type_ != va.attribute_type_) {
return false;
+ }
// It's OK to compare just the buffer descriptors here. We don't need to
// compare the buffers themselves.
- if (buffer_descriptor_.buffer_id != va.buffer_descriptor_.buffer_id)
+ if (buffer_descriptor_.buffer_id != va.buffer_descriptor_.buffer_id) {
return false;
+ }
if (buffer_descriptor_.buffer_update_count !=
- va.buffer_descriptor_.buffer_update_count)
+ va.buffer_descriptor_.buffer_update_count) {
return false;
- if (num_components_ != va.num_components_)
+ }
+ if (num_components_ != va.num_components_) {
return false;
- if (data_type_ != va.data_type_)
+ }
+ if (data_type_ != va.data_type_) {
return false;
- if (byte_stride_ != va.byte_stride_)
+ }
+ if (byte_stride_ != va.byte_stride_) {
return false;
- if (byte_offset_ != va.byte_offset_)
+ }
+ if (byte_offset_ != va.byte_offset_) {
return false;
+ }
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/attributes/geometry_attribute.h b/extern/draco/draco/src/draco/attributes/geometry_attribute.h
index 7be40fe2f65..b94ba8e22dd 100644
--- a/extern/draco/dracoenc/src/draco/attributes/geometry_attribute.h
+++ b/extern/draco/draco/src/draco/attributes/geometry_attribute.h
@@ -91,8 +91,9 @@ class GeometryAttribute {
// Byte address of the attribute index.
const int64_t byte_pos = byte_offset_ + byte_stride_ * att_index.value();
// Check we are not reading past end of data.
- if (byte_pos + sizeof(*out) > buffer_->data_size())
+ if (byte_pos + sizeof(*out) > buffer_->data_size()) {
return false;
+ }
buffer_->Read(byte_pos, &((*out)[0]), sizeof(*out));
return true;
}
@@ -118,6 +119,13 @@ class GeometryAttribute {
buffer_->Read(byte_pos, out_data, byte_stride_);
}
+ // Sets a value of an attribute entry. The input value must be allocated to
+ // cover all components of a single attribute entry.
+ void SetAttributeValue(AttributeValueIndex entry_index, const void *value) {
+ const int64_t byte_pos = entry_index.value() * byte_stride();
+ buffer_->Write(byte_pos, value, byte_stride());
+ }
+
// DEPRECATED: Use
// ConvertValue(AttributeValueIndex att_id,
// int out_num_components,
@@ -139,8 +147,9 @@ class GeometryAttribute {
template <typename OutT>
bool ConvertValue(AttributeValueIndex att_id, int8_t out_num_components,
OutT *out_val) const {
- if (out_val == nullptr)
+ if (out_val == nullptr) {
return false;
+ }
switch (data_type_) {
case DT_INT8:
return ConvertTypedValue<int8_t, OutT>(att_id, out_num_components,
@@ -191,6 +200,26 @@ class GeometryAttribute {
return ConvertValue<OutT>(att_index, num_components_, out_value);
}
+ // Utility function. Returns |attribute_type| as std::string.
+ static std::string TypeToString(Type attribute_type) {
+ switch (attribute_type) {
+ case INVALID:
+ return "INVALID";
+ case POSITION:
+ return "POSITION";
+ case NORMAL:
+ return "NORMAL";
+ case COLOR:
+ return "COLOR";
+ case TEX_COORD:
+ return "TEX_COORD";
+ case GENERIC:
+ return "GENERIC";
+ default:
+ return "UNKNOWN";
+ }
+ }
+
bool operator==(const GeometryAttribute &va) const;
// Returns the type of the attribute indicating the nature of the attribute.
@@ -285,8 +314,8 @@ struct GeometryAttributeHasher {
size_t hash = HashCombine(va.buffer_descriptor_.buffer_id,
va.buffer_descriptor_.buffer_update_count);
hash = HashCombine(va.num_components_, hash);
- hash = HashCombine((int8_t)va.data_type_, hash);
- hash = HashCombine((int8_t)va.attribute_type_, hash);
+ hash = HashCombine(static_cast<int8_t>(va.data_type_), hash);
+ hash = HashCombine(static_cast<int8_t>(va.attribute_type_), hash);
hash = HashCombine(va.byte_stride_, hash);
return HashCombine(va.byte_offset_, hash);
}
diff --git a/extern/draco/dracoenc/src/draco/attributes/geometry_indices.h b/extern/draco/draco/src/draco/attributes/geometry_indices.h
index 80e43e30a13..80e43e30a13 100644
--- a/extern/draco/dracoenc/src/draco/attributes/geometry_indices.h
+++ b/extern/draco/draco/src/draco/attributes/geometry_indices.h
diff --git a/extern/draco/dracoenc/src/draco/attributes/point_attribute.cc b/extern/draco/draco/src/draco/attributes/point_attribute.cc
index 0c4e8e1c738..b28f860c15d 100644
--- a/extern/draco/dracoenc/src/draco/attributes/point_attribute.cc
+++ b/extern/draco/draco/src/draco/attributes/point_attribute.cc
@@ -32,20 +32,32 @@ PointAttribute::PointAttribute(const GeometryAttribute &att)
num_unique_entries_(0),
identity_mapping_(false) {}
+void PointAttribute::Init(Type attribute_type, int8_t num_components,
+ DataType data_type, bool normalized,
+ size_t num_attribute_values) {
+ attribute_buffer_ = std::unique_ptr<DataBuffer>(new DataBuffer());
+ GeometryAttribute::Init(attribute_type, attribute_buffer_.get(),
+ num_components, data_type, normalized,
+ DataTypeLength(data_type) * num_components, 0);
+ Reset(num_attribute_values);
+ SetIdentityMapping();
+}
+
void PointAttribute::CopyFrom(const PointAttribute &src_att) {
if (buffer() == nullptr) {
// If the destination attribute doesn't have a valid buffer, create it.
attribute_buffer_ = std::unique_ptr<DataBuffer>(new DataBuffer());
ResetBuffer(attribute_buffer_.get(), 0, 0);
}
- if (!GeometryAttribute::CopyFrom(src_att))
+ if (!GeometryAttribute::CopyFrom(src_att)) {
return;
+ }
identity_mapping_ = src_att.identity_mapping_;
num_unique_entries_ = src_att.num_unique_entries_;
indices_map_ = src_att.indices_map_;
if (src_att.attribute_transform_data_) {
attribute_transform_data_ = std::unique_ptr<AttributeTransformData>(
- new AttributeTransformData(*src_att.attribute_transform_data_.get()));
+ new AttributeTransformData(*src_att.attribute_transform_data_));
} else {
attribute_transform_data_ = nullptr;
}
@@ -56,14 +68,20 @@ bool PointAttribute::Reset(size_t num_attribute_values) {
attribute_buffer_ = std::unique_ptr<DataBuffer>(new DataBuffer());
}
const int64_t entry_size = DataTypeLength(data_type()) * num_components();
- if (!attribute_buffer_->Update(nullptr, num_attribute_values * entry_size))
+ if (!attribute_buffer_->Update(nullptr, num_attribute_values * entry_size)) {
return false;
+ }
// Assign the new buffer to the parent attribute.
ResetBuffer(attribute_buffer_.get(), entry_size, 0);
num_unique_entries_ = static_cast<uint32_t>(num_attribute_values);
return true;
}
+void PointAttribute::Resize(size_t new_num_unique_entries) {
+ num_unique_entries_ = static_cast<uint32_t>(new_num_unique_entries);
+ attribute_buffer_->Resize(new_num_unique_entries * byte_stride());
+}
+
#ifdef DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED
AttributeValueIndex::ValueType PointAttribute::DeduplicateValues(
const GeometryAttribute &in_att) {
@@ -100,8 +118,9 @@ AttributeValueIndex::ValueType PointAttribute::DeduplicateValues(
default:
return -1; // Unsupported data type.
}
- if (unique_vals == 0)
+ if (unique_vals == 0) {
return -1; // Unexpected error.
+ }
return unique_vals;
}
@@ -181,8 +200,9 @@ AttributeValueIndex::ValueType PointAttribute::DeduplicateFormattedValues(
++unique_vals;
}
}
- if (unique_vals == num_unique_entries_)
+ if (unique_vals == num_unique_entries_) {
return unique_vals.value(); // Nothing has changed.
+ }
if (is_mapping_identity()) {
// Change identity mapping to the explicit one.
// The number of points is equal to the number of old unique values.
diff --git a/extern/draco/dracoenc/src/draco/attributes/point_attribute.h b/extern/draco/draco/src/draco/attributes/point_attribute.h
index 46e58a40aa1..ee36620313e 100644
--- a/extern/draco/dracoenc/src/draco/attributes/point_attribute.h
+++ b/extern/draco/draco/src/draco/attributes/point_attribute.h
@@ -17,13 +17,12 @@
#include <memory>
-#include "draco/draco_features.h"
-
#include "draco/attributes/attribute_transform_data.h"
#include "draco/attributes/geometry_attribute.h"
#include "draco/core/draco_index_type_vector.h"
#include "draco/core/hash_utils.h"
#include "draco/core/macros.h"
+#include "draco/draco_features.h"
namespace draco {
@@ -41,6 +40,12 @@ class PointAttribute : public GeometryAttribute {
PointAttribute(PointAttribute &&attribute) = default;
PointAttribute &operator=(PointAttribute &&attribute) = default;
+ // Initializes a point attribute. By default the attribute will be set to
+ // identity mapping between point indices and attribute values. To set custom
+ // mapping use SetExplicitMapping() function.
+ void Init(Type attribute_type, int8_t num_components, DataType data_type,
+ bool normalized, size_t num_attribute_values);
+
// Copies attribute data from the provided |src_att| attribute.
void CopyFrom(const PointAttribute &src_att);
@@ -49,15 +54,17 @@ class PointAttribute : public GeometryAttribute {
size_t size() const { return num_unique_entries_; }
AttributeValueIndex mapped_index(PointIndex point_index) const {
- if (identity_mapping_)
+ if (identity_mapping_) {
return AttributeValueIndex(point_index.value());
+ }
return indices_map_[point_index];
}
DataBuffer *buffer() const { return attribute_buffer_.get(); }
bool is_mapping_identity() const { return identity_mapping_; }
size_t indices_map_size() const {
- if (is_mapping_identity())
+ if (is_mapping_identity()) {
return 0;
+ }
return indices_map_.size();
}
@@ -65,10 +72,14 @@ class PointAttribute : public GeometryAttribute {
return GetAddress(mapped_index(point_index));
}
- // Sets the new number of unique attribute entries for the attribute.
- void Resize(size_t new_num_unique_entries) {
- num_unique_entries_ = static_cast<uint32_t>(new_num_unique_entries);
- }
+ // Sets the new number of unique attribute entries for the attribute. The
+ // function resizes the attribute storage to hold |num_attribute_values|
+ // entries.
+ // All previous entries with AttributeValueIndex < |num_attribute_values|
+ // are preserved. Caller needs to ensure that the PointAttribute is still
+ // valid after the resizing operation (that is, each point is mapped to a
+ // valid attribute value).
+ void Resize(size_t new_num_unique_entries);
// Functions for setting the type of mapping between point indices and
// attribute entry ids.
@@ -92,13 +103,6 @@ class PointAttribute : public GeometryAttribute {
indices_map_[point_index] = entry_index;
}
- // Sets a value of an attribute entry. The input value must be allocated to
- // cover all components of a single attribute entry.
- void SetAttributeValue(AttributeValueIndex entry_index, const void *value) {
- const int64_t byte_pos = entry_index.value() * byte_stride();
- buffer()->Write(byte_pos, value, byte_stride());
- }
-
// Same as GeometryAttribute::GetValue(), but using point id as the input.
// Mapping to attribute value index is performed automatically.
void GetMappedValue(PointIndex point_index, void *out_data) const {
@@ -165,7 +169,7 @@ struct PointAttributeHasher {
hash = HashCombine(attribute.identity_mapping_, hash);
hash = HashCombine(attribute.num_unique_entries_, hash);
hash = HashCombine(attribute.indices_map_.size(), hash);
- if (attribute.indices_map_.size() > 0) {
+ if (!attribute.indices_map_.empty()) {
const uint64_t indices_hash = FingerprintString(
reinterpret_cast<const char *>(attribute.indices_map_.data()),
attribute.indices_map_.size());
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/attributes_decoder.cc b/extern/draco/draco/src/draco/compression/attributes/attributes_decoder.cc
index eb42edea06a..ce5b8b9c756 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/attributes_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/attributes_decoder.cc
@@ -33,31 +33,42 @@ bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) {
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (point_cloud_decoder_->bitstream_version() <
DRACO_BITSTREAM_VERSION(2, 0)) {
- if (!in_buffer->Decode(&num_attributes))
+ if (!in_buffer->Decode(&num_attributes)) {
return false;
+ }
} else
#endif
{
- if (!DecodeVarint(&num_attributes, in_buffer))
+ if (!DecodeVarint(&num_attributes, in_buffer)) {
return false;
+ }
}
- if (num_attributes == 0)
+ if (num_attributes == 0) {
return false;
+ }
point_attribute_ids_.resize(num_attributes);
PointCloud *pc = point_cloud_;
for (uint32_t i = 0; i < num_attributes; ++i) {
// Decode attribute descriptor data.
uint8_t att_type, data_type, num_components, normalized;
- if (!in_buffer->Decode(&att_type))
+ if (!in_buffer->Decode(&att_type)) {
return false;
- if (!in_buffer->Decode(&data_type))
+ }
+ if (!in_buffer->Decode(&data_type)) {
return false;
- if (!in_buffer->Decode(&num_components))
+ }
+ if (!in_buffer->Decode(&num_components)) {
return false;
- if (!in_buffer->Decode(&normalized))
+ }
+ if (!in_buffer->Decode(&normalized)) {
return false;
- if (data_type <= DT_INVALID || data_type >= DT_TYPES_COUNT)
+ }
+ if (att_type >= GeometryAttribute::NAMED_ATTRIBUTES_COUNT) {
+ return false;
+ }
+ 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
@@ -70,8 +81,9 @@ bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) {
if (point_cloud_decoder_->bitstream_version() <
DRACO_BITSTREAM_VERSION(1, 3)) {
uint16_t custom_id;
- if (!in_buffer->Decode(&custom_id))
+ if (!in_buffer->Decode(&custom_id)) {
return false;
+ }
// TODO(draco-eng): Add "custom_id" to attribute metadata.
unique_id = static_cast<uint32_t>(custom_id);
ga.set_unique_id(unique_id);
@@ -87,8 +99,10 @@ bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) {
point_attribute_ids_[i] = att_id;
// Update the inverse map.
- if (att_id >= static_cast<int32_t>(point_attribute_to_local_id_map_.size()))
+ if (att_id >=
+ static_cast<int32_t>(point_attribute_to_local_id_map_.size())) {
point_attribute_to_local_id_map_.resize(att_id + 1, -1);
+ }
point_attribute_to_local_id_map_[att_id] = i;
}
return true;
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/attributes_decoder.h b/extern/draco/draco/src/draco/compression/attributes/attributes_decoder.h
index 9c6e9fe5e4d..5b2bb2cfeb2 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/attributes_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/attributes_decoder.h
@@ -17,11 +17,10 @@
#include <vector>
-#include "draco/draco_features.h"
-
#include "draco/compression/attributes/attributes_decoder_interface.h"
#include "draco/compression/point_cloud/point_cloud_decoder.h"
#include "draco/core/decoder_buffer.h"
+#include "draco/draco_features.h"
#include "draco/point_cloud/point_cloud.h"
namespace draco {
@@ -54,12 +53,15 @@ class AttributesDecoder : public AttributesDecoderInterface {
// Decodes attribute data from the source buffer.
bool DecodeAttributes(DecoderBuffer *in_buffer) override {
- if (!DecodePortableAttributes(in_buffer))
+ if (!DecodePortableAttributes(in_buffer)) {
return false;
- if (!DecodeDataNeededByPortableTransforms(in_buffer))
+ }
+ if (!DecodeDataNeededByPortableTransforms(in_buffer)) {
return false;
- if (!TransformAttributesToOriginalFormat())
+ }
+ if (!TransformAttributesToOriginalFormat()) {
return false;
+ }
return true;
}
@@ -67,8 +69,9 @@ class AttributesDecoder : public AttributesDecoderInterface {
int32_t GetLocalIdForPointAttribute(int32_t point_attribute_id) const {
const int id_map_size =
static_cast<int>(point_attribute_to_local_id_map_.size());
- if (point_attribute_id >= id_map_size)
+ if (point_attribute_id >= id_map_size) {
return -1;
+ }
return point_attribute_to_local_id_map_[point_attribute_id];
}
virtual bool DecodePortableAttributes(DecoderBuffer *in_buffer) = 0;
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/attributes_decoder_interface.h b/extern/draco/draco/src/draco/compression/attributes/attributes_decoder_interface.h
index 8e5cf52ac3b..8e5cf52ac3b 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/attributes_decoder_interface.h
+++ b/extern/draco/draco/src/draco/compression/attributes/attributes_decoder_interface.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/attributes_encoder.cc b/extern/draco/draco/src/draco/compression/attributes/attributes_encoder.cc
index 797c62f30aa..797c62f30aa 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/attributes_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/attributes_encoder.cc
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/attributes_encoder.h b/extern/draco/draco/src/draco/compression/attributes/attributes_encoder.h
index 09d10109803..9de846ae6d4 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/attributes_encoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/attributes_encoder.h
@@ -48,15 +48,18 @@ class AttributesEncoder {
// Encode attribute data to the target buffer.
virtual bool EncodeAttributes(EncoderBuffer *out_buffer) {
- if (!TransformAttributesToPortableFormat())
+ if (!TransformAttributesToPortableFormat()) {
return false;
- if (!EncodePortableAttributes(out_buffer))
+ }
+ if (!EncodePortableAttributes(out_buffer)) {
return false;
+ }
// Encode data needed by portable transforms after the attribute is encoded.
// This corresponds to the order in which the data is going to be decoded by
// the decoder.
- if (!EncodeDataNeededByPortableTransforms(out_buffer))
+ if (!EncodeDataNeededByPortableTransforms(out_buffer)) {
return false;
+ }
return true;
}
@@ -87,8 +90,9 @@ class AttributesEncoder {
void AddAttributeId(int32_t id) {
point_attribute_ids_.push_back(id);
- if (id >= static_cast<int32_t>(point_attribute_to_local_id_map_.size()))
+ if (id >= static_cast<int32_t>(point_attribute_to_local_id_map_.size())) {
point_attribute_to_local_id_map_.resize(id + 1, -1);
+ }
point_attribute_to_local_id_map_[id] =
static_cast<int32_t>(point_attribute_ids_.size()) - 1;
}
@@ -127,8 +131,9 @@ class AttributesEncoder {
int32_t GetLocalIdForPointAttribute(int32_t point_attribute_id) const {
const int id_map_size =
static_cast<int>(point_attribute_to_local_id_map_.size());
- if (point_attribute_id >= id_map_size)
+ if (point_attribute_id >= id_map_size) {
return -1;
+ }
return point_attribute_to_local_id_map_[point_attribute_id];
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/kd_tree_attributes_decoder.cc b/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.cc
index 4faa8ab29b5..99469f94590 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/kd_tree_attributes_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.cc
@@ -13,6 +13,7 @@
// limitations under the License.
//
#include "draco/compression/attributes/kd_tree_attributes_decoder.h"
+
#include "draco/compression/attributes/kd_tree_attributes_shared.h"
#include "draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h"
#include "draco/compression/point_cloud/algorithms/float_points_tree_decoder.h"
@@ -92,7 +93,7 @@ class PointAttributeVectorOutputIterator {
const uint32_t &data_size = std::get<3>(att);
const uint32_t &num_components = std::get<4>(att);
const uint32_t *data_source = val.data() + offset;
- if (data_size != 4) { // handle uint16_t, uint8_t
+ if (data_size < 4) { // handle uint16_t, uint8_t
// selectively copy data bytes
uint8_t *data_counter = data_;
for (uint32_t index = 0; index < num_components;
@@ -103,8 +104,9 @@ class PointAttributeVectorOutputIterator {
data_source = reinterpret_cast<uint32_t *>(data_);
}
const AttributeValueIndex avi = attribute->mapped_index(point_id_);
- if (avi >= static_cast<uint32_t>(attribute->size()))
+ if (avi >= static_cast<uint32_t>(attribute->size())) {
return *this;
+ }
attribute->SetAttributeValue(avi, data_source);
}
return *this;
@@ -134,8 +136,9 @@ bool KdTreeAttributesDecoder::DecodePortableAttributes(
return true;
}
uint8_t compression_level = 0;
- if (!in_buffer->Decode(&compression_level))
+ if (!in_buffer->Decode(&compression_level)) {
return false;
+ }
const int32_t num_points = GetDecoder()->point_cloud()->num_points();
// Decode data using the kd tree decoding into integer (portable) attributes.
@@ -197,44 +200,51 @@ bool KdTreeAttributesDecoder::DecodePortableAttributes(
switch (compression_level) {
case 0: {
DynamicIntegerPointsKdTreeDecoder<0> decoder(total_dimensionality);
- if (!decoder.DecodePoints(in_buffer, out_it))
+ if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
+ }
break;
}
case 1: {
DynamicIntegerPointsKdTreeDecoder<1> decoder(total_dimensionality);
- if (!decoder.DecodePoints(in_buffer, out_it))
+ if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
+ }
break;
}
case 2: {
DynamicIntegerPointsKdTreeDecoder<2> decoder(total_dimensionality);
- if (!decoder.DecodePoints(in_buffer, out_it))
+ if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
+ }
break;
}
case 3: {
DynamicIntegerPointsKdTreeDecoder<3> decoder(total_dimensionality);
- if (!decoder.DecodePoints(in_buffer, out_it))
+ if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
+ }
break;
}
case 4: {
DynamicIntegerPointsKdTreeDecoder<4> decoder(total_dimensionality);
- if (!decoder.DecodePoints(in_buffer, out_it))
+ if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
+ }
break;
}
case 5: {
DynamicIntegerPointsKdTreeDecoder<5> decoder(total_dimensionality);
- if (!decoder.DecodePoints(in_buffer, out_it))
+ if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
+ }
break;
}
case 6: {
DynamicIntegerPointsKdTreeDecoder<6> decoder(total_dimensionality);
- if (!decoder.DecodePoints(in_buffer, out_it))
+ if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
+ }
break;
}
default:
@@ -256,22 +266,26 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
if (att->data_type() == DT_FLOAT32) {
const int num_components = att->num_components();
min_value.resize(num_components);
- if (!in_buffer->Decode(&min_value[0], sizeof(float) * num_components))
+ if (!in_buffer->Decode(&min_value[0], sizeof(float) * num_components)) {
return false;
+ }
float max_value_dif;
- if (!in_buffer->Decode(&max_value_dif))
+ if (!in_buffer->Decode(&max_value_dif)) {
return false;
+ }
uint8_t quantization_bits;
- if (!in_buffer->Decode(&quantization_bits) || quantization_bits > 31)
+ if (!in_buffer->Decode(&quantization_bits) || quantization_bits > 31) {
return false;
+ }
AttributeQuantizationTransform transform;
transform.SetParameters(quantization_bits, min_value.data(),
num_components, max_value_dif);
const int num_transforms =
static_cast<int>(attribute_quantization_transforms_.size());
if (!transform.TransferToAttribute(
- quantized_portable_attributes_[num_transforms].get()))
+ quantized_portable_attributes_[num_transforms].get())) {
return false;
+ }
attribute_quantization_transforms_.push_back(transform);
}
}
@@ -299,6 +313,10 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
const DataType data_type = att->data_type();
const uint32_t data_size = (std::max)(0, DataTypeLength(data_type));
const uint32_t num_components = att->num_components();
+ if (data_size > 4) {
+ return false;
+ }
+
atts[attribute_index] = std::make_tuple(
att, total_dimensionality, data_type, data_size, num_components);
// everything is treated as 32bit in the encoder.
@@ -310,24 +328,30 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
att->SetIdentityMapping();
// Decode method
uint8_t method;
- if (!in_buffer->Decode(&method))
+ if (!in_buffer->Decode(&method)) {
return false;
+ }
if (method == KdTreeAttributesEncodingMethod::kKdTreeQuantizationEncoding) {
uint8_t compression_level = 0;
- if (!in_buffer->Decode(&compression_level))
+ if (!in_buffer->Decode(&compression_level)) {
return false;
+ }
uint32_t num_points = 0;
- if (!in_buffer->Decode(&num_points))
+ if (!in_buffer->Decode(&num_points)) {
return false;
+ }
att->Reset(num_points);
FloatPointsTreeDecoder decoder;
+ decoder.set_num_points_from_header(num_points);
PointAttributeVectorOutputIterator<float> out_it(atts);
- if (!decoder.DecodePointCloud(in_buffer, out_it))
+ if (!decoder.DecodePointCloud(in_buffer, out_it)) {
return false;
+ }
} else if (method == KdTreeAttributesEncodingMethod::kKdTreeIntegerEncoding) {
uint8_t compression_level = 0;
- if (!in_buffer->Decode(&compression_level))
+ if (!in_buffer->Decode(&compression_level)) {
return false;
+ }
if (6 < compression_level) {
LOGE("KdTreeAttributesDecoder: compression level %i not supported.\n",
compression_level);
@@ -335,8 +359,9 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
}
uint32_t num_points;
- if (!in_buffer->Decode(&num_points))
+ if (!in_buffer->Decode(&num_points)) {
return false;
+ }
for (auto attribute_index = 0;
static_cast<uint32_t>(attribute_index) < attribute_count;
@@ -353,44 +378,51 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
switch (compression_level) {
case 0: {
DynamicIntegerPointsKdTreeDecoder<0> decoder(total_dimensionality);
- if (!decoder.DecodePoints(in_buffer, out_it))
+ if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
+ }
break;
}
case 1: {
DynamicIntegerPointsKdTreeDecoder<1> decoder(total_dimensionality);
- if (!decoder.DecodePoints(in_buffer, out_it))
+ if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
+ }
break;
}
case 2: {
DynamicIntegerPointsKdTreeDecoder<2> decoder(total_dimensionality);
- if (!decoder.DecodePoints(in_buffer, out_it))
+ if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
+ }
break;
}
case 3: {
DynamicIntegerPointsKdTreeDecoder<3> decoder(total_dimensionality);
- if (!decoder.DecodePoints(in_buffer, out_it))
+ if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
+ }
break;
}
case 4: {
DynamicIntegerPointsKdTreeDecoder<4> decoder(total_dimensionality);
- if (!decoder.DecodePoints(in_buffer, out_it))
+ if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
+ }
break;
}
case 5: {
DynamicIntegerPointsKdTreeDecoder<5> decoder(total_dimensionality);
- if (!decoder.DecodePoints(in_buffer, out_it))
+ if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
+ }
break;
}
case 6: {
DynamicIntegerPointsKdTreeDecoder<6> decoder(total_dimensionality);
- if (!decoder.DecodePoints(in_buffer, out_it))
+ if (!decoder.DecodePoints(in_buffer, out_it)) {
return false;
+ }
break;
}
default:
@@ -445,16 +477,19 @@ bool KdTreeAttributesDecoder::TransformAttributesToOriginalFormat() {
// Values are stored as unsigned in the attribute, make them signed again.
if (att->data_type() == DT_INT32) {
if (!TransformAttributeBackToSignedType<int32_t>(
- att, num_processed_signed_components))
+ att, num_processed_signed_components)) {
return false;
+ }
} else if (att->data_type() == DT_INT16) {
if (!TransformAttributeBackToSignedType<int16_t>(
- att, num_processed_signed_components))
+ att, num_processed_signed_components)) {
return false;
+ }
} else if (att->data_type() == DT_INT8) {
if (!TransformAttributeBackToSignedType<int8_t>(
- att, num_processed_signed_components))
+ att, num_processed_signed_components)) {
return false;
+ }
}
num_processed_signed_components += att->num_components();
} else if (att->data_type() == DT_FLOAT32) {
@@ -491,8 +526,9 @@ bool KdTreeAttributesDecoder::TransformAttributesToOriginalFormat() {
int quant_val_id = 0;
int out_byte_pos = 0;
Dequantizer dequantizer;
- if (!dequantizer.Init(transform.range(), max_quantized_value))
+ if (!dequantizer.Init(transform.range(), max_quantized_value)) {
return false;
+ }
const uint32_t *const portable_attribute_data =
reinterpret_cast<const uint32_t *>(
src_att->GetAddress(AttributeValueIndex(0)));
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/kd_tree_attributes_decoder.h b/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.h
index 87338d6b0d4..87338d6b0d4 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/kd_tree_attributes_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/kd_tree_attributes_encoder.cc b/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.cc
index f2a8af23bfc..0f9c31565e5 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/kd_tree_attributes_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.cc
@@ -13,6 +13,7 @@
// limitations under the License.
//
#include "draco/compression/attributes/kd_tree_attributes_encoder.h"
+
#include "draco/compression/attributes/kd_tree_attributes_shared.h"
#include "draco/compression/attributes/point_d_vector.h"
#include "draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h"
@@ -50,8 +51,9 @@ bool KdTreeAttributesEncoder::TransformAttributesToPortableFormat() {
AttributeQuantizationTransform attribute_quantization_transform;
const int quantization_bits = encoder()->options()->GetAttributeInt(
att_id, "quantization_bits", -1);
- if (quantization_bits < 1)
+ if (quantization_bits < 1) {
return false;
+ }
if (encoder()->options()->IsAttributeOptionSet(att_id,
"quantization_origin") &&
encoder()->options()->IsAttributeOptionSet(att_id,
@@ -91,8 +93,9 @@ bool KdTreeAttributesEncoder::TransformAttributesToPortableFormat() {
++avi) {
att->ConvertValue<int32_t>(avi, &act_value[0]);
for (int c = 0; c < att->num_components(); ++c) {
- if (min_value[c] > act_value[c])
+ if (min_value[c] > act_value[c]) {
min_value[c] = act_value[c];
+ }
}
}
for (int c = 0; c < att->num_components(); ++c) {
@@ -167,8 +170,9 @@ bool KdTreeAttributesEncoder::EncodePortableAttributes(
return false;
}
- if (source_att == nullptr)
+ if (source_att == nullptr) {
return false;
+ }
// Copy source_att to the vector.
if (source_att->data_type() == DT_UINT32) {
@@ -233,50 +237,57 @@ bool KdTreeAttributesEncoder::EncodePortableAttributes(
case 6: {
DynamicIntegerPointsKdTreeEncoder<6> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
- num_bits, out_buffer))
+ num_bits, out_buffer)) {
return false;
+ }
break;
}
case 5: {
DynamicIntegerPointsKdTreeEncoder<5> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
- num_bits, out_buffer))
+ num_bits, out_buffer)) {
return false;
+ }
break;
}
case 4: {
DynamicIntegerPointsKdTreeEncoder<4> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
- num_bits, out_buffer))
+ num_bits, out_buffer)) {
return false;
+ }
break;
}
case 3: {
DynamicIntegerPointsKdTreeEncoder<3> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
- num_bits, out_buffer))
+ num_bits, out_buffer)) {
return false;
+ }
break;
}
case 2: {
DynamicIntegerPointsKdTreeEncoder<2> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
- num_bits, out_buffer))
+ num_bits, out_buffer)) {
return false;
+ }
break;
}
case 1: {
DynamicIntegerPointsKdTreeEncoder<1> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
- num_bits, out_buffer))
+ num_bits, out_buffer)) {
return false;
+ }
break;
}
case 0: {
DynamicIntegerPointsKdTreeEncoder<0> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
- num_bits, out_buffer))
+ num_bits, out_buffer)) {
return false;
+ }
break;
}
// Compression level and/or encoding speed seem wrong.
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/kd_tree_attributes_encoder.h b/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.h
index 8b4c4e2faab..8b4c4e2faab 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/kd_tree_attributes_encoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/kd_tree_attributes_shared.h b/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_shared.h
index 94841a91d99..94841a91d99 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/kd_tree_attributes_shared.h
+++ b/extern/draco/draco/src/draco/compression/attributes/kd_tree_attributes_shared.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/linear_sequencer.h b/extern/draco/draco/src/draco/compression/attributes/linear_sequencer.h
index dc4dfffe9d5..7d9b5264199 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/linear_sequencer.h
+++ b/extern/draco/draco/src/draco/compression/attributes/linear_sequencer.h
@@ -32,8 +32,9 @@ class LinearSequencer : public PointsSequencer {
protected:
bool GenerateSequenceInternal() override {
- if (num_points_ < 0)
+ if (num_points_ < 0) {
return false;
+ }
out_point_ids()->resize(num_points_);
for (int i = 0; i < num_points_; ++i) {
out_point_ids()->at(i) = PointIndex(i);
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/mesh_attribute_indices_encoding_data.h b/extern/draco/draco/src/draco/compression/attributes/mesh_attribute_indices_encoding_data.h
index 9a358e44733..9a358e44733 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/mesh_attribute_indices_encoding_data.h
+++ b/extern/draco/draco/src/draco/compression/attributes/mesh_attribute_indices_encoding_data.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/normal_compression_utils.h b/extern/draco/draco/src/draco/compression/attributes/normal_compression_utils.h
index 4e6ff1a2134..32e27c711e3 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/normal_compression_utils.h
+++ b/extern/draco/draco/src/draco/compression/attributes/normal_compression_utils.h
@@ -39,6 +39,7 @@
#define DRACO_COMPRESSION_ATTRIBUTES_NORMAL_COMPRESSION_UTILS_H_
#include <inttypes.h>
+
#include <algorithm>
#include <cmath>
@@ -55,8 +56,9 @@ class OctahedronToolBox {
center_value_(-1) {}
bool SetQuantizationBits(int32_t q) {
- if (q < 2 || q > 30)
+ if (q < 2 || q > 30) {
return false;
+ }
quantization_bits_ = q;
max_quantized_value_ = (1 << quantization_bits_) - 1;
max_value_ = max_quantized_value_ - 1;
@@ -157,8 +159,9 @@ class OctahedronToolBox {
int_vec[2] = 0;
}
// Take care of the sign.
- if (scaled_vector[2] < 0)
+ if (scaled_vector[2] < 0) {
int_vec[2] *= -1;
+ }
IntegerVectorToQuantizedOctahedralCoords(int_vec, out_s, out_t);
}
@@ -189,6 +192,8 @@ 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);
@@ -304,18 +309,21 @@ class OctahedronToolBox {
// For correction values.
int32_t ModMax(int32_t x) const {
- if (x > this->center_value())
+ if (x > this->center_value()) {
return x - this->max_quantized_value();
- if (x < -this->center_value())
+ }
+ if (x < -this->center_value()) {
return x + this->max_quantized_value();
+ }
return x;
}
// For correction values.
int32_t MakePositive(int32_t x) const {
DRACO_DCHECK_LE(x, this->center_value() * 2);
- if (x < 0)
+ if (x < 0) {
return x + this->max_quantized_value();
+ }
return x;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/point_d_vector.h b/extern/draco/draco/src/draco/compression/attributes/point_d_vector.h
index ce99c8014d7..3b115d500cd 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/point_d_vector.h
+++ b/extern/draco/draco/src/draco/compression/attributes/point_d_vector.h
@@ -19,6 +19,7 @@
#include <cstring>
#include <memory>
#include <vector>
+
#include "draco/core/macros.h"
namespace draco {
@@ -42,8 +43,9 @@ class PseudoPointD {
// Specifically copies referenced memory
void swap(PseudoPointD &other) noexcept {
- for (internal_t dim = 0; dim < dimension_; dim += 1)
+ for (internal_t dim = 0; dim < dimension_; dim += 1) {
std::swap(mem_[dim], other.mem_[dim]);
+ }
}
PseudoPointD(const PseudoPointD &other)
@@ -59,9 +61,11 @@ class PseudoPointD {
}
bool operator==(const PseudoPointD &other) const {
- for (auto dim = 0; dim < dimension_; dim += 1)
- if (mem_[dim] != other.mem_[dim])
+ for (auto dim = 0; dim < dimension_; dim += 1) {
+ if (mem_[dim] != other.mem_[dim]) {
return false;
+ }
+ }
return true;
}
bool operator!=(const PseudoPointD &other) const {
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/points_sequencer.h b/extern/draco/draco/src/draco/compression/attributes/points_sequencer.h
index 2f4f7e16d11..2f4f7e16d11 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/points_sequencer.h
+++ b/extern/draco/draco/src/draco/compression/attributes/points_sequencer.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h
index b64b23d25de..36c124baa83 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h
@@ -18,13 +18,12 @@
#include <algorithm>
#include <cmath>
-#include "draco/draco_features.h"
-
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h"
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h"
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h"
#include "draco/compression/bit_coders/rans_bit_decoder.h"
#include "draco/core/varint_decoding.h"
+#include "draco/draco_features.h"
namespace draco {
@@ -123,8 +122,9 @@ bool MeshPredictionSchemeConstrainedMultiParallelogramDecoder<
++num_parallelograms;
// Stop processing when we reach the maximum number of allowed
// parallelograms.
- if (num_parallelograms == kMaxNumParallelograms)
+ if (num_parallelograms == kMaxNumParallelograms) {
break;
+ }
}
// Proceed to the next corner attached to the vertex. First swing left
@@ -154,8 +154,9 @@ bool MeshPredictionSchemeConstrainedMultiParallelogramDecoder<
for (int i = 0; i < num_parallelograms; ++i) {
const int context = num_parallelograms - 1;
const int pos = is_crease_edge_pos[context]++;
- if (is_crease_edge_[context].size() <= pos)
+ if (is_crease_edge_[context].size() <= pos) {
return false;
+ }
const bool is_crease = is_crease_edge_[context][pos];
if (!is_crease) {
++num_used_parallelograms;
@@ -206,12 +207,15 @@ bool MeshPredictionSchemeConstrainedMultiParallelogramDecoder<
// Encode selected edges using separate rans bit coder for each context.
for (int i = 0; i < kMaxNumParallelograms; ++i) {
uint32_t num_flags;
- DecodeVarint<uint32_t>(&num_flags, buffer);
+ if (!DecodeVarint<uint32_t>(&num_flags, buffer)) {
+ return false;
+ }
if (num_flags > 0) {
is_crease_edge_[i].resize(num_flags);
RAnsBitDecoder decoder;
- if (!decoder.StartDecoding(buffer))
+ if (!decoder.StartDecoding(buffer)) {
return false;
+ }
for (uint32_t j = 0; j < num_flags; ++j) {
is_crease_edge_[i][j] = decoder.DecodeNextBit();
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h
index 455c2ceb5ed..77df8ee24f1 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h
@@ -108,10 +108,12 @@ class MeshPredictionSchemeConstrainedMultiParallelogramEncoder
int residual_error;
bool operator<(const Error &e) const {
- if (num_bits < e.num_bits)
+ if (num_bits < e.num_bits) {
return true;
- if (num_bits > e.num_bits)
+ }
+ if (num_bits > e.num_bits) {
return false;
+ }
return residual_error < e.residual_error;
}
};
@@ -231,8 +233,9 @@ bool MeshPredictionSchemeConstrainedMultiParallelogramEncoder<
++num_parallelograms;
// Stop processing when we reach the maximum number of allowed
// parallelograms.
- if (num_parallelograms == kMaxNumParallelograms)
+ if (num_parallelograms == kMaxNumParallelograms) {
break;
+ }
}
// Proceed to the next corner attached to the vertex. First swing left
@@ -304,8 +307,9 @@ bool MeshPredictionSchemeConstrainedMultiParallelogramEncoder<
}
uint8_t configuration = 0;
for (int j = 0; j < num_parallelograms; ++j) {
- if (exluded_parallelograms[j])
+ if (exluded_parallelograms[j]) {
continue;
+ }
for (int c = 0; c < num_components; ++c) {
multi_pred_vals[c] += pred_vals[j][c];
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h
index c7a4e351aeb..c7a4e351aeb 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h
diff --git a/extern/draco/dracoenc/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..f712952556a 100644
--- a/extern/draco/dracoenc/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
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h
index 6694a981c10..6694a981c10 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h
index ab3c81a3901..ab3c81a3901 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h
index cd8299627b7..da1387a3075 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h
@@ -15,11 +15,10 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_GEOMETRIC_NORMAL_DECODER_H_
#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_GEOMETRIC_NORMAL_DECODER_H_
-#include "draco/draco_features.h"
-
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h"
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h"
#include "draco/compression/bit_coders/rans_bit_decoder.h"
+#include "draco/draco_features.h"
namespace draco {
@@ -52,12 +51,15 @@ class MeshPredictionSchemeGeometricNormalDecoder
}
bool IsInitialized() const override {
- if (!predictor_.IsInitialized())
+ if (!predictor_.IsInitialized()) {
return false;
- if (!this->mesh_data().IsInitialized())
+ }
+ if (!this->mesh_data().IsInitialized()) {
return false;
- if (!octahedron_tool_box_.IsInitialized())
+ }
+ if (!octahedron_tool_box_.IsInitialized()) {
return false;
+ }
return true;
}
@@ -70,10 +72,12 @@ class MeshPredictionSchemeGeometricNormalDecoder
}
bool SetParentAttribute(const PointAttribute *att) override {
- if (att->attribute_type() != GeometryAttribute::POSITION)
+ if (att->attribute_type() != GeometryAttribute::POSITION) {
return false; // Invalid attribute type.
- if (att->num_components() != 3)
+ }
+ if (att->num_components() != 3) {
return false; // Currently works only for 3 component positions.
+ }
predictor_.SetPositionAttribute(*att);
return true;
}
@@ -137,23 +141,28 @@ bool MeshPredictionSchemeGeometricNormalDecoder<
DataTypeT, TransformT, MeshDataT>::DecodePredictionData(DecoderBuffer
*buffer) {
// Get data needed for transform
- if (!this->transform().DecodeTransformData(buffer))
+ if (!this->transform().DecodeTransformData(buffer)) {
return false;
+ }
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
uint8_t prediction_mode;
- buffer->Decode(&prediction_mode);
+ if (!buffer->Decode(&prediction_mode)) {
+ return false;
+ }
if (!predictor_.SetNormalPredictionMode(
- NormalPredictionMode(prediction_mode)))
+ NormalPredictionMode(prediction_mode))) {
return false;
+ }
}
#endif
// Init normal flips.
- if (!flip_normal_bit_decoder_.StartDecoding(buffer))
+ if (!flip_normal_bit_decoder_.StartDecoding(buffer)) {
return false;
+ }
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h
index ffddf0170d6..cf146f83ac9 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h
@@ -50,10 +50,12 @@ class MeshPredictionSchemeGeometricNormalEncoder
}
bool IsInitialized() const override {
- if (!predictor_.IsInitialized())
+ if (!predictor_.IsInitialized()) {
return false;
- if (!this->mesh_data().IsInitialized())
+ }
+ if (!this->mesh_data().IsInitialized()) {
return false;
+ }
return true;
}
@@ -66,10 +68,12 @@ class MeshPredictionSchemeGeometricNormalEncoder
}
bool SetParentAttribute(const PointAttribute *att) override {
- if (att->attribute_type() != GeometryAttribute::POSITION)
+ if (att->attribute_type() != GeometryAttribute::POSITION) {
return false; // Invalid attribute type.
- if (att->num_components() != 3)
+ }
+ if (att->num_components() != 3) {
return false; // Currently works only for 3 component positions.
+ }
predictor_.SetPositionAttribute(*att);
return true;
}
@@ -162,8 +166,9 @@ template <typename DataTypeT, class TransformT, class MeshDataT>
bool MeshPredictionSchemeGeometricNormalEncoder<
DataTypeT, TransformT, MeshDataT>::EncodePredictionData(EncoderBuffer
*buffer) {
- if (!this->transform().EncodeTransformData(buffer))
+ if (!this->transform().EncodeTransformData(buffer)) {
return false;
+ }
// Encode normal flips.
flip_normal_bit_encoder_.EndEncoding(buffer);
diff --git a/extern/draco/dracoenc/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..bf1a6146111 100644
--- a/extern/draco/dracoenc/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
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h
index 9a26551decf..a554dda9676 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h
@@ -45,10 +45,12 @@ class MeshPredictionSchemeGeometricNormalPredictorBase {
entry_to_point_id_map_ = map;
}
bool IsInitialized() const {
- if (pos_attribute_ == nullptr)
+ if (pos_attribute_ == nullptr) {
return false;
- if (entry_to_point_id_map_ == nullptr)
+ }
+ if (entry_to_point_id_map_ == nullptr) {
return false;
+ }
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h
index a0cc802da03..fc82e0a8f76 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h
@@ -16,10 +16,9 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_MULTI_PARALLELOGRAM_DECODER_H_
#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_MULTI_PARALLELOGRAM_DECODER_H_
-#include "draco/draco_features.h"
-
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h"
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h"
+#include "draco/draco_features.h"
namespace draco {
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h
index 301b357d411..301b357d411 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_decoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_decoder.h
index 4d47ddf306e..4d47ddf306e 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_decoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h
index f00801932c2..f00801932c2 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h
diff --git a/extern/draco/dracoenc/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 c63c8d05ba6..485d457ccf6 100644
--- a/extern/draco/dracoenc/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
@@ -47,8 +47,9 @@ inline bool ComputeParallelogramPrediction(
const std::vector<int32_t> &vertex_to_data_map, const DataTypeT *in_data,
int num_components, DataTypeT *out_prediction) {
const CornerIndex oci = table->Opposite(ci);
- if (oci == kInvalidCornerIndex)
+ if (oci == kInvalidCornerIndex) {
return false;
+ }
int vert_opp, vert_next, vert_prev;
GetParallelogramEntries<CornerTableT>(oci, table, vertex_to_data_map,
&vert_opp, &vert_next, &vert_prev);
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h
index 2e389b2a2b4..02cf7e60f26 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h
@@ -18,12 +18,11 @@
#include <math.h>
-#include "draco/draco_features.h"
-
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h"
#include "draco/compression/bit_coders/rans_bit_decoder.h"
#include "draco/core/varint_decoding.h"
#include "draco/core/vector_d.h"
+#include "draco/draco_features.h"
#include "draco/mesh/corner_table.h"
namespace draco {
@@ -60,10 +59,12 @@ class MeshPredictionSchemeTexCoordsDecoder
}
bool IsInitialized() const override {
- if (pos_attribute_ == nullptr)
+ if (pos_attribute_ == nullptr) {
return false;
- if (!this->mesh_data().IsInitialized())
+ }
+ if (!this->mesh_data().IsInitialized()) {
return false;
+ }
return true;
}
@@ -76,12 +77,15 @@ class MeshPredictionSchemeTexCoordsDecoder
}
bool SetParentAttribute(const PointAttribute *att) override {
- if (att == nullptr)
+ if (att == nullptr) {
return false;
- if (att->attribute_type() != GeometryAttribute::POSITION)
+ }
+ if (att->attribute_type() != GeometryAttribute::POSITION) {
return false; // Invalid attribute type.
- if (att->num_components() != 3)
+ }
+ if (att->num_components() != 3) {
return false; // Currently works only for 3 component positions.
+ }
pos_attribute_ = att;
return true;
}
@@ -144,22 +148,27 @@ bool MeshPredictionSchemeTexCoordsDecoder<DataTypeT, TransformT, MeshDataT>::
// Decode the delta coded orientations.
uint32_t num_orientations = 0;
if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
- if (!buffer->Decode(&num_orientations))
+ if (!buffer->Decode(&num_orientations)) {
return false;
+ }
} else {
- if (!DecodeVarint(&num_orientations, buffer))
+ if (!DecodeVarint(&num_orientations, buffer)) {
return false;
+ }
}
- if (num_orientations == 0)
+ if (num_orientations == 0) {
return false;
+ }
orientations_.resize(num_orientations);
bool last_orientation = true;
RAnsBitDecoder decoder;
- if (!decoder.StartDecoding(buffer))
+ if (!decoder.StartDecoding(buffer)) {
return false;
+ }
for (uint32_t i = 0; i < num_orientations; ++i) {
- if (!decoder.DecodeNextBit())
+ if (!decoder.DecodeNextBit()) {
last_orientation = !last_orientation;
+ }
orientations_[i] = last_orientation;
}
decoder.EndDecoding();
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h
index 0e938b9c388..813b72ae35f 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h
@@ -16,6 +16,7 @@
#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_ENCODER_H_
#include <math.h>
+
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h"
#include "draco/compression/bit_coders/rans_bit_encoder.h"
#include "draco/core/varint_encoding.h"
@@ -55,10 +56,12 @@ class MeshPredictionSchemeTexCoordsEncoder
}
bool IsInitialized() const override {
- if (pos_attribute_ == nullptr)
+ if (pos_attribute_ == nullptr) {
return false;
- if (!this->mesh_data().IsInitialized())
+ }
+ if (!this->mesh_data().IsInitialized()) {
return false;
+ }
return true;
}
@@ -71,10 +74,12 @@ class MeshPredictionSchemeTexCoordsEncoder
}
bool SetParentAttribute(const PointAttribute *att) override {
- if (att->attribute_type() != GeometryAttribute::POSITION)
+ if (att->attribute_type() != GeometryAttribute::POSITION) {
return false; // Invalid attribute type.
- if (att->num_components() != 3)
+ }
+ if (att->num_components() != 3) {
return false; // Currently works only for 3 component positions.
+ }
pos_attribute_ = att;
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h
index 0fee0ceb6e2..83d4966393f 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h
@@ -48,10 +48,12 @@ class MeshPredictionSchemeTexCoordsPortableDecoder
}
bool IsInitialized() const override {
- if (!predictor_.IsInitialized())
+ if (!predictor_.IsInitialized()) {
return false;
- if (!this->mesh_data().IsInitialized())
+ }
+ if (!this->mesh_data().IsInitialized()) {
return false;
+ }
return true;
}
@@ -64,10 +66,12 @@ class MeshPredictionSchemeTexCoordsPortableDecoder
}
bool SetParentAttribute(const PointAttribute *att) override {
- if (!att || att->attribute_type() != GeometryAttribute::POSITION)
+ if (!att || att->attribute_type() != GeometryAttribute::POSITION) {
return false; // Invalid attribute type.
- if (att->num_components() != 3)
+ }
+ if (att->num_components() != 3) {
return false; // Currently works only for 3 component positions.
+ }
predictor_.SetPositionAttribute(*att);
return true;
}
@@ -84,6 +88,10 @@ bool MeshPredictionSchemeTexCoordsPortableDecoder<
DataTypeT *out_data, int /* size */,
int num_components,
const PointIndex *entry_to_point_id_map) {
+ if (num_components != MeshPredictionSchemeTexCoordsPortablePredictor<
+ DataTypeT, MeshDataT>::kNumComponents) {
+ return false;
+ }
predictor_.SetEntryToPointIdMap(entry_to_point_id_map);
this->transform().Init(num_components);
@@ -92,8 +100,9 @@ bool MeshPredictionSchemeTexCoordsPortableDecoder<
for (int p = 0; p < corner_map_size; ++p) {
const CornerIndex corner_id = this->mesh_data().data_to_corner_map()->at(p);
if (!predictor_.template ComputePredictedValue<false>(corner_id, out_data,
- p))
+ p)) {
return false;
+ }
const int dst_offset = p * num_components;
this->transform().ComputeOriginalValue(predictor_.predicted_value(),
@@ -109,16 +118,19 @@ bool MeshPredictionSchemeTexCoordsPortableDecoder<
*buffer) {
// Decode the delta coded orientations.
int32_t num_orientations = 0;
- if (!buffer->Decode(&num_orientations) || num_orientations < 0)
+ if (!buffer->Decode(&num_orientations) || num_orientations < 0) {
return false;
+ }
predictor_.ResizeOrientations(num_orientations);
bool last_orientation = true;
RAnsBitDecoder decoder;
- if (!decoder.StartDecoding(buffer))
+ if (!decoder.StartDecoding(buffer)) {
return false;
+ }
for (int i = 0; i < num_orientations; ++i) {
- if (!decoder.DecodeNextBit())
+ if (!decoder.DecodeNextBit()) {
last_orientation = !last_orientation;
+ }
predictor_.set_orientation(i, last_orientation);
}
decoder.EndDecoding();
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h
index 04a66325183..741ec66dc2a 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h
@@ -51,10 +51,12 @@ class MeshPredictionSchemeTexCoordsPortableEncoder
}
bool IsInitialized() const override {
- if (!predictor_.IsInitialized())
+ if (!predictor_.IsInitialized()) {
return false;
- if (!this->mesh_data().IsInitialized())
+ }
+ if (!this->mesh_data().IsInitialized()) {
return false;
+ }
return true;
}
@@ -67,10 +69,12 @@ class MeshPredictionSchemeTexCoordsPortableEncoder
}
bool SetParentAttribute(const PointAttribute *att) override {
- if (att->attribute_type() != GeometryAttribute::POSITION)
+ if (att->attribute_type() != GeometryAttribute::POSITION) {
return false; // Invalid attribute type.
- if (att->num_components() != 3)
+ }
+ if (att->num_components() != 3) {
return false; // Currently works only for 3 component positions.
+ }
predictor_.SetPositionAttribute(*att);
return true;
}
diff --git a/extern/draco/dracoenc/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 f9357712638..5d8a5060133 100644
--- a/extern/draco/dracoenc/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
@@ -16,6 +16,7 @@
#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_PORTABLE_PREDICTOR_H_
#include <math.h>
+
#include "draco/attributes/point_attribute.h"
#include "draco/core/math_utils.h"
#include "draco/core/vector_d.h"
@@ -28,6 +29,8 @@ namespace draco {
template <typename DataTypeT, class MeshDataT>
class MeshPredictionSchemeTexCoordsPortablePredictor {
public:
+ static constexpr int kNumComponents = 2;
+
explicit MeshPredictionSchemeTexCoordsPortablePredictor(const MeshDataT &md)
: pos_attribute_(nullptr),
entry_to_point_id_map_(nullptr),
@@ -71,7 +74,6 @@ class MeshPredictionSchemeTexCoordsPortablePredictor {
private:
const PointAttribute *pos_attribute_;
const PointIndex *entry_to_point_id_map_;
- static constexpr int kNumComponents = 2;
DataTypeT predicted_value_[kNumComponents];
// Encoded / decoded array of UV flips.
// TODO(ostava): We should remove this and replace this with in-place encoding
@@ -203,14 +205,16 @@ bool MeshPredictionSchemeTexCoordsPortablePredictor<
}
} else {
// When decoding the data, we already know which orientation to use.
- if (orientations_.empty())
+ if (orientations_.empty()) {
return false;
+ }
const bool orientation = orientations_.back();
orientations_.pop_back();
- if (orientation)
+ if (orientation) {
predicted_uv = (x_uv + cx_uv) / pn_norm2_squared;
- else
+ } else {
predicted_uv = (x_uv - cx_uv) / pn_norm2_squared;
+ }
}
predicted_value_[0] = static_cast<int>(predicted_uv[0]);
predicted_value_[1] = static_cast<int>(predicted_uv[1]);
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h
index 9a14ff8d7d2..064e1b44fe1 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h
@@ -46,8 +46,9 @@ class PredictionSchemeDecoder : public PredictionSchemeTypedDecoderInterface<
: attribute_(attribute), transform_(transform) {}
bool DecodePredictionData(DecoderBuffer *buffer) override {
- if (!transform_.DecodeTransformData(buffer))
+ if (!transform_.DecodeTransformData(buffer)) {
return false;
+ }
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h
index db835554385..cf2a6ba6b3b 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h
@@ -18,9 +18,8 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DECODER_FACTORY_H_
#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DECODER_FACTORY_H_
-#include "draco/draco_features.h"
-
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h"
+#include "draco/draco_features.h"
#ifdef DRACO_NORMAL_ENCODING_SUPPORTED
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h"
#endif
@@ -154,8 +153,9 @@ std::unique_ptr<PredictionSchemeDecoder<DataTypeT, TransformT>>
CreatePredictionSchemeForDecoder(PredictionSchemeMethod method, int att_id,
const PointCloudDecoder *decoder,
const TransformT &transform) {
- if (method == PREDICTION_NONE)
+ if (method == PREDICTION_NONE) {
return nullptr;
+ }
const PointAttribute *const att = decoder->point_cloud()->attribute(att_id);
if (decoder->GetGeometryType() == TRIANGULAR_MESH) {
// Cast the decoder to mesh decoder. This is not necessarily safe if there
@@ -170,8 +170,9 @@ CreatePredictionSchemeForDecoder(PredictionSchemeMethod method, int att_id,
MeshDecoder, PredictionSchemeDecoder<DataTypeT, TransformT>,
MeshPredictionSchemeDecoderFactory<DataTypeT>>(
mesh_decoder, method, att_id, transform, decoder->bitstream_version());
- if (ret)
+ if (ret) {
return ret;
+ }
// Otherwise try to create another prediction scheme.
}
// Create delta decoder.
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h
index 6f19f7fdb99..6f19f7fdb99 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h
index 47c1532ad98..47c1532ad98 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h
index ae72c71208a..ae72c71208a 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h
index 324afafa637..324afafa637 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h
index 548a54d4e02..2a211a9fc20 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h
@@ -46,8 +46,9 @@ class PredictionSchemeEncoder : public PredictionSchemeTypedEncoderInterface<
: attribute_(attribute), transform_(transform) {}
bool EncodePredictionData(EncoderBuffer *buffer) override {
- if (!transform_.EncodeTransformData(buffer))
+ if (!transform_.EncodeTransformData(buffer)) {
return false;
+ }
return true;
}
diff --git a/extern/draco/dracoenc/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 6b74e571c6d..428340da013 100644
--- a/extern/draco/dracoenc/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
@@ -62,10 +62,12 @@ PredictionSchemeMethod GetPredictionMethodFromOptions(
int att_id, const EncoderOptions &options) {
const int pred_type =
options.GetAttributeInt(att_id, "prediction_scheme", -1);
- if (pred_type == -1)
+ if (pred_type == -1) {
return PREDICTION_UNDEFINED;
- if (pred_type < 0 || pred_type >= NUM_PREDICTION_SCHEMES)
+ }
+ if (pred_type < 0 || pred_type >= NUM_PREDICTION_SCHEMES) {
return PREDICTION_NONE;
+ }
return static_cast<PredictionSchemeMethod>(pred_type);
}
diff --git a/extern/draco/dracoenc/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 4cc40010773..40a7683aa0d 100644
--- a/extern/draco/dracoenc/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
@@ -86,8 +86,9 @@ CreatePredictionSchemeForEncoder(PredictionSchemeMethod method, int att_id,
if (method == PREDICTION_UNDEFINED) {
method = SelectPredictionMethod(att_id, encoder);
}
- if (method == PREDICTION_NONE)
+ if (method == PREDICTION_NONE) {
return nullptr; // No prediction is used.
+ }
if (encoder->GetGeometryType() == TRIANGULAR_MESH) {
// Cast the encoder to mesh encoder. This is not necessarily safe if there
// is some other encoder decides to use TRIANGULAR_MESH as the return type,
@@ -100,8 +101,9 @@ CreatePredictionSchemeForEncoder(PredictionSchemeMethod method, int att_id,
MeshEncoder, PredictionSchemeEncoder<DataTypeT, TransformT>,
MeshPredictionSchemeEncoderFactory<DataTypeT>>(
mesh_encoder, method, att_id, transform, kDracoMeshBitstreamVersion);
- if (ret)
+ if (ret) {
return ret;
+ }
// Otherwise try to create another prediction scheme.
}
// Create delta encoder.
diff --git a/extern/draco/dracoenc/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..ab64bce7114 100644
--- a/extern/draco/dracoenc/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
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h
index 0929492aaec..0929492aaec 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h
index 9fce686ae41..b36c4c8a273 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h
@@ -61,8 +61,9 @@ std::unique_ptr<PredictionSchemeT> CreateMeshPredictionScheme(
&encoding_data->vertex_to_encoded_attribute_value_index_map);
MeshPredictionSchemeFactoryT factory;
auto ret = factory(method, att, transform, md, bitstream_version);
- if (ret)
+ if (ret) {
return ret;
+ }
} else {
typedef MeshPredictionSchemeData<CornerTable> MeshData;
MeshData md;
@@ -71,8 +72,9 @@ std::unique_ptr<PredictionSchemeT> CreateMeshPredictionScheme(
&encoding_data->vertex_to_encoded_attribute_value_index_map);
MeshPredictionSchemeFactoryT factory;
auto ret = factory(method, att, transform, md, bitstream_version);
- if (ret)
+ if (ret) {
return ret;
+ }
}
}
return nullptr;
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h
index c9b3706930f..c9b3706930f 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h
index 14ecb84654b..5a6c7c2dd45 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h
@@ -44,18 +44,23 @@ class PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform
bool DecodeTransformData(DecoderBuffer *buffer) {
DataTypeT max_quantized_value, center_value;
- if (!buffer->Decode(&max_quantized_value))
+ if (!buffer->Decode(&max_quantized_value)) {
return false;
- if (!buffer->Decode(&center_value))
+ }
+ if (!buffer->Decode(&center_value)) {
return false;
+ }
(void)center_value;
- if (!this->set_max_quantized_value(max_quantized_value))
+ if (!this->set_max_quantized_value(max_quantized_value)) {
return false;
+ }
// Account for reading wrong values, e.g., due to fuzzing.
- if (this->quantization_bits() < 2)
+ if (this->quantization_bits() < 2) {
return false;
- if (this->quantization_bits() > 30)
+ }
+ if (this->quantization_bits() > 30) {
return false;
+ }
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h
index 0dc96967b10..0dc96967b10 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h
index 981077294f8..4a1e3a67b83 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h
@@ -90,8 +90,9 @@ class PredictionSchemeNormalOctahedronCanonicalizedTransformBase
}
bool IsInBottomLeft(const Point2 &p) const {
- if (p[0] == 0 && p[1] == 0)
+ if (p[0] == 0 && p[1] == 0) {
return true;
+ }
return (p[0] < 0 && p[1] <= 0);
}
};
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h
index dbb788a33e0..a1bc4a327ac 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h
@@ -18,13 +18,12 @@
#include <cmath>
-#include "draco/draco_features.h"
-
#include "draco/compression/attributes/normal_compression_utils.h"
#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h"
#include "draco/core/decoder_buffer.h"
#include "draco/core/macros.h"
#include "draco/core/vector_d.h"
+#include "draco/draco_features.h"
namespace draco {
@@ -45,11 +44,13 @@ class PredictionSchemeNormalOctahedronDecodingTransform
void Init(int num_components) {}
bool DecodeTransformData(DecoderBuffer *buffer) {
DataTypeT max_quantized_value, center_value;
- if (!buffer->Decode(&max_quantized_value))
+ if (!buffer->Decode(&max_quantized_value)) {
return false;
+ }
if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
- if (!buffer->Decode(&center_value))
+ if (!buffer->Decode(&center_value)) {
return false;
+ }
}
(void)center_value;
return this->set_max_quantized_value(max_quantized_value);
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h
index 4abfef66903..4abfef66903 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h
index ff71fe86fdf..c9dd7d67bf4 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h
@@ -60,8 +60,9 @@ class PredictionSchemeNormalOctahedronTransformBase {
protected:
inline bool set_max_quantized_value(DataTypeT max_quantized_value) {
- if (max_quantized_value % 2 == 0)
+ if (max_quantized_value % 2 == 0) {
return false;
+ }
int q = MostSignificantBit(max_quantized_value) + 1;
return octahedron_tool_box_.SetQuantizationBits(q);
}
diff --git a/extern/draco/dracoenc/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 bd40df8d2f9..0a14d0d9ba4 100644
--- a/extern/draco/dracoenc/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
@@ -39,25 +39,30 @@ class PredictionSchemeWrapDecodingTransform
predicted_vals = this->ClampPredictedValue(predicted_vals);
for (int i = 0; i < this->num_components(); ++i) {
out_original_vals[i] = predicted_vals[i] + corr_vals[i];
- if (out_original_vals[i] > this->max_value())
+ if (out_original_vals[i] > this->max_value()) {
out_original_vals[i] -= this->max_dif();
- else if (out_original_vals[i] < this->min_value())
+ } else if (out_original_vals[i] < this->min_value()) {
out_original_vals[i] += this->max_dif();
+ }
}
}
bool DecodeTransformData(DecoderBuffer *buffer) {
DataTypeT min_value, max_value;
- if (!buffer->Decode(&min_value))
+ if (!buffer->Decode(&min_value)) {
return false;
- if (!buffer->Decode(&max_value))
+ }
+ if (!buffer->Decode(&max_value)) {
return false;
- if (min_value > max_value)
+ }
+ if (min_value > max_value) {
return false;
+ }
this->set_min_value(min_value);
this->set_max_value(max_value);
- if (!this->InitCorrectionBounds())
+ if (!this->InitCorrectionBounds()) {
return false;
+ }
return true;
}
};
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h
index 8cd241f2e0a..1f5e8b13584 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h
+++ b/extern/draco/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h
@@ -32,15 +32,17 @@ class PredictionSchemeWrapEncodingTransform
void Init(const DataTypeT *orig_data, int size, int num_components) {
PredictionSchemeWrapTransformBase<DataTypeT>::Init(num_components);
// Go over the original values and compute the bounds.
- if (size == 0)
+ if (size == 0) {
return;
+ }
DataTypeT min_value = orig_data[0];
DataTypeT max_value = min_value;
for (int i = 1; i < size; ++i) {
- if (orig_data[i] < min_value)
+ if (orig_data[i] < min_value) {
min_value = orig_data[i];
- else if (orig_data[i] > max_value)
+ } else if (orig_data[i] > max_value) {
max_value = orig_data[i];
+ }
}
this->set_min_value(min_value);
this->set_max_value(max_value);
@@ -58,10 +60,11 @@ class PredictionSchemeWrapEncodingTransform
out_corr_vals[i] = original_vals[i] - predicted_vals[i];
// Wrap around if needed.
DataTypeT &corr_val = out_corr_vals[i];
- if (corr_val < this->min_correction())
+ if (corr_val < this->min_correction()) {
corr_val += this->max_dif();
- else if (corr_val > this->max_correction())
+ } else if (corr_val > this->max_correction()) {
corr_val -= this->max_dif();
+ }
}
}
diff --git a/extern/draco/dracoenc/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 cf522269f1f..26f61fbaf6a 100644
--- a/extern/draco/dracoenc/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
@@ -15,6 +15,7 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_WRAP_TRANSFORM_BASE_H_
#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_WRAP_TRANSFORM_BASE_H_
+#include <limits>
#include <vector>
#include "draco/compression/config/compression_shared.h"
@@ -61,12 +62,13 @@ class PredictionSchemeWrapTransformBase {
inline const DataTypeT *ClampPredictedValue(
const DataTypeT *predicted_val) const {
for (int i = 0; i < this->num_components(); ++i) {
- if (predicted_val[i] > max_value_)
+ if (predicted_val[i] > max_value_) {
clamped_value_[i] = max_value_;
- else if (predicted_val[i] < min_value_)
+ } else if (predicted_val[i] < min_value_) {
clamped_value_[i] = min_value_;
- else
+ } else {
clamped_value_[i] = predicted_val[i];
+ }
}
return &clamped_value_[0];
}
@@ -81,13 +83,15 @@ class PredictionSchemeWrapTransformBase {
bool InitCorrectionBounds() {
const int64_t dif =
static_cast<int64_t>(max_value_) - static_cast<int64_t>(min_value_);
- if (dif < 0 || dif >= std::numeric_limits<DataTypeT>::max())
+ if (dif < 0 || dif >= std::numeric_limits<DataTypeT>::max()) {
return false;
+ }
max_dif_ = 1 + static_cast<DataTypeT>(dif);
max_correction_ = max_dif_ / 2;
min_correction_ = -max_correction_;
- if ((max_dif_ & 1) == 0)
+ if ((max_dif_ & 1) == 0) {
max_correction_ -= 1;
+ }
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_decoder.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_decoder.cc
index 9e33cef3428..b4ba24f2d31 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_decoder.cc
@@ -36,10 +36,13 @@ bool SequentialAttributeDecoder::InitializeStandalone(
bool SequentialAttributeDecoder::DecodePortableAttribute(
const std::vector<PointIndex> &point_ids, DecoderBuffer *in_buffer) {
- if (attribute_->num_components() <= 0 || !attribute_->Reset(point_ids.size()))
+ if (attribute_->num_components() <= 0 ||
+ !attribute_->Reset(point_ids.size())) {
return false;
- if (!DecodeValues(point_ids, in_buffer))
+ }
+ if (!DecodeValues(point_ids, in_buffer)) {
return false;
+ }
return true;
}
@@ -74,8 +77,9 @@ bool SequentialAttributeDecoder::InitPredictionScheme(
for (int i = 0; i < ps->GetNumParentAttributes(); ++i) {
const int att_id = decoder_->point_cloud()->GetNamedAttributeId(
ps->GetParentAttributeType(i));
- if (att_id == -1)
+ if (att_id == -1) {
return false; // Requested attribute does not exist.
+ }
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
if (!ps->SetParentAttribute(decoder_->point_cloud()->attribute(att_id))) {
@@ -102,8 +106,9 @@ bool SequentialAttributeDecoder::DecodeValues(
int out_byte_pos = 0;
// Decode raw attribute values in their original format.
for (int i = 0; i < num_values; ++i) {
- if (!in_buffer->Decode(value_data, entry_size))
+ if (!in_buffer->Decode(value_data, entry_size)) {
return false;
+ }
attribute_->buffer()->Write(out_byte_pos, value_data, entry_size);
out_byte_pos += entry_size;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_decoder.h b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_decoder.h
index 721a587fc2a..d48119465a9 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_decoder.h
@@ -15,10 +15,9 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_ATTRIBUTE_DECODER_H_
#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_ATTRIBUTE_DECODER_H_
-#include "draco/draco_features.h"
-
#include "draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h"
#include "draco/compression/point_cloud/point_cloud_decoder.h"
+#include "draco/draco_features.h"
namespace draco {
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_decoders_controller.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_decoders_controller.cc
index 2676eb7905c..0e5e26bcaa2 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_decoders_controller.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_decoders_controller.cc
@@ -27,36 +27,42 @@ SequentialAttributeDecodersController::SequentialAttributeDecodersController(
bool SequentialAttributeDecodersController::DecodeAttributesDecoderData(
DecoderBuffer *buffer) {
- if (!AttributesDecoder::DecodeAttributesDecoderData(buffer))
+ if (!AttributesDecoder::DecodeAttributesDecoderData(buffer)) {
return false;
+ }
// Decode unique ids of all sequential encoders and create them.
const int32_t num_attributes = GetNumAttributes();
sequential_decoders_.resize(num_attributes);
for (int i = 0; i < num_attributes; ++i) {
uint8_t decoder_type;
- if (!buffer->Decode(&decoder_type))
+ if (!buffer->Decode(&decoder_type)) {
return false;
+ }
// Create the decoder from the id.
sequential_decoders_[i] = CreateSequentialDecoder(decoder_type);
- if (!sequential_decoders_[i])
+ if (!sequential_decoders_[i]) {
return false;
- if (!sequential_decoders_[i]->Init(GetDecoder(), GetAttributeId(i)))
+ }
+ if (!sequential_decoders_[i]->Init(GetDecoder(), GetAttributeId(i))) {
return false;
+ }
}
return true;
}
bool SequentialAttributeDecodersController::DecodeAttributes(
DecoderBuffer *buffer) {
- if (!sequencer_ || !sequencer_->GenerateSequence(&point_ids_))
+ if (!sequencer_ || !sequencer_->GenerateSequence(&point_ids_)) {
return false;
+ }
// Initialize point to attribute value mapping for all decoded attributes.
const int32_t num_attributes = GetNumAttributes();
for (int i = 0; i < num_attributes; ++i) {
PointAttribute *const pa =
GetDecoder()->point_cloud()->attribute(GetAttributeId(i));
- if (!sequencer_->UpdatePointToAttributeIndexMapping(pa))
+ if (!sequencer_->UpdatePointToAttributeIndexMapping(pa)) {
return false;
+ }
}
return AttributesDecoder::DecodeAttributes(buffer);
}
@@ -66,8 +72,9 @@ bool SequentialAttributeDecodersController::DecodePortableAttributes(
const int32_t num_attributes = GetNumAttributes();
for (int i = 0; i < num_attributes; ++i) {
if (!sequential_decoders_[i]->DecodePortableAttribute(point_ids_,
- in_buffer))
+ in_buffer)) {
return false;
+ }
}
return true;
}
@@ -77,8 +84,9 @@ bool SequentialAttributeDecodersController::
const int32_t num_attributes = GetNumAttributes();
for (int i = 0; i < num_attributes; ++i) {
if (!sequential_decoders_[i]->DecodeDataNeededByPortableTransform(
- point_ids_, in_buffer))
+ point_ids_, in_buffer)) {
return false;
+ }
}
return true;
}
@@ -106,8 +114,9 @@ bool SequentialAttributeDecodersController::
}
}
if (!sequential_decoders_[i]->TransformAttributeToOriginalFormat(
- point_ids_))
+ point_ids_)) {
return false;
+ }
}
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_decoders_controller.h b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_decoders_controller.h
index 9fd5e490741..abc1f368523 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_decoders_controller.h
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_decoders_controller.h
@@ -37,8 +37,9 @@ class SequentialAttributeDecodersController : public AttributesDecoder {
const PointAttribute *GetPortableAttribute(
int32_t point_attribute_id) override {
const int32_t loc_id = GetLocalIdForPointAttribute(point_attribute_id);
- if (loc_id < 0)
+ if (loc_id < 0) {
return nullptr;
+ }
return sequential_decoders_[loc_id]->GetPortableAttribute();
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_encoder.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoder.cc
index 95547c005e7..6bde3eeb3ba 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoder.cc
@@ -46,8 +46,9 @@ bool SequentialAttributeEncoder::TransformAttributeToPortableFormat(
bool SequentialAttributeEncoder::EncodePortableAttribute(
const std::vector<PointIndex> &point_ids, EncoderBuffer *out_buffer) {
// Lossless encoding of the input values.
- if (!EncodeValues(point_ids, out_buffer))
+ if (!EncodeValues(point_ids, out_buffer)) {
return false;
+ }
return true;
}
@@ -80,8 +81,9 @@ bool SequentialAttributeEncoder::InitPredictionScheme(
for (int i = 0; i < ps->GetNumParentAttributes(); ++i) {
const int att_id = encoder_->point_cloud()->GetNamedAttributeId(
ps->GetParentAttributeType(i));
- if (att_id == -1)
+ if (att_id == -1) {
return false; // Requested attribute does not exist.
+ }
parent_attributes_.push_back(att_id);
encoder_->MarkParentAttribute(att_id);
}
@@ -93,10 +95,12 @@ bool SequentialAttributeEncoder::SetPredictionSchemeParentAttributes(
for (int i = 0; i < ps->GetNumParentAttributes(); ++i) {
const int att_id = encoder_->point_cloud()->GetNamedAttributeId(
ps->GetParentAttributeType(i));
- if (att_id == -1)
+ if (att_id == -1) {
return false; // Requested attribute does not exist.
- if (!ps->SetParentAttribute(encoder_->GetPortableAttribute(att_id)))
+ }
+ if (!ps->SetParentAttribute(encoder_->GetPortableAttribute(att_id))) {
return false;
+ }
}
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_encoder.h b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoder.h
index 540ba947077..00f62db8959 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_encoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoder.h
@@ -64,8 +64,9 @@ class SequentialAttributeEncoder {
int GetParentAttributeId(int i) const { return parent_attributes_[i]; }
const PointAttribute *GetPortableAttribute() const {
- if (portable_attribute_ != nullptr)
+ if (portable_attribute_ != nullptr) {
return portable_attribute_.get();
+ }
return attribute();
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_encoders_controller.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.cc
index b40cef842ae..521935c1e99 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_encoders_controller.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.cc
@@ -31,23 +31,27 @@ SequentialAttributeEncodersController::SequentialAttributeEncodersController(
bool SequentialAttributeEncodersController::Init(PointCloudEncoder *encoder,
const PointCloud *pc) {
- if (!AttributesEncoder::Init(encoder, pc))
+ if (!AttributesEncoder::Init(encoder, pc)) {
return false;
- if (!CreateSequentialEncoders())
+ }
+ if (!CreateSequentialEncoders()) {
return false;
+ }
// Initialize all value encoders.
for (uint32_t i = 0; i < num_attributes(); ++i) {
const int32_t att_id = GetAttributeId(i);
- if (!sequential_encoders_[i]->Init(encoder, att_id))
+ if (!sequential_encoders_[i]->Init(encoder, att_id)) {
return false;
+ }
}
return true;
}
bool SequentialAttributeEncodersController::EncodeAttributesEncoderData(
EncoderBuffer *out_buffer) {
- if (!AttributesEncoder::EncodeAttributesEncoderData(out_buffer))
+ if (!AttributesEncoder::EncodeAttributesEncoderData(out_buffer)) {
return false;
+ }
// Encode a unique id of every sequential encoder.
for (uint32_t i = 0; i < sequential_encoders_.size(); ++i) {
out_buffer->Encode(sequential_encoders_[i]->GetUniqueId());
@@ -57,8 +61,9 @@ bool SequentialAttributeEncodersController::EncodeAttributesEncoderData(
bool SequentialAttributeEncodersController::EncodeAttributes(
EncoderBuffer *buffer) {
- if (!sequencer_ || !sequencer_->GenerateSequence(&point_ids_))
+ if (!sequencer_ || !sequencer_->GenerateSequence(&point_ids_)) {
return false;
+ }
return AttributesEncoder::EncodeAttributes(buffer);
}
@@ -66,8 +71,9 @@ bool SequentialAttributeEncodersController::
TransformAttributesToPortableFormat() {
for (uint32_t i = 0; i < sequential_encoders_.size(); ++i) {
if (!sequential_encoders_[i]->TransformAttributeToPortableFormat(
- point_ids_))
+ point_ids_)) {
return false;
+ }
}
return true;
}
@@ -76,8 +82,9 @@ bool SequentialAttributeEncodersController::EncodePortableAttributes(
EncoderBuffer *out_buffer) {
for (uint32_t i = 0; i < sequential_encoders_.size(); ++i) {
if (!sequential_encoders_[i]->EncodePortableAttribute(point_ids_,
- out_buffer))
+ out_buffer)) {
return false;
+ }
}
return true;
}
@@ -86,8 +93,9 @@ bool SequentialAttributeEncodersController::
EncodeDataNeededByPortableTransforms(EncoderBuffer *out_buffer) {
for (uint32_t i = 0; i < sequential_encoders_.size(); ++i) {
if (!sequential_encoders_[i]->EncodeDataNeededByPortableTransform(
- out_buffer))
+ out_buffer)) {
return false;
+ }
}
return true;
}
@@ -96,11 +104,13 @@ bool SequentialAttributeEncodersController::CreateSequentialEncoders() {
sequential_encoders_.resize(num_attributes());
for (uint32_t i = 0; i < num_attributes(); ++i) {
sequential_encoders_[i] = CreateSequentialEncoder(i);
- if (sequential_encoders_[i] == nullptr)
+ if (sequential_encoders_[i] == nullptr) {
return false;
+ }
if (i < sequential_encoder_marked_as_parent_.size()) {
- if (sequential_encoder_marked_as_parent_[i])
+ if (sequential_encoder_marked_as_parent_[i]) {
sequential_encoders_[i]->MarkParentAttribute();
+ }
}
}
return true;
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_encoders_controller.h b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.h
index d5574abef8d..13c2704ec0a 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_attribute_encoders_controller.h
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.h
@@ -42,23 +42,26 @@ class SequentialAttributeEncodersController : public AttributesEncoder {
int NumParentAttributes(int32_t point_attribute_id) const override {
const int32_t loc_id = GetLocalIdForPointAttribute(point_attribute_id);
- if (loc_id < 0)
+ if (loc_id < 0) {
return 0;
+ }
return sequential_encoders_[loc_id]->NumParentAttributes();
}
int GetParentAttributeId(int32_t point_attribute_id,
int32_t parent_i) const override {
const int32_t loc_id = GetLocalIdForPointAttribute(point_attribute_id);
- if (loc_id < 0)
+ if (loc_id < 0) {
return -1;
+ }
return sequential_encoders_[loc_id]->GetParentAttributeId(parent_i);
}
bool MarkParentAttribute(int32_t point_attribute_id) override {
const int32_t loc_id = GetLocalIdForPointAttribute(point_attribute_id);
- if (loc_id < 0)
+ if (loc_id < 0) {
return false;
+ }
// Mark the attribute encoder as parent (even when if it is not created
// yet).
if (sequential_encoder_marked_as_parent_.size() <= loc_id) {
@@ -66,8 +69,9 @@ class SequentialAttributeEncodersController : public AttributesEncoder {
}
sequential_encoder_marked_as_parent_[loc_id] = true;
- if (sequential_encoders_.size() <= loc_id)
+ if (sequential_encoders_.size() <= loc_id) {
return true; // Sequential encoders not generated yet.
+ }
sequential_encoders_[loc_id]->MarkParentAttribute();
return true;
}
@@ -75,8 +79,9 @@ class SequentialAttributeEncodersController : public AttributesEncoder {
const PointAttribute *GetPortableAttribute(
int32_t point_attribute_id) override {
const int32_t loc_id = GetLocalIdForPointAttribute(point_attribute_id);
- if (loc_id < 0)
+ if (loc_id < 0) {
return nullptr;
+ }
return sequential_encoders_[loc_id]->GetPortableAttribute();
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_integer_attribute_decoder.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.cc
index 8d9210af912..d01fb26aad4 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_integer_attribute_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.cc
@@ -24,8 +24,9 @@ SequentialIntegerAttributeDecoder::SequentialIntegerAttributeDecoder() {}
bool SequentialIntegerAttributeDecoder::Init(PointCloudDecoder *decoder,
int attribute_id) {
- if (!SequentialAttributeDecoder::Init(decoder, attribute_id))
+ if (!SequentialAttributeDecoder::Init(decoder, attribute_id)) {
return false;
+ }
return true;
}
@@ -33,8 +34,9 @@ bool SequentialIntegerAttributeDecoder::TransformAttributeToOriginalFormat(
const std::vector<PointIndex> &point_ids) {
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder() &&
- decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0))
+ decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
return true; // Don't revert the transform here for older files.
+ }
#endif
return StoreValues(static_cast<uint32_t>(point_ids.size()));
}
@@ -43,30 +45,37 @@ bool SequentialIntegerAttributeDecoder::DecodeValues(
const std::vector<PointIndex> &point_ids, DecoderBuffer *in_buffer) {
// Decode prediction scheme.
int8_t prediction_scheme_method;
- in_buffer->Decode(&prediction_scheme_method);
+ if (!in_buffer->Decode(&prediction_scheme_method)) {
+ return false;
+ }
if (prediction_scheme_method != PREDICTION_NONE) {
int8_t prediction_transform_type;
- in_buffer->Decode(&prediction_transform_type);
+ if (!in_buffer->Decode(&prediction_transform_type)) {
+ return false;
+ }
prediction_scheme_ = CreateIntPredictionScheme(
static_cast<PredictionSchemeMethod>(prediction_scheme_method),
static_cast<PredictionSchemeTransformType>(prediction_transform_type));
}
if (prediction_scheme_) {
- if (!InitPredictionScheme(prediction_scheme_.get()))
+ if (!InitPredictionScheme(prediction_scheme_.get())) {
return false;
+ }
}
- if (!DecodeIntegerValues(point_ids, in_buffer))
+ if (!DecodeIntegerValues(point_ids, in_buffer)) {
return false;
+ }
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
const int32_t num_values = static_cast<uint32_t>(point_ids.size());
if (decoder() &&
decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
// For older files, revert the transform right after we decode the data.
- if (!StoreValues(num_values))
+ if (!StoreValues(num_values)) {
return false;
+ }
}
#endif
return true;
@@ -76,8 +85,9 @@ std::unique_ptr<PredictionSchemeTypedDecoderInterface<int32_t>>
SequentialIntegerAttributeDecoder::CreateIntPredictionScheme(
PredictionSchemeMethod method,
PredictionSchemeTransformType transform_type) {
- if (transform_type != PREDICTION_TRANSFORM_WRAP)
+ if (transform_type != PREDICTION_TRANSFORM_WRAP) {
return nullptr; // For now we support only wrap transform.
+ }
return CreatePredictionSchemeForDecoder<
int32_t, PredictionSchemeWrapDecodingTransform<int32_t>>(
method, attribute_id(), decoder());
@@ -86,44 +96,55 @@ SequentialIntegerAttributeDecoder::CreateIntPredictionScheme(
bool SequentialIntegerAttributeDecoder::DecodeIntegerValues(
const std::vector<PointIndex> &point_ids, DecoderBuffer *in_buffer) {
const int num_components = GetNumValueComponents();
- if (num_components <= 0)
+ if (num_components <= 0) {
return false;
+ }
const size_t num_entries = point_ids.size();
const size_t num_values = num_entries * num_components;
PreparePortableAttribute(static_cast<int>(num_entries), num_components);
int32_t *const portable_attribute_data = GetPortableAttributeData();
- if (portable_attribute_data == nullptr)
+ if (portable_attribute_data == nullptr) {
return false;
+ }
uint8_t compressed;
- if (!in_buffer->Decode(&compressed))
+ if (!in_buffer->Decode(&compressed)) {
return false;
+ }
if (compressed > 0) {
// Decode compressed values.
if (!DecodeSymbols(static_cast<uint32_t>(num_values), num_components,
in_buffer,
- reinterpret_cast<uint32_t *>(portable_attribute_data)))
+ reinterpret_cast<uint32_t *>(portable_attribute_data))) {
return false;
+ }
} else {
// Decode the integer data directly.
// Get the number of bytes for a given entry.
uint8_t num_bytes;
- if (!in_buffer->Decode(&num_bytes))
+ if (!in_buffer->Decode(&num_bytes)) {
return false;
+ }
if (num_bytes == DataTypeLength(DT_INT32)) {
if (portable_attribute()->buffer()->data_size() <
- sizeof(int32_t) * num_values)
+ sizeof(int32_t) * num_values) {
return false;
+ }
if (!in_buffer->Decode(portable_attribute_data,
- sizeof(int32_t) * num_values))
+ sizeof(int32_t) * num_values)) {
return false;
+ }
} else {
- if (portable_attribute()->buffer()->data_size() < num_bytes * num_values)
+ if (portable_attribute()->buffer()->data_size() <
+ num_bytes * num_values) {
return false;
+ }
if (in_buffer->remaining_size() <
- static_cast<int64_t>(num_bytes) * static_cast<int64_t>(num_values))
+ static_cast<int64_t>(num_bytes) * static_cast<int64_t>(num_values)) {
return false;
+ }
for (size_t i = 0; i < num_values; ++i) {
- in_buffer->Decode(portable_attribute_data + i, num_bytes);
+ if (!in_buffer->Decode(portable_attribute_data + i, num_bytes))
+ return false;
}
}
}
@@ -138,8 +159,9 @@ bool SequentialIntegerAttributeDecoder::DecodeIntegerValues(
// If the data was encoded with a prediction scheme, we must revert it.
if (prediction_scheme_) {
- if (!prediction_scheme_->DecodePredictionData(in_buffer))
+ if (!prediction_scheme_->DecodePredictionData(in_buffer)) {
return false;
+ }
if (num_values > 0) {
if (!prediction_scheme_->ComputeOriginalValues(
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_integer_attribute_decoder.h b/extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.h
index 150ae1f831f..ef48ed817a5 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_integer_attribute_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.h
@@ -15,10 +15,9 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_INTEGER_ATTRIBUTE_DECODER_H_
#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_INTEGER_ATTRIBUTE_DECODER_H_
-#include "draco/draco_features.h"
-
#include "draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h"
#include "draco/compression/attributes/sequential_attribute_decoder.h"
+#include "draco/draco_features.h"
namespace draco {
@@ -56,8 +55,9 @@ class SequentialIntegerAttributeDecoder : public SequentialAttributeDecoder {
void PreparePortableAttribute(int num_entries, int num_components);
int32_t *GetPortableAttributeData() {
- if (portable_attribute()->size() == 0)
+ if (portable_attribute()->size() == 0) {
return nullptr;
+ }
return reinterpret_cast<int32_t *>(
portable_attribute()->GetAddress(AttributeValueIndex(0)));
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_integer_attribute_encoder.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.cc
index 0cae81d9f95..2889e0521a0 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_integer_attribute_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.cc
@@ -25,8 +25,9 @@ SequentialIntegerAttributeEncoder::SequentialIntegerAttributeEncoder() {}
bool SequentialIntegerAttributeEncoder::Init(PointCloudEncoder *encoder,
int attribute_id) {
- if (!SequentialAttributeEncoder::Init(encoder, attribute_id))
+ if (!SequentialAttributeEncoder::Init(encoder, attribute_id)) {
return false;
+ }
if (GetUniqueId() == SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER) {
// When encoding integers, this encoder currently works only for integer
// attributes up to 32 bits.
@@ -58,11 +59,13 @@ bool SequentialIntegerAttributeEncoder::Init(PointCloudEncoder *encoder,
bool SequentialIntegerAttributeEncoder::TransformAttributeToPortableFormat(
const std::vector<PointIndex> &point_ids) {
if (encoder()) {
- if (!PrepareValues(point_ids, encoder()->point_cloud()->num_points()))
+ if (!PrepareValues(point_ids, encoder()->point_cloud()->num_points())) {
return false;
+ }
} else {
- if (!PrepareValues(point_ids, 0))
+ if (!PrepareValues(point_ids, 0)) {
return false;
+ }
}
// Update point to attribute mapping with the portable attribute if the
@@ -100,8 +103,9 @@ bool SequentialIntegerAttributeEncoder::EncodeValues(
const std::vector<PointIndex> &point_ids, EncoderBuffer *out_buffer) {
// Initialize general quantization data.
const PointAttribute *const attrib = attribute();
- if (attrib->size() == 0)
+ if (attrib->size() == 0) {
return true;
+ }
int8_t prediction_scheme_method = PREDICTION_NONE;
if (prediction_scheme_) {
@@ -202,8 +206,9 @@ bool SequentialIntegerAttributeEncoder::PrepareValues(
for (PointIndex pi : point_ids) {
const AttributeValueIndex att_id = attrib->mapped_index(pi);
if (!attrib->ConvertValue<int32_t>(att_id,
- portable_attribute_data + dst_index))
+ portable_attribute_data + dst_index)) {
return false;
+ }
dst_index += num_components;
}
return true;
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_integer_attribute_encoder.h b/extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.h
index c1d6222ef40..c1d6222ef40 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_integer_attribute_encoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_normal_attribute_decoder.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.cc
index 2f208d50dbe..017344393dc 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_normal_attribute_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.cc
@@ -13,6 +13,7 @@
// limitations under the License.
//
#include "draco/compression/attributes/sequential_normal_attribute_decoder.h"
+
#include "draco/attributes/attribute_octahedron_transform.h"
#include "draco/compression/attributes/normal_compression_utils.h"
@@ -26,11 +27,13 @@ bool SequentialNormalAttributeDecoder::Init(PointCloudDecoder *decoder,
if (!SequentialIntegerAttributeDecoder::Init(decoder, attribute_id))
return false;
// Currently, this encoder works only for 3-component normal vectors.
- if (attribute()->num_components() != 3)
+ if (attribute()->num_components() != 3) {
return false;
+ }
// Also the data type must be DT_FLOAT32.
- if (attribute()->data_type() != DT_FLOAT32)
+ if (attribute()->data_type() != DT_FLOAT32) {
return false;
+ }
return true;
}
@@ -39,8 +42,9 @@ bool SequentialNormalAttributeDecoder::DecodeIntegerValues(
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
uint8_t quantization_bits;
- if (!in_buffer->Decode(&quantization_bits))
+ if (!in_buffer->Decode(&quantization_bits)) {
return false;
+ }
quantization_bits_ = quantization_bits;
}
#endif
@@ -53,8 +57,9 @@ bool SequentialNormalAttributeDecoder::DecodeDataNeededByPortableTransform(
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 (!in_buffer->Decode(&quantization_bits)) {
return false;
+ }
quantization_bits_ = quantization_bits;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_normal_attribute_decoder.h b/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.h
index d6439fcd6cf..860eacb4c84 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_normal_attribute_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.h
@@ -15,12 +15,11 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_NORMAL_ATTRIBUTE_DECODER_H_
#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_NORMAL_ATTRIBUTE_DECODER_H_
-#include "draco/draco_features.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"
#include "draco/compression/attributes/sequential_integer_attribute_decoder.h"
+#include "draco/draco_features.h"
namespace draco {
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_normal_attribute_encoder.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.cc
index af207a87111..23fa8bb7b39 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_normal_attribute_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.cc
@@ -13,6 +13,7 @@
// limitations under the License.
//
#include "draco/compression/attributes/sequential_normal_attribute_encoder.h"
+
#include "draco/compression/attributes/normal_compression_utils.h"
namespace draco {
@@ -22,14 +23,16 @@ bool SequentialNormalAttributeEncoder::Init(PointCloudEncoder *encoder,
if (!SequentialIntegerAttributeEncoder::Init(encoder, attribute_id))
return false;
// Currently this encoder works only for 3-component normal vectors.
- if (attribute()->num_components() != 3)
+ if (attribute()->num_components() != 3) {
return false;
+ }
// Initialize AttributeOctahedronTransform.
const int quantization_bits = encoder->options()->GetAttributeInt(
attribute_id, "quantization_bits", -1);
- if (quantization_bits < 1)
+ if (quantization_bits < 1) {
return false;
+ }
attribute_octahedron_transform_.SetParameters(quantization_bits);
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_normal_attribute_encoder.h b/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.h
index 53705c5982b..53705c5982b 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_normal_attribute_encoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc
index dfaf2edbe8e..bf925c4a595 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc
@@ -24,13 +24,15 @@ SequentialQuantizationAttributeDecoder::SequentialQuantizationAttributeDecoder()
bool SequentialQuantizationAttributeDecoder::Init(PointCloudDecoder *decoder,
int attribute_id) {
- if (!SequentialIntegerAttributeDecoder::Init(decoder, attribute_id))
+ if (!SequentialIntegerAttributeDecoder::Init(decoder, attribute_id)) {
return false;
+ }
const PointAttribute *const attribute =
decoder->point_cloud()->attribute(attribute_id);
// Currently we can quantize only floating point arguments.
- if (attribute->data_type() != DT_FLOAT32)
+ if (attribute->data_type() != DT_FLOAT32) {
return false;
+ }
return true;
}
@@ -38,8 +40,9 @@ bool SequentialQuantizationAttributeDecoder::DecodeIntegerValues(
const std::vector<PointIndex> &point_ids, DecoderBuffer *in_buffer) {
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0) &&
- !DecodeQuantizedDataInfo())
+ !DecodeQuantizedDataInfo()) {
return false;
+ }
#endif
return SequentialIntegerAttributeDecoder::DecodeIntegerValues(point_ids,
in_buffer);
@@ -50,8 +53,9 @@ bool SequentialQuantizationAttributeDecoder::
const std::vector<PointIndex> &point_ids, DecoderBuffer *in_buffer) {
if (decoder()->bitstream_version() >= DRACO_BITSTREAM_VERSION(2, 0)) {
// Decode quantization data here only for files with bitstream version 2.0+
- if (!DecodeQuantizedDataInfo())
+ if (!DecodeQuantizedDataInfo()) {
return false;
+ }
}
// Store the decoded transform data in portable attribute;
@@ -69,14 +73,17 @@ 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))
+ sizeof(float) * num_components)) {
return false;
- if (!decoder()->buffer()->Decode(&max_value_dif_))
+ }
+ if (!decoder()->buffer()->Decode(&max_value_dif_)) {
return false;
+ }
uint8_t quantization_bits;
if (!decoder()->buffer()->Decode(&quantization_bits) ||
- quantization_bits > 31)
+ quantization_bits > 31) {
return false;
+ }
quantization_bits_ = quantization_bits;
return true;
}
@@ -92,8 +99,9 @@ bool SequentialQuantizationAttributeDecoder::DequantizeValues(
int quant_val_id = 0;
int out_byte_pos = 0;
Dequantizer dequantizer;
- if (!dequantizer.Init(max_value_dif_, max_quantized_value))
+ 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) {
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_quantization_attribute_decoder.h b/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.h
index 27d88be72bd..c0b7637a750 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_quantization_attribute_decoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.h
@@ -15,9 +15,8 @@
#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_QUANTIZATION_ATTRIBUTE_DECODER_H_
#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_QUANTIZATION_ATTRIBUTE_DECODER_H_
-#include "draco/draco_features.h"
-
#include "draco/compression/attributes/sequential_integer_attribute_decoder.h"
+#include "draco/draco_features.h"
namespace draco {
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc b/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc
index 9110450061c..cd5b8b141e0 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc
@@ -23,19 +23,22 @@ SequentialQuantizationAttributeEncoder::
bool SequentialQuantizationAttributeEncoder::Init(PointCloudEncoder *encoder,
int attribute_id) {
- if (!SequentialIntegerAttributeEncoder::Init(encoder, attribute_id))
+ if (!SequentialIntegerAttributeEncoder::Init(encoder, attribute_id)) {
return false;
+ }
// This encoder currently works only for floating point attributes.
const PointAttribute *const attribute =
encoder->point_cloud()->attribute(attribute_id);
- if (attribute->data_type() != DT_FLOAT32)
+ if (attribute->data_type() != DT_FLOAT32) {
return false;
+ }
// Initialize AttributeQuantizationTransform.
const int quantization_bits = encoder->options()->GetAttributeInt(
attribute_id, "quantization_bits", -1);
- if (quantization_bits < 1)
+ if (quantization_bits < 1) {
return false;
+ }
if (encoder->options()->IsAttributeOptionSet(attribute_id,
"quantization_origin") &&
encoder->options()->IsAttributeOptionSet(attribute_id,
@@ -52,8 +55,10 @@ bool SequentialQuantizationAttributeEncoder::Init(PointCloudEncoder *encoder,
attribute->num_components(), range);
} else {
// Compute quantization settings from the attribute values.
- attribute_quantization_transform_.ComputeParameters(*attribute,
- quantization_bits);
+ if (!attribute_quantization_transform_.ComputeParameters(
+ *attribute, quantization_bits)) {
+ return false;
+ }
}
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_quantization_attribute_encoder.h b/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.h
index e9762bdd6d0..e9762bdd6d0 100644
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_quantization_attribute_encoder.h
+++ b/extern/draco/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h b/extern/draco/draco/src/draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h
index faacbd5b940..faacbd5b940 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h
+++ b/extern/draco/draco/src/draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.cc b/extern/draco/draco/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.cc
index 87ff7007a3d..056842c4a99 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.cc
@@ -26,15 +26,18 @@ bool AdaptiveRAnsBitDecoder::StartDecoding(DecoderBuffer *source_buffer) {
Clear();
uint32_t size_in_bytes;
- if (!source_buffer->Decode(&size_in_bytes))
+ if (!source_buffer->Decode(&size_in_bytes)) {
return false;
- if (size_in_bytes > source_buffer->remaining_size())
+ }
+ if (size_in_bytes > source_buffer->remaining_size()) {
return false;
+ }
if (ans_read_init(&ans_decoder_,
reinterpret_cast<uint8_t *>(
const_cast<char *>(source_buffer->data_head())),
- size_in_bytes) != 0)
+ size_in_bytes) != 0) {
return false;
+ }
source_buffer->Advance(size_in_bytes);
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.h b/extern/draco/draco/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.h
index a1ea011dd6a..a1ea011dd6a 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.h
+++ b/extern/draco/draco/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.cc b/extern/draco/draco/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.cc
index 5ce9dc388b8..5ce9dc388b8 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.cc
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.h b/extern/draco/draco/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.h
index 9b1832844ad..9b1832844ad 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.h
+++ b/extern/draco/draco/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/direct_bit_decoder.cc b/extern/draco/draco/src/draco/compression/bit_coders/direct_bit_decoder.cc
index 515ea9b52ee..2abe3382a4c 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/direct_bit_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/bit_coders/direct_bit_decoder.cc
@@ -23,19 +23,23 @@ DirectBitDecoder::~DirectBitDecoder() { Clear(); }
bool DirectBitDecoder::StartDecoding(DecoderBuffer *source_buffer) {
Clear();
uint32_t size_in_bytes;
- if (!source_buffer->Decode(&size_in_bytes))
+ if (!source_buffer->Decode(&size_in_bytes)) {
return false;
+ }
// Check that size_in_bytes is > 0 and a multiple of 4 as the encoder always
// encodes 32 bit elements.
- if (size_in_bytes == 0 || size_in_bytes & 0x3)
+ if (size_in_bytes == 0 || size_in_bytes & 0x3) {
return false;
- if (size_in_bytes > source_buffer->remaining_size())
+ }
+ if (size_in_bytes > source_buffer->remaining_size()) {
return false;
+ }
const uint32_t num_32bit_elements = size_in_bytes / 4;
bits_.resize(num_32bit_elements);
- if (!source_buffer->Decode(bits_.data(), size_in_bytes))
+ if (!source_buffer->Decode(bits_.data(), size_in_bytes)) {
return false;
+ }
pos_ = bits_.begin();
num_used_bits_ = 0;
return true;
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/direct_bit_decoder.h b/extern/draco/draco/src/draco/compression/bit_coders/direct_bit_decoder.h
index b9fbc2d6fed..b9fbc2d6fed 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/direct_bit_decoder.h
+++ b/extern/draco/draco/src/draco/compression/bit_coders/direct_bit_decoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/direct_bit_encoder.cc b/extern/draco/draco/src/draco/compression/bit_coders/direct_bit_encoder.cc
index d39143cf56a..d39143cf56a 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/direct_bit_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/bit_coders/direct_bit_encoder.cc
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/direct_bit_encoder.h b/extern/draco/draco/src/draco/compression/bit_coders/direct_bit_encoder.h
index 705b2ca93c2..705b2ca93c2 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/direct_bit_encoder.h
+++ b/extern/draco/draco/src/draco/compression/bit_coders/direct_bit_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/folded_integer_bit_decoder.h b/extern/draco/draco/src/draco/compression/bit_coders/folded_integer_bit_decoder.h
index 9f8bedd1eb0..c14058b6569 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/folded_integer_bit_decoder.h
+++ b/extern/draco/draco/src/draco/compression/bit_coders/folded_integer_bit_decoder.h
@@ -32,8 +32,9 @@ class FoldedBit32Decoder {
// Sets |source_buffer| as the buffer to decode bits from.
bool StartDecoding(DecoderBuffer *source_buffer) {
for (int i = 0; i < 32; i++) {
- if (!folded_number_decoders_[i].StartDecoding(source_buffer))
+ if (!folded_number_decoders_[i].StartDecoding(source_buffer)) {
return false;
+ }
}
return bit_decoder_.StartDecoding(source_buffer);
}
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/folded_integer_bit_encoder.h b/extern/draco/draco/src/draco/compression/bit_coders/folded_integer_bit_encoder.h
index 375b38a61fb..375b38a61fb 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/folded_integer_bit_encoder.h
+++ b/extern/draco/draco/src/draco/compression/bit_coders/folded_integer_bit_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/rans_bit_decoder.cc b/extern/draco/draco/src/draco/compression/bit_coders/rans_bit_decoder.cc
index 023e0dbc192..a9b8fb9e91e 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/rans_bit_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/bit_coders/rans_bit_decoder.cc
@@ -27,30 +27,35 @@ RAnsBitDecoder::~RAnsBitDecoder() { Clear(); }
bool RAnsBitDecoder::StartDecoding(DecoderBuffer *source_buffer) {
Clear();
- if (!source_buffer->Decode(&prob_zero_))
+ if (!source_buffer->Decode(&prob_zero_)) {
return false;
+ }
uint32_t size_in_bytes;
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (source_buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
- if (!source_buffer->Decode(&size_in_bytes))
+ if (!source_buffer->Decode(&size_in_bytes)) {
return false;
+ }
} else
#endif
{
- if (!DecodeVarint(&size_in_bytes, source_buffer))
+ if (!DecodeVarint(&size_in_bytes, source_buffer)) {
return false;
+ }
}
- if (size_in_bytes > source_buffer->remaining_size())
+ if (size_in_bytes > source_buffer->remaining_size()) {
return false;
+ }
if (ans_read_init(&ans_decoder_,
reinterpret_cast<uint8_t *>(
const_cast<char *>(source_buffer->data_head())),
- size_in_bytes) != 0)
+ size_in_bytes) != 0) {
return false;
+ }
source_buffer->Advance(size_in_bytes);
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/rans_bit_decoder.h b/extern/draco/draco/src/draco/compression/bit_coders/rans_bit_decoder.h
index 1fbf6a1324a..25d243eac16 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/rans_bit_decoder.h
+++ b/extern/draco/draco/src/draco/compression/bit_coders/rans_bit_decoder.h
@@ -18,10 +18,9 @@
#include <vector>
-#include "draco/draco_features.h"
-
#include "draco/compression/entropy/ans.h"
#include "draco/core/decoder_buffer.h"
+#include "draco/draco_features.h"
namespace draco {
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/rans_bit_encoder.cc b/extern/draco/draco/src/draco/compression/bit_coders/rans_bit_encoder.cc
index ea2972fe262..8d00ea35292 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/rans_bit_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/bit_coders/rans_bit_encoder.cc
@@ -72,8 +72,9 @@ void RAnsBitEncoder::EncodeLeastSignificantBits32(int nbits, uint32_t value) {
void RAnsBitEncoder::EndEncoding(EncoderBuffer *target_buffer) {
uint64_t total = bit_counts_[1] + bit_counts_[0];
- if (total == 0)
+ if (total == 0) {
total++;
+ }
// The probability interval [0,1] is mapped to values of [0, 256]. However,
// the coding scheme can not deal with probabilities of 0 or 1, which is why
@@ -83,8 +84,9 @@ void RAnsBitEncoder::EndEncoding(EncoderBuffer *target_buffer) {
((bit_counts_[0] / static_cast<double>(total)) * 256.0) + 0.5);
uint8_t zero_prob = 255;
- if (zero_prob_raw < 255)
+ if (zero_prob_raw < 255) {
zero_prob = static_cast<uint8_t>(zero_prob_raw);
+ }
zero_prob += (zero_prob == 0);
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/rans_bit_encoder.h b/extern/draco/draco/src/draco/compression/bit_coders/rans_bit_encoder.h
index 1993dd3d3c2..1993dd3d3c2 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/rans_bit_encoder.h
+++ b/extern/draco/draco/src/draco/compression/bit_coders/rans_bit_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/symbol_bit_decoder.cc b/extern/draco/draco/src/draco/compression/bit_coders/symbol_bit_decoder.cc
index 6b35ae3f87f..8ed50ef92ec 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/symbol_bit_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/bit_coders/symbol_bit_decoder.cc
@@ -6,12 +6,14 @@ namespace draco {
bool SymbolBitDecoder::StartDecoding(DecoderBuffer *source_buffer) {
uint32_t size;
- if (!source_buffer->Decode(&size))
+ if (!source_buffer->Decode(&size)) {
return false;
+ }
symbols_.resize(size);
- if (!DecodeSymbols(size, 1, source_buffer, symbols_.data()))
+ if (!DecodeSymbols(size, 1, source_buffer, symbols_.data())) {
return false;
+ }
std::reverse(symbols_.begin(), symbols_.end());
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/symbol_bit_decoder.h b/extern/draco/draco/src/draco/compression/bit_coders/symbol_bit_decoder.h
index 909d7174fb5..909d7174fb5 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/symbol_bit_decoder.h
+++ b/extern/draco/draco/src/draco/compression/bit_coders/symbol_bit_decoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/symbol_bit_encoder.cc b/extern/draco/draco/src/draco/compression/bit_coders/symbol_bit_encoder.cc
index 83834236fa5..83834236fa5 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/symbol_bit_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/bit_coders/symbol_bit_encoder.cc
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/symbol_bit_encoder.h b/extern/draco/draco/src/draco/compression/bit_coders/symbol_bit_encoder.h
index 7f1570c1a7c..7f1570c1a7c 100644
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/symbol_bit_encoder.h
+++ b/extern/draco/draco/src/draco/compression/bit_coders/symbol_bit_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/config/compression_shared.h b/extern/draco/draco/src/draco/compression/config/compression_shared.h
index 5204fbc1f3e..40061d3cd48 100644
--- a/extern/draco/dracoenc/src/draco/compression/config/compression_shared.h
+++ b/extern/draco/draco/src/draco/compression/config/compression_shared.h
@@ -18,7 +18,6 @@
#include <stdint.h>
#include "draco/core/macros.h"
-
#include "draco/draco_features.h"
namespace draco {
diff --git a/extern/draco/dracoenc/src/draco/compression/config/decoder_options.h b/extern/draco/draco/src/draco/compression/config/decoder_options.h
index 3b3889993e2..3b3889993e2 100644
--- a/extern/draco/dracoenc/src/draco/compression/config/decoder_options.h
+++ b/extern/draco/draco/src/draco/compression/config/decoder_options.h
diff --git a/extern/draco/dracoenc/src/draco/compression/config/draco_options.h b/extern/draco/draco/src/draco/compression/config/draco_options.h
index c77f5df4014..0d1247b2ad1 100644
--- a/extern/draco/dracoenc/src/draco/compression/config/draco_options.h
+++ b/extern/draco/draco/src/draco/compression/config/draco_options.h
@@ -159,8 +159,9 @@ int DracoOptions<AttributeKeyT>::GetAttributeInt(const AttributeKeyT &att_key,
const std::string &name,
int default_val) const {
const Options *const att_options = FindAttributeOptions(att_key);
- if (att_options && att_options->IsOptionSet(name))
+ if (att_options && att_options->IsOptionSet(name)) {
return att_options->GetInt(name, default_val);
+ }
return global_options_.GetInt(name, default_val);
}
@@ -176,8 +177,9 @@ float DracoOptions<AttributeKeyT>::GetAttributeFloat(
const AttributeKeyT &att_key, const std::string &name,
float default_val) const {
const Options *const att_options = FindAttributeOptions(att_key);
- if (att_options && att_options->IsOptionSet(name))
+ if (att_options && att_options->IsOptionSet(name)) {
return att_options->GetFloat(name, default_val);
+ }
return global_options_.GetFloat(name, default_val);
}
@@ -192,8 +194,9 @@ bool DracoOptions<AttributeKeyT>::GetAttributeBool(const AttributeKeyT &att_key,
const std::string &name,
bool default_val) const {
const Options *const att_options = FindAttributeOptions(att_key);
- if (att_options && att_options->IsOptionSet(name))
+ if (att_options && att_options->IsOptionSet(name)) {
return att_options->GetBool(name, default_val);
+ }
return global_options_.GetBool(name, default_val);
}
@@ -210,8 +213,9 @@ bool DracoOptions<AttributeKeyT>::GetAttributeVector(
const AttributeKey &att_key, const std::string &name, int num_dims,
DataTypeT *val) const {
const Options *const att_options = FindAttributeOptions(att_key);
- if (att_options && att_options->IsOptionSet(name))
+ if (att_options && att_options->IsOptionSet(name)) {
return att_options->GetVector(name, num_dims, val);
+ }
return global_options_.GetVector(name, num_dims, val);
}
@@ -227,8 +231,9 @@ template <typename AttributeKeyT>
bool DracoOptions<AttributeKeyT>::IsAttributeOptionSet(
const AttributeKey &att_key, const std::string &name) const {
const Options *const att_options = FindAttributeOptions(att_key);
- if (att_options)
+ if (att_options) {
return att_options->IsOptionSet(name);
+ }
return global_options_.IsOptionSet(name);
}
diff --git a/extern/draco/dracoenc/src/draco/compression/config/encoder_options.h b/extern/draco/draco/src/draco/compression/config/encoder_options.h
index aacd58e0187..ed1b020683d 100644
--- a/extern/draco/dracoenc/src/draco/compression/config/encoder_options.h
+++ b/extern/draco/draco/src/draco/compression/config/encoder_options.h
@@ -15,11 +15,10 @@
#ifndef DRACO_COMPRESSION_CONFIG_ENCODER_OPTIONS_H_
#define DRACO_COMPRESSION_CONFIG_ENCODER_OPTIONS_H_
-#include "draco/draco_features.h"
-
#include "draco/attributes/geometry_attribute.h"
#include "draco/compression/config/draco_options.h"
#include "draco/compression/config/encoding_features.h"
+#include "draco/draco_features.h"
namespace draco {
@@ -56,8 +55,9 @@ class EncoderOptionsBase : public DracoOptions<AttributeKeyT> {
const int encoding_speed = this->GetGlobalInt("encoding_speed", -1);
const int decoding_speed = this->GetGlobalInt("decoding_speed", -1);
const int max_speed = std::max(encoding_speed, decoding_speed);
- if (max_speed == -1)
+ if (max_speed == -1) {
return 5; // Default value.
+ }
return max_speed;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/config/encoding_features.h b/extern/draco/draco/src/draco/compression/config/encoding_features.h
index d6a8b7128a8..d6a8b7128a8 100644
--- a/extern/draco/dracoenc/src/draco/compression/config/encoding_features.h
+++ b/extern/draco/draco/src/draco/compression/config/encoding_features.h
diff --git a/extern/draco/dracoenc/src/draco/compression/decode.cc b/extern/draco/draco/src/draco/compression/decode.cc
index ab70ef1ec60..ab70ef1ec60 100644
--- a/extern/draco/dracoenc/src/draco/compression/decode.cc
+++ b/extern/draco/draco/src/draco/compression/decode.cc
diff --git a/extern/draco/dracoenc/src/draco/compression/decode.h b/extern/draco/draco/src/draco/compression/decode.h
index 0216d72586a..5f3fad26bb4 100644
--- a/extern/draco/dracoenc/src/draco/compression/decode.h
+++ b/extern/draco/draco/src/draco/compression/decode.h
@@ -15,12 +15,11 @@
#ifndef DRACO_COMPRESSION_DECODE_H_
#define DRACO_COMPRESSION_DECODE_H_
-#include "draco/draco_features.h"
-
#include "draco/compression/config/compression_shared.h"
#include "draco/compression/config/decoder_options.h"
#include "draco/core/decoder_buffer.h"
#include "draco/core/status_or.h"
+#include "draco/draco_features.h"
#include "draco/mesh/mesh.h"
namespace draco {
diff --git a/extern/draco/dracoenc/src/draco/compression/encode.cc b/extern/draco/draco/src/draco/compression/encode.cc
index 5de05ace81f..f380aec1591 100644
--- a/extern/draco/dracoenc/src/draco/compression/encode.cc
+++ b/extern/draco/draco/src/draco/compression/encode.cc
@@ -85,8 +85,9 @@ void Encoder::SetEncodingMethod(int encoding_method) {
Status Encoder::SetAttributePredictionScheme(GeometryAttribute::Type type,
int prediction_scheme_method) {
Status status = CheckPredictionScheme(type, prediction_scheme_method);
- if (!status.ok())
+ if (!status.ok()) {
return status;
+ }
options().SetAttributeInt(type, "prediction_scheme",
prediction_scheme_method);
return status;
diff --git a/extern/draco/dracoenc/src/draco/compression/encode.h b/extern/draco/draco/src/draco/compression/encode.h
index bce8b34c238..bce8b34c238 100644
--- a/extern/draco/dracoenc/src/draco/compression/encode.h
+++ b/extern/draco/draco/src/draco/compression/encode.h
diff --git a/extern/draco/dracoenc/src/draco/compression/encode_base.h b/extern/draco/draco/src/draco/compression/encode_base.h
index 451d970eb6f..0c63a972bf4 100644
--- a/extern/draco/dracoenc/src/draco/compression/encode_base.h
+++ b/extern/draco/draco/src/draco/compression/encode_base.h
@@ -68,24 +68,29 @@ class EncoderBase {
Status CheckPredictionScheme(GeometryAttribute::Type att_type,
int prediction_scheme) const {
// Out of bound checks:
- if (prediction_scheme < PREDICTION_NONE)
+ if (prediction_scheme < PREDICTION_NONE) {
return Status(Status::DRACO_ERROR,
"Invalid prediction scheme requested.");
- if (prediction_scheme >= NUM_PREDICTION_SCHEMES)
+ }
+ if (prediction_scheme >= NUM_PREDICTION_SCHEMES) {
return Status(Status::DRACO_ERROR,
"Invalid prediction scheme requested.");
+ }
// Deprecated prediction schemes:
- if (prediction_scheme == MESH_PREDICTION_TEX_COORDS_DEPRECATED)
+ if (prediction_scheme == MESH_PREDICTION_TEX_COORDS_DEPRECATED) {
return Status(Status::DRACO_ERROR,
"MESH_PREDICTION_TEX_COORDS_DEPRECATED is deprecated.");
- if (prediction_scheme == MESH_PREDICTION_MULTI_PARALLELOGRAM)
+ }
+ if (prediction_scheme == MESH_PREDICTION_MULTI_PARALLELOGRAM) {
return Status(Status::DRACO_ERROR,
"MESH_PREDICTION_MULTI_PARALLELOGRAM is deprecated.");
+ }
// Attribute specific checks:
if (prediction_scheme == MESH_PREDICTION_TEX_COORDS_PORTABLE) {
- if (att_type != GeometryAttribute::TEX_COORD)
+ if (att_type != GeometryAttribute::TEX_COORD) {
return Status(Status::DRACO_ERROR,
"Invalid prediction scheme for attribute type.");
+ }
}
if (prediction_scheme == MESH_PREDICTION_GEOMETRIC_NORMAL) {
if (att_type != GeometryAttribute::NORMAL) {
diff --git a/extern/draco/dracoenc/src/draco/compression/entropy/ans.h b/extern/draco/draco/src/draco/compression/entropy/ans.h
index 310ae256667..c765256b96e 100644
--- a/extern/draco/dracoenc/src/draco/compression/entropy/ans.h
+++ b/extern/draco/draco/src/draco/compression/entropy/ans.h
@@ -255,11 +255,12 @@ static inline void uabs_write(struct AnsCoder *ans, int val, AnsP8 p0) {
ans->buf[ans->buf_offset++] = ans->state % DRACO_ANS_IO_BASE;
ans->state /= DRACO_ANS_IO_BASE;
}
- if (!val)
+ if (!val) {
ans->state = DRACO_ANS_DIV(ans->state * DRACO_ANS_P8_PRECISION, p0);
- else
+ } else {
ans->state =
DRACO_ANS_DIV((ans->state + 1) * DRACO_ANS_P8_PRECISION + p - 1, p) - 1;
+ }
}
static inline int uabs_read(struct AnsDecoder *ans, AnsP8 p0) {
@@ -276,10 +277,11 @@ static inline int uabs_read(struct AnsDecoder *ans, AnsP8 p0) {
xp = sp / DRACO_ANS_P8_PRECISION;
// s = xp1 - xp;
s = (sp & 0xFF) >= p0;
- if (UNPREDICTABLE(s))
+ if (UNPREDICTABLE(s)) {
ans->state = xp;
- else
+ } else {
ans->state = state - xp;
+ }
return s;
}
@@ -297,29 +299,33 @@ static inline int uabs_read_bit(struct AnsDecoder *ans) {
static inline int ans_read_init(struct AnsDecoder *const ans,
const uint8_t *const buf, int offset) {
unsigned x;
- if (offset < 1)
+ if (offset < 1) {
return 1;
+ }
ans->buf = buf;
x = buf[offset - 1] >> 6;
if (x == 0) {
ans->buf_offset = offset - 1;
ans->state = buf[offset - 1] & 0x3F;
} else if (x == 1) {
- if (offset < 2)
+ if (offset < 2) {
return 1;
+ }
ans->buf_offset = offset - 2;
ans->state = mem_get_le16(buf + offset - 2) & 0x3FFF;
} else if (x == 2) {
- if (offset < 3)
+ if (offset < 3) {
return 1;
+ }
ans->buf_offset = offset - 3;
ans->state = mem_get_le24(buf + offset - 3) & 0x3FFFFF;
} else {
return 1;
}
ans->state += DRACO_ANS_L_BASE;
- if (ans->state >= DRACO_ANS_L_BASE * DRACO_ANS_IO_BASE)
+ if (ans->state >= DRACO_ANS_L_BASE * DRACO_ANS_IO_BASE) {
return 1;
+ }
return 0;
}
@@ -415,21 +421,24 @@ class RAnsDecoder {
// error.
inline int read_init(const uint8_t *const buf, int offset) {
unsigned x;
- if (offset < 1)
+ if (offset < 1) {
return 1;
+ }
ans_.buf = buf;
x = buf[offset - 1] >> 6;
if (x == 0) {
ans_.buf_offset = offset - 1;
ans_.state = buf[offset - 1] & 0x3F;
} else if (x == 1) {
- if (offset < 2)
+ if (offset < 2) {
return 1;
+ }
ans_.buf_offset = offset - 2;
ans_.state = mem_get_le16(buf + offset - 2) & 0x3FFF;
} else if (x == 2) {
- if (offset < 3)
+ if (offset < 3) {
return 1;
+ }
ans_.buf_offset = offset - 3;
ans_.state = mem_get_le24(buf + offset - 3) & 0x3FFFFF;
} else if (x == 3) {
@@ -439,8 +448,9 @@ class RAnsDecoder {
return 1;
}
ans_.state += l_rans_base;
- if (ans_.state >= l_rans_base * DRACO_ANS_IO_BASE)
+ if (ans_.state >= l_rans_base * DRACO_ANS_IO_BASE) {
return 1;
+ }
return 0;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/entropy/rans_symbol_coding.h b/extern/draco/draco/src/draco/compression/entropy/rans_symbol_coding.h
index 0a68e29fe26..0a68e29fe26 100644
--- a/extern/draco/dracoenc/src/draco/compression/entropy/rans_symbol_coding.h
+++ b/extern/draco/draco/src/draco/compression/entropy/rans_symbol_coding.h
diff --git a/extern/draco/dracoenc/src/draco/compression/entropy/rans_symbol_decoder.h b/extern/draco/draco/src/draco/compression/entropy/rans_symbol_decoder.h
index 1b5f1c8b715..10cdc6781a0 100644
--- a/extern/draco/dracoenc/src/draco/compression/entropy/rans_symbol_decoder.h
+++ b/extern/draco/draco/src/draco/compression/entropy/rans_symbol_decoder.h
@@ -15,12 +15,11 @@
#ifndef DRACO_COMPRESSION_ENTROPY_RANS_SYMBOL_DECODER_H_
#define DRACO_COMPRESSION_ENTROPY_RANS_SYMBOL_DECODER_H_
-#include "draco/draco_features.h"
-
#include "draco/compression/config/compression_shared.h"
#include "draco/compression/entropy/rans_symbol_coding.h"
#include "draco/core/decoder_buffer.h"
#include "draco/core/varint_decoding.h"
+#include "draco/draco_features.h"
namespace draco {
@@ -59,30 +58,35 @@ template <int unique_symbols_bit_length_t>
bool RAnsSymbolDecoder<unique_symbols_bit_length_t>::Create(
DecoderBuffer *buffer) {
// Check that the DecoderBuffer version is set.
- if (buffer->bitstream_version() == 0)
+ if (buffer->bitstream_version() == 0) {
return false;
- // Decode the number of alphabet symbols.
+ }
+ // Decode the number of alphabet symbols.
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
- if (!buffer->Decode(&num_symbols_))
+ if (!buffer->Decode(&num_symbols_)) {
return false;
+ }
} else
#endif
{
- if (!DecodeVarint(&num_symbols_, buffer))
+ if (!DecodeVarint(&num_symbols_, buffer)) {
return false;
+ }
}
probability_table_.resize(num_symbols_);
- if (num_symbols_ == 0)
+ if (num_symbols_ == 0) {
return true;
+ }
// Decode the table.
for (uint32_t i = 0; i < num_symbols_; ++i) {
uint8_t prob_data = 0;
// Decode the first byte and extract the number of extra bytes we need to
// get, or the offset to the next symbol with non-zero probability.
- if (!buffer->Decode(&prob_data))
+ if (!buffer->Decode(&prob_data)) {
return false;
+ }
// Token is stored in the first two bits of the first byte. Values 0-2 are
// used to indicate the number of extra bytes, and value 3 is a special
// symbol used to denote run-length coding of zero probability entries.
@@ -90,8 +94,9 @@ bool RAnsSymbolDecoder<unique_symbols_bit_length_t>::Create(
const int token = prob_data & 3;
if (token == 3) {
const uint32_t offset = prob_data >> 2;
- if (i + offset >= num_symbols_)
+ if (i + offset >= num_symbols_) {
return false;
+ }
// Set zero probability for all symbols in the specified range.
for (uint32_t j = 0; j < offset + 1; ++j) {
probability_table_[i + j] = 0;
@@ -102,8 +107,9 @@ bool RAnsSymbolDecoder<unique_symbols_bit_length_t>::Create(
uint32_t prob = prob_data >> 2;
for (int b = 0; b < extra_bytes; ++b) {
uint8_t eb;
- if (!buffer->Decode(&eb))
+ if (!buffer->Decode(&eb)) {
return false;
+ }
// Shift 8 bits for each extra byte and subtract 2 for the two first
// bits.
prob |= static_cast<uint32_t>(eb) << (8 * (b + 1) - 2);
@@ -111,8 +117,9 @@ bool RAnsSymbolDecoder<unique_symbols_bit_length_t>::Create(
probability_table_[i] = prob;
}
}
- if (!ans_.rans_build_look_up_table(&probability_table_[0], num_symbols_))
+ if (!ans_.rans_build_look_up_table(&probability_table_[0], num_symbols_)) {
return false;
+ }
return true;
}
@@ -123,23 +130,27 @@ bool RAnsSymbolDecoder<unique_symbols_bit_length_t>::StartDecoding(
// Decode the number of bytes encoded by the encoder.
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
- if (!buffer->Decode(&bytes_encoded))
+ if (!buffer->Decode(&bytes_encoded)) {
return false;
+ }
} else
#endif
{
- if (!DecodeVarint<uint64_t>(&bytes_encoded, buffer))
+ if (!DecodeVarint<uint64_t>(&bytes_encoded, buffer)) {
return false;
+ }
}
- if (bytes_encoded > static_cast<uint64_t>(buffer->remaining_size()))
+ if (bytes_encoded > static_cast<uint64_t>(buffer->remaining_size())) {
return false;
+ }
const uint8_t *const data_head =
reinterpret_cast<const uint8_t *>(buffer->data_head());
// Advance the buffer past the rANS data.
buffer->Advance(bytes_encoded);
- if (ans_.read_init(data_head, static_cast<int>(bytes_encoded)) != 0)
+ if (ans_.read_init(data_head, static_cast<int>(bytes_encoded)) != 0) {
return false;
+ }
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/entropy/rans_symbol_encoder.h b/extern/draco/draco/src/draco/compression/entropy/rans_symbol_encoder.h
index 4b0ed091af0..4e07ec87123 100644
--- a/extern/draco/dracoenc/src/draco/compression/entropy/rans_symbol_encoder.h
+++ b/extern/draco/draco/src/draco/compression/entropy/rans_symbol_encoder.h
@@ -91,8 +91,9 @@ bool RAnsSymbolEncoder<unique_symbols_bit_length_t>::Create(
int max_valid_symbol = 0;
for (int i = 0; i < num_symbols; ++i) {
total_freq += frequencies[i];
- if (frequencies[i] > 0)
+ if (frequencies[i] > 0) {
max_valid_symbol = i;
+ }
}
num_symbols = max_valid_symbol + 1;
num_symbols_ = num_symbols;
@@ -111,8 +112,9 @@ bool RAnsSymbolEncoder<unique_symbols_bit_length_t>::Create(
// RAns probability in range of [1, rans_precision - 1].
uint32_t rans_prob = static_cast<uint32_t>(prob * rans_precision_d + 0.5f);
- if (rans_prob == 0 && freq > 0)
+ if (rans_prob == 0 && freq > 0) {
rans_prob = 1;
+ }
probability_table_[i].prob = rans_prob;
total_rans_prob += rans_prob;
}
@@ -140,25 +142,30 @@ bool RAnsSymbolEncoder<unique_symbols_bit_length_t>::Create(
for (int j = num_symbols - 1; j > 0; --j) {
int symbol_id = sorted_probabilities[j];
if (probability_table_[symbol_id].prob <= 1) {
- if (j == num_symbols - 1)
+ if (j == num_symbols - 1) {
return false; // Most frequent symbol would be empty.
+ }
break;
}
const int32_t new_prob = static_cast<int32_t>(
floor(act_rel_error_d *
static_cast<double>(probability_table_[symbol_id].prob)));
int32_t fix = probability_table_[symbol_id].prob - new_prob;
- if (fix == 0u)
+ if (fix == 0u) {
fix = 1;
- if (fix >= static_cast<int32_t>(probability_table_[symbol_id].prob))
+ }
+ if (fix >= static_cast<int32_t>(probability_table_[symbol_id].prob)) {
fix = probability_table_[symbol_id].prob - 1;
- if (fix > error)
+ }
+ if (fix > error) {
fix = error;
+ }
probability_table_[symbol_id].prob -= fix;
total_rans_prob -= fix;
error -= fix;
- if (total_rans_prob == rans_precision_)
+ if (total_rans_prob == rans_precision_) {
break;
+ }
}
}
}
@@ -170,8 +177,9 @@ bool RAnsSymbolEncoder<unique_symbols_bit_length_t>::Create(
probability_table_[i].cum_prob = total_prob;
total_prob += probability_table_[i].prob;
}
- if (total_prob != rans_precision_)
+ if (total_prob != rans_precision_) {
return false;
+ }
// Estimate the number of bits needed to encode the input.
// From Shannon entropy the total number of bits N is:
@@ -180,15 +188,17 @@ bool RAnsSymbolEncoder<unique_symbols_bit_length_t>::Create(
// symbol's frequency in the input data.
double num_bits = 0;
for (int i = 0; i < num_symbols; ++i) {
- if (probability_table_[i].prob == 0)
+ if (probability_table_[i].prob == 0) {
continue;
+ }
const double norm_prob =
static_cast<double>(probability_table_[i].prob) / rans_precision_d;
num_bits += static_cast<double>(frequencies[i]) * log2(norm_prob);
}
num_expected_bits_ = static_cast<uint64_t>(ceil(-num_bits));
- if (!EncodeTable(buffer))
+ if (!EncodeTable(buffer)) {
return false;
+ }
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/entropy/shannon_entropy.cc b/extern/draco/draco/src/draco/compression/entropy/shannon_entropy.cc
index 5050c11188c..137eafe5fac 100644
--- a/extern/draco/dracoenc/src/draco/compression/entropy/shannon_entropy.cc
+++ b/extern/draco/draco/src/draco/compression/entropy/shannon_entropy.cc
@@ -27,20 +27,23 @@ int64_t ComputeShannonEntropy(const uint32_t *symbols, int num_symbols,
log2(static_cast<double>(symbol_frequencies[i]) / num_symbols_d);
}
}
- if (out_num_unique_symbols)
+ if (out_num_unique_symbols) {
*out_num_unique_symbols = num_unique_symbols;
+ }
// Entropy is always negative.
return static_cast<int64_t>(-total_bits);
}
double ComputeBinaryShannonEntropy(uint32_t num_values,
uint32_t num_true_values) {
- if (num_values == 0)
+ if (num_values == 0) {
return 0;
+ }
// We can exit early if the data set has 0 entropy.
- if (num_true_values == 0 || num_values == num_true_values)
+ if (num_true_values == 0 || num_values == num_true_values) {
return 0;
+ }
const double true_freq =
static_cast<double>(num_true_values) / static_cast<double>(num_values);
const double false_freq = 1.0 - true_freq;
@@ -120,8 +123,9 @@ ShannonEntropyTracker::EntropyData ShannonEntropyTracker::UpdateSymbols(
int64_t ShannonEntropyTracker::GetNumberOfDataBits(
const EntropyData &entropy_data) {
- if (entropy_data.num_values < 2)
+ if (entropy_data.num_values < 2) {
return 0;
+ }
// We need to compute the number of bits required to represent the stream
// using the entropy norm. Note that:
//
diff --git a/extern/draco/dracoenc/src/draco/compression/entropy/shannon_entropy.h b/extern/draco/draco/src/draco/compression/entropy/shannon_entropy.h
index 85165f4cb8d..85165f4cb8d 100644
--- a/extern/draco/dracoenc/src/draco/compression/entropy/shannon_entropy.h
+++ b/extern/draco/draco/src/draco/compression/entropy/shannon_entropy.h
diff --git a/extern/draco/dracoenc/src/draco/compression/entropy/symbol_decoding.cc b/extern/draco/draco/src/draco/compression/entropy/symbol_decoding.cc
index 39a1eb0ff24..93d29971c89 100644
--- a/extern/draco/dracoenc/src/draco/compression/entropy/symbol_decoding.cc
+++ b/extern/draco/draco/src/draco/compression/entropy/symbol_decoding.cc
@@ -31,12 +31,14 @@ bool DecodeRawSymbols(uint32_t num_values, DecoderBuffer *src_buffer,
bool DecodeSymbols(uint32_t num_values, int num_components,
DecoderBuffer *src_buffer, uint32_t *out_values) {
- if (num_values == 0)
+ if (num_values == 0) {
return true;
+ }
// Decode which scheme to use.
uint8_t scheme;
- if (!src_buffer->Decode(&scheme))
+ if (!src_buffer->Decode(&scheme)) {
return false;
+ }
if (scheme == SYMBOL_CODING_TAGGED) {
return DecodeTaggedSymbols<RAnsSymbolDecoder>(num_values, num_components,
src_buffer, out_values);
@@ -52,14 +54,17 @@ bool DecodeTaggedSymbols(uint32_t num_values, int num_components,
DecoderBuffer *src_buffer, uint32_t *out_values) {
// Decode the encoded data.
SymbolDecoderT<5> tag_decoder;
- if (!tag_decoder.Create(src_buffer))
+ if (!tag_decoder.Create(src_buffer)) {
return false;
+ }
- if (!tag_decoder.StartDecoding(src_buffer))
+ if (!tag_decoder.StartDecoding(src_buffer)) {
return false;
+ }
- if (num_values > 0 && tag_decoder.num_symbols() == 0)
+ if (num_values > 0 && tag_decoder.num_symbols() == 0) {
return false; // Wrong number of symbols.
+ }
// src_buffer now points behind the encoded tag data (to the place where the
// values are encoded).
@@ -71,8 +76,9 @@ bool DecodeTaggedSymbols(uint32_t num_values, int num_components,
// Decode the actual value.
for (int j = 0; j < num_components; ++j) {
uint32_t val;
- if (!src_buffer->DecodeLeastSignificantBits32(bit_length, &val))
+ if (!src_buffer->DecodeLeastSignificantBits32(bit_length, &val)) {
return false;
+ }
out_values[value_id++] = val;
}
}
@@ -85,14 +91,17 @@ template <class SymbolDecoderT>
bool DecodeRawSymbolsInternal(uint32_t num_values, DecoderBuffer *src_buffer,
uint32_t *out_values) {
SymbolDecoderT decoder;
- if (!decoder.Create(src_buffer))
+ if (!decoder.Create(src_buffer)) {
return false;
+ }
- if (num_values > 0 && decoder.num_symbols() == 0)
+ if (num_values > 0 && decoder.num_symbols() == 0) {
return false; // Wrong number of symbols.
+ }
- if (!decoder.StartDecoding(src_buffer))
+ if (!decoder.StartDecoding(src_buffer)) {
return false;
+ }
for (uint32_t i = 0; i < num_values; ++i) {
// Decode a symbol into the value.
const uint32_t value = decoder.DecodeSymbol();
@@ -106,8 +115,9 @@ template <template <int> class SymbolDecoderT>
bool DecodeRawSymbols(uint32_t num_values, DecoderBuffer *src_buffer,
uint32_t *out_values) {
uint8_t max_bit_length;
- if (!src_buffer->Decode(&max_bit_length))
+ if (!src_buffer->Decode(&max_bit_length)) {
return false;
+ }
switch (max_bit_length) {
case 1:
return DecodeRawSymbolsInternal<SymbolDecoderT<1>>(num_values, src_buffer,
diff --git a/extern/draco/dracoenc/src/draco/compression/entropy/symbol_decoding.h b/extern/draco/draco/src/draco/compression/entropy/symbol_decoding.h
index ea11165c347..ea11165c347 100644
--- a/extern/draco/dracoenc/src/draco/compression/entropy/symbol_decoding.h
+++ b/extern/draco/draco/src/draco/compression/entropy/symbol_decoding.h
diff --git a/extern/draco/dracoenc/src/draco/compression/entropy/symbol_encoding.cc b/extern/draco/draco/src/draco/compression/entropy/symbol_encoding.cc
index 9a5868c40a5..710c96284da 100644
--- a/extern/draco/dracoenc/src/draco/compression/entropy/symbol_encoding.cc
+++ b/extern/draco/draco/src/draco/compression/entropy/symbol_encoding.cc
@@ -36,8 +36,9 @@ void SetSymbolEncodingMethod(Options *options, SymbolCodingMethod method) {
bool SetSymbolEncodingCompressionLevel(Options *options,
int compression_level) {
- if (compression_level < 0 || compression_level > 10)
+ if (compression_level < 0 || compression_level > 10) {
return false;
+ }
options->SetInt("symbol_encoding_compression_level", compression_level);
return true;
}
@@ -56,8 +57,9 @@ static void ComputeBitLengths(const uint32_t *symbols, int num_values,
// Get the maximum value for a given entry across all attribute components.
uint32_t max_component_value = symbols[i];
for (int j = 1; j < num_components; ++j) {
- if (max_component_value < symbols[i + j])
+ if (max_component_value < symbols[i + j]) {
max_component_value = symbols[i + j];
+ }
}
int value_msb_pos = 0;
if (max_component_value > 0) {
@@ -113,12 +115,15 @@ bool EncodeRawSymbols(const uint32_t *symbols, int num_values,
bool EncodeSymbols(const uint32_t *symbols, int num_values, int num_components,
const Options *options, EncoderBuffer *target_buffer) {
- if (num_values < 0)
+ if (num_values < 0) {
return false;
- if (num_values == 0)
+ }
+ if (num_values == 0) {
return true;
- if (num_components <= 0)
+ }
+ if (num_components <= 0) {
num_components = 1;
+ }
std::vector<uint32_t> bit_lengths;
uint32_t max_value;
ComputeBitLengths(symbols, num_values, num_components, &bit_lengths,
@@ -275,8 +280,9 @@ bool EncodeRawSymbols(const uint32_t *symbols, int num_values,
}
int unique_symbols_bit_length = symbol_bits + 1;
// Currently, we don't support encoding of more than 2^18 unique symbols.
- if (unique_symbols_bit_length > kMaxRawEncodingBitLength)
+ if (unique_symbols_bit_length > kMaxRawEncodingBitLength) {
return false;
+ }
int compression_level = kDefaultSymbolCodingCompressionLevel;
if (options != nullptr &&
options->IsOptionSet("symbol_encoding_compression_level")) {
diff --git a/extern/draco/dracoenc/src/draco/compression/entropy/symbol_encoding.h b/extern/draco/draco/src/draco/compression/entropy/symbol_encoding.h
index 839b28b17a5..839b28b17a5 100644
--- a/extern/draco/dracoenc/src/draco/compression/entropy/symbol_encoding.h
+++ b/extern/draco/draco/src/draco/compression/entropy/symbol_encoding.h
diff --git a/extern/draco/dracoenc/src/draco/compression/expert_encode.cc b/extern/draco/draco/src/draco/compression/expert_encode.cc
index 112e6ae3d3e..4c70a72a765 100644
--- a/extern/draco/dracoenc/src/draco/compression/expert_encode.cc
+++ b/extern/draco/draco/src/draco/compression/expert_encode.cc
@@ -30,8 +30,9 @@ ExpertEncoder::ExpertEncoder(const Mesh &mesh)
: point_cloud_(&mesh), mesh_(&mesh) {}
Status ExpertEncoder::EncodeToBuffer(EncoderBuffer *out_buffer) {
- if (point_cloud_ == nullptr)
+ if (point_cloud_ == nullptr) {
return Status(Status::DRACO_ERROR, "Invalid input geometry.");
+ }
if (mesh_ == nullptr) {
return EncodePointCloudToBuffer(*point_cloud_, out_buffer);
}
@@ -62,13 +63,16 @@ Status ExpertEncoder::EncodePointCloudToBuffer(const PointCloud &pc,
if (kd_tree_possible && att->data_type() != DT_FLOAT32 &&
att->data_type() != DT_UINT32 && att->data_type() != DT_UINT16 &&
att->data_type() != DT_UINT8 && att->data_type() != DT_INT32 &&
- att->data_type() != DT_INT16 && att->data_type() != DT_INT8)
+ att->data_type() != DT_INT16 && att->data_type() != DT_INT8) {
kd_tree_possible = false;
+ }
if (kd_tree_possible && att->data_type() == DT_FLOAT32 &&
- options().GetAttributeInt(0, "quantization_bits", -1) <= 0)
+ options().GetAttributeInt(0, "quantization_bits", -1) <= 0) {
kd_tree_possible = false; // Quantization not enabled.
- if (!kd_tree_possible)
+ }
+ if (!kd_tree_possible) {
break;
+ }
}
if (kd_tree_possible) {
@@ -167,8 +171,9 @@ Status ExpertEncoder::SetAttributePredictionScheme(
auto att_type = att->attribute_type();
const Status status =
CheckPredictionScheme(att_type, prediction_scheme_method);
- if (!status.ok())
+ if (!status.ok()) {
return status;
+ }
options().SetAttributeInt(attribute_id, "prediction_scheme",
prediction_scheme_method);
return status;
diff --git a/extern/draco/dracoenc/src/draco/compression/expert_encode.h b/extern/draco/draco/src/draco/compression/expert_encode.h
index a1aa7b8b3a8..a1aa7b8b3a8 100644
--- a/extern/draco/dracoenc/src/draco/compression/expert_encode.h
+++ b/extern/draco/draco/src/draco/compression/expert_encode.h
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_decoder.cc b/extern/draco/draco/src/draco/compression/mesh/mesh_decoder.cc
index 01913dcd047..6e48e56fb98 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_decoder.cc
@@ -25,10 +25,12 @@ Status MeshDecoder::Decode(const DecoderOptions &options,
}
bool MeshDecoder::DecodeGeometryData() {
- if (mesh_ == nullptr)
+ if (mesh_ == nullptr) {
return false;
- if (!DecodeConnectivity())
+ }
+ if (!DecodeConnectivity()) {
return false;
+ }
return PointCloudDecoder::DecodeGeometryData();
}
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_decoder.h b/extern/draco/draco/src/draco/compression/mesh/mesh_decoder.h
index 397a679d440..397a679d440 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_decoder.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_decoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_decoder.cc b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder.cc
index e164f82b12b..427dd59f5df 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder.cc
@@ -13,6 +13,7 @@
// limitations under the License.
//
#include "draco/compression/mesh/mesh_edgebreaker_decoder.h"
+
#include "draco/compression/mesh/mesh_edgebreaker_decoder_impl.h"
#include "draco/compression/mesh/mesh_edgebreaker_traversal_predictive_decoder.h"
#include "draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h"
@@ -27,8 +28,9 @@ bool MeshEdgebreakerDecoder::CreateAttributesDecoder(int32_t att_decoder_id) {
bool MeshEdgebreakerDecoder::InitializeDecoder() {
uint8_t traversal_decoder_type;
- if (!buffer()->Decode(&traversal_decoder_type))
+ if (!buffer()->Decode(&traversal_decoder_type)) {
return false;
+ }
impl_ = nullptr;
if (traversal_decoder_type == MESH_EDGEBREAKER_STANDARD_ENCODING) {
#ifdef DRACO_STANDARD_EDGEBREAKER_SUPPORTED
@@ -51,8 +53,9 @@ bool MeshEdgebreakerDecoder::InitializeDecoder() {
if (!impl_) {
return false;
}
- if (!impl_->Init(this))
+ if (!impl_->Init(this)) {
return false;
+ }
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_decoder.h b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder.h
index c3569405220..5c161794298 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_decoder.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder.h
@@ -15,10 +15,9 @@
#ifndef DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_DECODER_H_
#define DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_DECODER_H_
-#include "draco/draco_features.h"
-
#include "draco/compression/mesh/mesh_decoder.h"
#include "draco/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h"
+#include "draco/draco_features.h"
namespace draco {
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc
index 9b91a6f07c4..50d1971c15b 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc
@@ -65,14 +65,16 @@ MeshEdgebreakerDecoderImpl<TraversalDecoder>::GetAttributeCornerTable(
int att_id) const {
for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
const int decoder_id = attribute_data_[i].decoder_id;
- if (decoder_id < 0 || decoder_id >= decoder_->num_attributes_decoders())
+ if (decoder_id < 0 || decoder_id >= decoder_->num_attributes_decoders()) {
continue;
+ }
const AttributesDecoderInterface *const dec =
decoder_->attributes_decoder(decoder_id);
for (int j = 0; j < dec->GetNumAttributes(); ++j) {
if (dec->GetAttributeId(j) == att_id) {
- if (attribute_data_[i].is_connectivity_used)
+ if (attribute_data_[i].is_connectivity_used) {
return &attribute_data_[i].connectivity_data;
+ }
return nullptr;
}
}
@@ -86,13 +88,15 @@ MeshEdgebreakerDecoderImpl<TraversalDecoder>::GetAttributeEncodingData(
int att_id) const {
for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
const int decoder_id = attribute_data_[i].decoder_id;
- if (decoder_id < 0 || decoder_id >= decoder_->num_attributes_decoders())
+ if (decoder_id < 0 || decoder_id >= decoder_->num_attributes_decoders()) {
continue;
+ }
const AttributesDecoderInterface *const dec =
decoder_->attributes_decoder(decoder_id);
for (int j = 0; j < dec->GetNumAttributes(); ++j) {
- if (dec->GetAttributeId(j) == att_id)
+ if (dec->GetAttributeId(j) == att_id) {
return &attribute_data_[i].encoding_data;
+ }
}
}
return &pos_encoding_data_;
@@ -124,11 +128,13 @@ template <class TraversalDecoder>
bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::CreateAttributesDecoder(
int32_t att_decoder_id) {
int8_t att_data_id;
- if (!decoder_->buffer()->Decode(&att_data_id))
+ if (!decoder_->buffer()->Decode(&att_data_id)) {
return false;
+ }
uint8_t decoder_type;
- if (!decoder_->buffer()->Decode(&decoder_type))
+ if (!decoder_->buffer()->Decode(&decoder_type)) {
return false;
+ }
if (att_data_id >= 0) {
if (att_data_id >= attribute_data_.size()) {
@@ -137,22 +143,25 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::CreateAttributesDecoder(
// Ensure that the attribute data is not mapped to a different attributes
// decoder already.
- if (attribute_data_[att_data_id].decoder_id >= 0)
+ if (attribute_data_[att_data_id].decoder_id >= 0) {
return false;
+ }
attribute_data_[att_data_id].decoder_id = att_decoder_id;
} else {
// Assign the attributes decoder to |pos_encoding_data_|.
- if (pos_data_decoder_id_ >= 0)
+ if (pos_data_decoder_id_ >= 0) {
return false; // Some other decoder is already using the data. Error.
+ }
pos_data_decoder_id_ = att_decoder_id;
}
MeshTraversalMethod traversal_method = MESH_TRAVERSAL_DEPTH_FIRST;
if (decoder_->bitstream_version() >= DRACO_BITSTREAM_VERSION(1, 2)) {
uint8_t traversal_method_encoded;
- if (!decoder_->buffer()->Decode(&traversal_method_encoded))
+ if (!decoder_->buffer()->Decode(&traversal_method_encoded)) {
return false;
+ }
traversal_method =
static_cast<MeshTraversalMethod>(traversal_method_encoded);
}
@@ -186,10 +195,12 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::CreateAttributesDecoder(
return false; // Unsupported method
}
} else {
- if (traversal_method != MESH_TRAVERSAL_DEPTH_FIRST)
+ if (traversal_method != MESH_TRAVERSAL_DEPTH_FIRST) {
return false; // Unsupported method.
- if (att_data_id < 0)
+ }
+ if (att_data_id < 0) {
return false; // Attribute data must be specified.
+ }
// Per-corner attribute decoder.
@@ -216,8 +227,9 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::CreateAttributesDecoder(
sequencer = std::move(traversal_sequencer);
}
- if (!sequencer)
+ if (!sequencer) {
return false;
+ }
std::unique_ptr<SequentialAttributeDecodersController> att_controller(
new SequentialAttributeDecodersController(std::move(sequencer)));
@@ -234,11 +246,13 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity() {
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
uint32_t num_new_verts;
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
- if (!decoder_->buffer()->Decode(&num_new_verts))
+ if (!decoder_->buffer()->Decode(&num_new_verts)) {
return false;
+ }
} else {
- if (!DecodeVarint(&num_new_verts, decoder_->buffer()))
+ if (!DecodeVarint(&num_new_verts, decoder_->buffer())) {
return false;
+ }
}
num_new_vertices_ = num_new_verts;
}
@@ -247,50 +261,58 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity() {
uint32_t num_encoded_vertices;
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
- if (!decoder_->buffer()->Decode(&num_encoded_vertices))
+ if (!decoder_->buffer()->Decode(&num_encoded_vertices)) {
return false;
+ }
} else
#endif
{
- if (!DecodeVarint(&num_encoded_vertices, decoder_->buffer()))
+ if (!DecodeVarint(&num_encoded_vertices, decoder_->buffer())) {
return false;
+ }
}
num_encoded_vertices_ = num_encoded_vertices;
uint32_t num_faces;
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
- if (!decoder_->buffer()->Decode(&num_faces))
+ if (!decoder_->buffer()->Decode(&num_faces)) {
return false;
+ }
} else
#endif
{
- if (!DecodeVarint(&num_faces, decoder_->buffer()))
+ if (!DecodeVarint(&num_faces, decoder_->buffer())) {
return false;
+ }
}
- if (num_faces > std::numeric_limits<CornerIndex::ValueType>::max() / 3)
+ if (num_faces > std::numeric_limits<CornerIndex::ValueType>::max() / 3) {
return false; // Draco cannot handle this many faces.
+ }
if (static_cast<uint32_t>(num_encoded_vertices_) > num_faces * 3) {
return false; // There cannot be more vertices than 3 * num_faces.
}
uint8_t num_attribute_data;
- if (!decoder_->buffer()->Decode(&num_attribute_data))
+ if (!decoder_->buffer()->Decode(&num_attribute_data)) {
return false;
+ }
uint32_t num_encoded_symbols;
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
- if (!decoder_->buffer()->Decode(&num_encoded_symbols))
+ if (!decoder_->buffer()->Decode(&num_encoded_symbols)) {
return false;
+ }
} else
#endif
{
- if (!DecodeVarint(&num_encoded_symbols, decoder_->buffer()))
+ if (!DecodeVarint(&num_encoded_symbols, decoder_->buffer())) {
return false;
+ }
}
if (num_faces < num_encoded_symbols) {
@@ -311,14 +333,16 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity() {
uint32_t num_encoded_split_symbols;
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
- if (!decoder_->buffer()->Decode(&num_encoded_split_symbols))
+ if (!decoder_->buffer()->Decode(&num_encoded_split_symbols)) {
return false;
+ }
} else
#endif
{
- if (!DecodeVarint(&num_encoded_split_symbols, decoder_->buffer()))
+ if (!DecodeVarint(&num_encoded_split_symbols, decoder_->buffer())) {
return false;
+ }
}
if (num_encoded_split_symbols > num_encoded_symbols) {
@@ -328,8 +352,9 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity() {
// Decode topology (connectivity).
vertex_traversal_length_.clear();
corner_table_ = std::unique_ptr<CornerTable>(new CornerTable());
- if (corner_table_ == nullptr)
+ if (corner_table_ == nullptr) {
return false;
+ }
processed_corner_ids_.clear();
processed_corner_ids_.reserve(num_faces);
processed_connectivity_corners_.clear();
@@ -347,9 +372,10 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity() {
// Add one attribute data for each attribute decoder.
attribute_data_.resize(num_attribute_data);
- if (!corner_table_->Reset(num_faces,
- num_encoded_vertices_ + num_encoded_split_symbols))
+ if (!corner_table_->Reset(
+ num_faces, num_encoded_vertices_ + num_encoded_split_symbols)) {
return false;
+ }
// Start with all vertices marked as holes (boundaries).
// Only vertices decoded with TOPOLOGY_C symbol (and the initial face) will
@@ -363,15 +389,18 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity() {
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
uint32_t encoded_connectivity_size;
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
- if (!decoder_->buffer()->Decode(&encoded_connectivity_size))
+ if (!decoder_->buffer()->Decode(&encoded_connectivity_size)) {
return false;
+ }
} else {
- if (!DecodeVarint(&encoded_connectivity_size, decoder_->buffer()))
+ if (!DecodeVarint(&encoded_connectivity_size, decoder_->buffer())) {
return false;
+ }
}
if (encoded_connectivity_size == 0 ||
- encoded_connectivity_size > decoder_->buffer()->remaining_size())
+ encoded_connectivity_size > decoder_->buffer()->remaining_size()) {
return false;
+ }
DecoderBuffer event_buffer;
event_buffer.Init(
decoder_->buffer()->data_head() + encoded_connectivity_size,
@@ -380,14 +409,16 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity() {
// Decode hole and topology split events.
topology_split_decoded_bytes =
DecodeHoleAndTopologySplitEvents(&event_buffer);
- if (topology_split_decoded_bytes == -1)
+ if (topology_split_decoded_bytes == -1) {
return false;
+ }
} else
#endif
{
- if (DecodeHoleAndTopologySplitEvents(decoder_->buffer()) == -1)
+ if (DecodeHoleAndTopologySplitEvents(decoder_->buffer()) == -1) {
return false;
+ }
}
traversal_decoder_.Init(this);
@@ -397,12 +428,14 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity() {
traversal_decoder_.SetNumAttributeData(num_attribute_data);
DecoderBuffer traversal_end_buffer;
- if (!traversal_decoder_.Start(&traversal_end_buffer))
+ if (!traversal_decoder_.Start(&traversal_end_buffer)) {
return false;
+ }
const int num_connectivity_verts = DecodeConnectivity(num_encoded_symbols);
- if (num_connectivity_verts == -1)
+ if (num_connectivity_verts == -1) {
return false;
+ }
// Set the main buffer to the end of the traversal.
decoder_->buffer()->Init(traversal_end_buffer.data_head(),
@@ -421,16 +454,18 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity() {
#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) {
- if (!DecodeAttributeConnectivitiesOnFaceLegacy(ci))
+ if (!DecodeAttributeConnectivitiesOnFaceLegacy(ci)) {
return false;
+ }
}
} else
#endif
{
for (CornerIndex ci(0); ci < corner_table_->num_corners(); ci += 3) {
- if (!DecodeAttributeConnectivitiesOnFace(ci))
+ if (!DecodeAttributeConnectivitiesOnFace(ci)) {
return false;
+ }
}
}
}
@@ -456,12 +491,14 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity() {
// it).
int32_t att_connectivity_verts =
attribute_data_[i].connectivity_data.num_vertices();
- if (att_connectivity_verts < corner_table_->num_vertices())
+ if (att_connectivity_verts < corner_table_->num_vertices()) {
att_connectivity_verts = corner_table_->num_vertices();
+ }
attribute_data_[i].encoding_data.Init(att_connectivity_verts);
}
- if (!AssignPointsToCorners(num_connectivity_verts))
+ if (!AssignPointsToCorners(num_connectivity_verts)) {
return false;
+ }
return true;
}
@@ -523,8 +560,9 @@ int MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity(
// Find the corner "b" from the corner "a" which is the corner on the
// top of the active stack.
- if (active_corner_stack.empty())
+ if (active_corner_stack.empty()) {
return -1;
+ }
const CornerIndex corner_a = active_corner_stack.back();
const VertexIndex vertex_x =
@@ -565,8 +603,9 @@ int MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity(
// . .
// . .
// *
- if (active_corner_stack.empty())
+ if (active_corner_stack.empty()) {
return -1;
+ }
const CornerIndex corner_a = active_corner_stack.back();
// First corner on the new face is either corner "l" or "r".
@@ -587,8 +626,9 @@ int MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity(
// Update vertex mapping.
const VertexIndex new_vert_index = corner_table_->AddNewVertex();
- if (corner_table_->num_vertices() > max_num_vertices)
+ if (corner_table_->num_vertices() > max_num_vertices) {
return -1; // Unexpected number of decoded vertices.
+ }
corner_table_->MapCornerToVertex(opp_corner, new_vert_index);
corner_table_->SetLeftMostCorner(new_vert_index, opp_corner);
@@ -614,8 +654,9 @@ int MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity(
// \ / S \ /
// *.......*
//
- if (active_corner_stack.empty())
+ if (active_corner_stack.empty()) {
return -1;
+ }
const CornerIndex corner_b = active_corner_stack.back();
active_corner_stack.pop_back();
@@ -626,8 +667,9 @@ int MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity(
// Topology split event. Move the retrieved edge to the stack.
active_corner_stack.push_back(it->second);
}
- if (active_corner_stack.empty())
+ if (active_corner_stack.empty()) {
return -1;
+ }
const CornerIndex corner_a = active_corner_stack.back();
if (corner_table_->Opposite(corner_a) != kInvalidCornerIndex ||
@@ -669,8 +711,9 @@ int MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity(
// Make sure the old vertex n is now mapped to an invalid corner (make it
// isolated).
corner_table_->MakeVertexIsolated(vertex_n);
- if (remove_invalid_vertices)
+ if (remove_invalid_vertices) {
invalid_vertices.push_back(vertex_n);
+ }
active_corner_stack.back() = corner;
} else if (symbol == TOPOLOGY_E) {
const CornerIndex corner(3 * face.value());
@@ -682,8 +725,9 @@ int MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity(
corner_table_->MapCornerToVertex(corner + 2,
corner_table_->AddNewVertex());
- if (corner_table_->num_vertices() > max_num_vertices)
+ if (corner_table_->num_vertices() > max_num_vertices) {
return -1; // Unexpected number of decoded vertices.
+ }
corner_table_->SetLeftMostCorner(first_vert_index, corner);
corner_table_->SetLeftMostCorner(first_vert_index + 1, corner + 1);
@@ -713,8 +757,9 @@ int MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity(
int encoder_split_symbol_id;
while (IsTopologySplit(encoder_symbol_id, &split_edge,
&encoder_split_symbol_id)) {
- if (encoder_split_symbol_id < 0)
+ if (encoder_split_symbol_id < 0) {
return -1; // Wrong split symbol id.
+ }
// Symbol was part of a topology split. Now we need to determine which
// edge should be added to the active edges stack.
const CornerIndex act_top_corner = active_corner_stack.back();
@@ -742,8 +787,9 @@ int MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity(
}
}
}
- if (corner_table_->num_vertices() > max_num_vertices)
+ if (corner_table_->num_vertices() > max_num_vertices) {
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) {
const CornerIndex corner = active_corner_stack.back();
@@ -817,21 +863,23 @@ int MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity(
init_corners_.push_back(corner);
}
}
- if (num_faces != corner_table_->num_faces())
+ if (num_faces != corner_table_->num_faces()) {
return -1; // Unexpected number of decoded faces.
+ }
int num_vertices = corner_table_->num_vertices();
// If any vertex was marked as isolated, we want to remove it from the corner
// table to ensure that all vertices in range <0, num_vertices> are valid.
- for (const VertexIndex invalid_vert : invalid_vertices) {
+ for (const VertexIndex& invalid_vert : invalid_vertices) {
// Find the last valid vertex and swap it with the isolated vertex.
VertexIndex src_vert(num_vertices - 1);
while (corner_table_->LeftMostCorner(src_vert) == kInvalidCornerIndex) {
// The last vertex is invalid, proceed to the previous one.
src_vert = VertexIndex(--num_vertices - 1);
}
- if (src_vert < invalid_vert)
+ if (src_vert < invalid_vert) {
continue; // No need to swap anything.
+ }
// Remap all corners mapped to |src_vert| to |invalid_vert|.
VertexCornersIterator<CornerTable> vcit(corner_table_.get(), src_vert);
@@ -861,29 +909,36 @@ MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeHoleAndTopologySplitEvents(
uint32_t num_topology_splits;
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
- if (!decoder_buffer->Decode(&num_topology_splits))
+ if (!decoder_buffer->Decode(&num_topology_splits)) {
return -1;
+ }
} else
#endif
{
- if (!DecodeVarint(&num_topology_splits, decoder_buffer))
+ if (!DecodeVarint(&num_topology_splits, decoder_buffer)) {
return -1;
+ }
}
if (num_topology_splits > 0) {
- if (num_topology_splits > static_cast<uint32_t>(corner_table_->num_faces()))
+ if (num_topology_splits >
+ static_cast<uint32_t>(corner_table_->num_faces())) {
return -1;
+ }
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(1, 2)) {
for (uint32_t i = 0; i < num_topology_splits; ++i) {
TopologySplitEventData event_data;
- if (!decoder_buffer->Decode(&event_data.split_symbol_id))
+ if (!decoder_buffer->Decode(&event_data.split_symbol_id)) {
return -1;
- if (!decoder_buffer->Decode(&event_data.source_symbol_id))
+ }
+ if (!decoder_buffer->Decode(&event_data.source_symbol_id)) {
return -1;
+ }
uint8_t edge_data;
- if (!decoder_buffer->Decode(&edge_data))
+ if (!decoder_buffer->Decode(&edge_data)) {
return -1;
+ }
event_data.source_edge = edge_data & 1;
topology_split_data_.push_back(event_data);
}
@@ -900,8 +955,9 @@ MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeHoleAndTopologySplitEvents(
DecodeVarint<uint32_t>(&delta, decoder_buffer);
event_data.source_symbol_id = delta + last_source_symbol_id;
DecodeVarint<uint32_t>(&delta, decoder_buffer);
- if (delta > event_data.source_symbol_id)
+ if (delta > event_data.source_symbol_id) {
return -1;
+ }
event_data.split_symbol_id =
event_data.source_symbol_id - static_cast<int32_t>(delta);
last_source_symbol_id = event_data.source_symbol_id;
@@ -925,11 +981,13 @@ MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeHoleAndTopologySplitEvents(
uint32_t num_hole_events = 0;
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
- if (!decoder_buffer->Decode(&num_hole_events))
+ if (!decoder_buffer->Decode(&num_hole_events)) {
return -1;
+ }
} else if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 1)) {
- if (!DecodeVarint(&num_hole_events, decoder_buffer))
+ if (!DecodeVarint(&num_hole_events, decoder_buffer)) {
return -1;
+ }
}
#endif
if (num_hole_events > 0) {
@@ -937,8 +995,9 @@ MeshEdgebreakerDecoderImpl<TraversalDecoder>::DecodeHoleAndTopologySplitEvents(
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(1, 2)) {
for (uint32_t i = 0; i < num_hole_events; ++i) {
HoleEventData event_data;
- if (!decoder_buffer->Decode(&event_data))
+ if (!decoder_buffer->Decode(&event_data)) {
return -1;
+ }
hole_event_data_.push_back(event_data);
}
@@ -981,8 +1040,9 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::
for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
const bool is_seam = traversal_decoder_.DecodeAttributeSeam(i);
- if (is_seam)
+ if (is_seam) {
attribute_data_[i].attribute_seam_corners.push_back(corners[c].value());
+ }
}
}
return true;
@@ -1009,13 +1069,15 @@ bool MeshEdgebreakerDecoderImpl<
}
const FaceIndex opp_face_id = corner_table_->Face(opp_corner);
// Don't decode edges when the opposite face has been already processed.
- if (opp_face_id < src_face_id)
+ if (opp_face_id < src_face_id) {
continue;
+ }
for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
const bool is_seam = traversal_decoder_.DecodeAttributeSeam(i);
- if (is_seam)
+ if (is_seam) {
attribute_data_[i].attribute_seam_corners.push_back(corners[c].value());
+ }
}
}
return true;
@@ -1055,8 +1117,9 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::AssignPointsToCorners(
std::vector<int32_t> corner_to_point_map(corner_table_->num_corners());
for (int v = 0; v < corner_table_->num_vertices(); ++v) {
CornerIndex c = corner_table_->LeftMostCorner(VertexIndex(v));
- if (c == kInvalidCornerIndex)
+ if (c == kInvalidCornerIndex) {
continue; // Isolated vertex.
+ }
CornerIndex deduplication_first_corner = c;
if (is_vert_hole_[v]) {
// If the vertex is on a boundary, start deduplication from the left most
@@ -1066,8 +1129,9 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::AssignPointsToCorners(
// If we are not on the boundary we need to find the first seam (of any
// attribute).
for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
- if (!attribute_data_[i].connectivity_data.IsCornerOnSeam(c))
+ if (!attribute_data_[i].connectivity_data.IsCornerOnSeam(c)) {
continue; // No seam for this attribute, ignore it.
+ }
// Else there needs to be at least one seam edge.
// At this point, we use identity mapping between corners and point ids.
@@ -1076,8 +1140,9 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::AssignPointsToCorners(
CornerIndex act_c = corner_table_->SwingRight(c);
bool seam_found = false;
while (act_c != c) {
- if (act_c == kInvalidCornerIndex)
+ if (act_c == kInvalidCornerIndex) {
return false;
+ }
if (attribute_data_[i].connectivity_data.Vertex(act_c) != vert_id) {
// Attribute seam found. Stop.
deduplication_first_corner = act_c;
@@ -1086,8 +1151,9 @@ bool MeshEdgebreakerDecoderImpl<TraversalDecoder>::AssignPointsToCorners(
}
act_c = corner_table_->SwingRight(act_c);
}
- if (seam_found)
+ if (seam_found) {
break; // No reason to process other attributes if we found a seam.
+ }
}
}
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h
index 5299a189d48..78053f91dbe 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h
@@ -17,14 +17,13 @@
#include <unordered_map>
#include <unordered_set>
-#include "draco/compression/mesh/traverser/mesh_traversal_sequencer.h"
-
-#include "draco/draco_features.h"
#include "draco/compression/attributes/mesh_attribute_indices_encoding_data.h"
#include "draco/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h"
#include "draco/compression/mesh/mesh_edgebreaker_shared.h"
+#include "draco/compression/mesh/traverser/mesh_traversal_sequencer.h"
#include "draco/core/decoder_buffer.h"
+#include "draco/draco_features.h"
#include "draco/mesh/corner_table.h"
#include "draco/mesh/mesh_attribute_corner_table.h"
@@ -85,8 +84,9 @@ class MeshEdgebreakerDecoderImpl : public MeshEdgebreakerDecoderImplInterface {
// symbol.
bool IsTopologySplit(int encoder_symbol_id, EdgeFaceName *out_face_edge,
int *out_encoder_split_symbol_id) {
- if (topology_split_data_.size() == 0)
+ if (topology_split_data_.size() == 0) {
return false;
+ }
if (topology_split_data_.back().source_symbol_id >
static_cast<uint32_t>(encoder_symbol_id)) {
// Something is wrong; if the desired source symbol is greater than the
@@ -97,8 +97,9 @@ class MeshEdgebreakerDecoderImpl : public MeshEdgebreakerDecoderImplInterface {
*out_encoder_split_symbol_id = -1;
return true;
}
- if (topology_split_data_.back().source_symbol_id != encoder_symbol_id)
+ if (topology_split_data_.back().source_symbol_id != encoder_symbol_id) {
return false;
+ }
*out_face_edge =
static_cast<EdgeFaceName>(topology_split_data_.back().source_edge);
*out_encoder_split_symbol_id = topology_split_data_.back().split_symbol_id;
@@ -123,8 +124,9 @@ class MeshEdgebreakerDecoderImpl : public MeshEdgebreakerDecoderImplInterface {
bool AssignPointsToCorners(int num_connectivity_verts);
bool IsFaceVisited(CornerIndex corner_id) const {
- if (corner_id < 0)
+ if (corner_id < 0) {
return true; // Invalid corner signalizes that the face does not exist.
+ }
return visited_faces_[corner_table_->Face(corner_id).value()];
}
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h
index 31fabf252d8..31fabf252d8 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoder.cc b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder.cc
index 54fd55a483c..5aff5d8cc10 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder.cc
@@ -59,23 +59,27 @@ bool MeshEdgebreakerEncoder::InitializeEncoder() {
new MeshEdgebreakerEncoderImpl<
MeshEdgebreakerTraversalValenceEncoder>());
}
- if (!impl_)
+ if (!impl_) {
return false;
- if (!impl_->Init(this))
+ }
+ if (!impl_->Init(this)) {
return false;
+ }
return true;
}
bool MeshEdgebreakerEncoder::GenerateAttributesEncoder(int32_t att_id) {
- if (!impl_->GenerateAttributesEncoder(att_id))
+ if (!impl_->GenerateAttributesEncoder(att_id)) {
return false;
+ }
return true;
}
bool MeshEdgebreakerEncoder::EncodeAttributesEncoderIdentifier(
int32_t att_encoder_id) {
- if (!impl_->EncodeAttributesEncoderIdentifier(att_encoder_id))
+ if (!impl_->EncodeAttributesEncoderIdentifier(att_encoder_id)) {
return false;
+ }
return true;
}
@@ -84,11 +88,13 @@ Status MeshEdgebreakerEncoder::EncodeConnectivity() {
}
void MeshEdgebreakerEncoder::ComputeNumberOfEncodedPoints() {
- if (!impl_)
+ if (!impl_) {
return;
+ }
const CornerTable *const corner_table = impl_->GetCornerTable();
- if (!corner_table)
+ if (!corner_table) {
return;
+ }
size_t num_points =
corner_table->num_vertices() - corner_table->NumIsolatedVertices();
@@ -96,22 +102,26 @@ void MeshEdgebreakerEncoder::ComputeNumberOfEncodedPoints() {
// Gather all corner tables for all non-position attributes.
std::vector<const MeshAttributeCornerTable *> attribute_corner_tables;
for (int i = 0; i < mesh()->num_attributes(); ++i) {
- if (mesh()->attribute(i)->attribute_type() == GeometryAttribute::POSITION)
+ if (mesh()->attribute(i)->attribute_type() ==
+ GeometryAttribute::POSITION) {
continue;
+ }
const MeshAttributeCornerTable *const att_corner_table =
GetAttributeCornerTable(i);
// Attribute corner table may not be used in some configurations. For
// these cases we can assume the attribute connectivity to be the same as
// the connectivity of the position data.
- if (att_corner_table)
+ if (att_corner_table) {
attribute_corner_tables.push_back(att_corner_table);
+ }
}
// Add a new point based on the configuration of interior attribute seams
// (replicating what the decoder would do).
for (VertexIndex vi(0); vi < corner_table->num_vertices(); ++vi) {
- if (corner_table->IsVertexIsolated(vi))
+ if (corner_table->IsVertexIsolated(vi)) {
continue;
+ }
// Go around all corners of the vertex and keep track of the observed
// attribute seams.
const CornerIndex first_corner_index = corner_table->LeftMostCorner(vi);
@@ -144,8 +154,9 @@ void MeshEdgebreakerEncoder::ComputeNumberOfEncodedPoints() {
++num_attribute_seams;
}
- if (corner_index == first_corner_index)
+ if (corner_index == first_corner_index) {
break;
+ }
// Proceed to the next corner
last_corner_index = corner_index;
@@ -170,11 +181,13 @@ void MeshEdgebreakerEncoder::ComputeNumberOfEncodedPoints() {
}
void MeshEdgebreakerEncoder::ComputeNumberOfEncodedFaces() {
- if (!impl_)
+ if (!impl_) {
return;
+ }
const CornerTable *const corner_table = impl_->GetCornerTable();
- if (!corner_table)
+ if (!corner_table) {
return;
+ }
set_num_encoded_faces(corner_table->num_faces() -
corner_table->NumDegeneratedFaces());
}
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoder.h b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder.h
index 70d4d5061a7..70d4d5061a7 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoder.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.cc b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.cc
index f69ec993f9e..0791dc6705a 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.cc
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.cc
@@ -67,8 +67,9 @@ MeshEdgebreakerEncoderImpl<TraversalEncoder>::GetAttributeCornerTable(
int att_id) const {
for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
if (attribute_data_[i].attribute_index == att_id) {
- if (attribute_data_[i].is_connectivity_used)
+ if (attribute_data_[i].is_connectivity_used) {
return &attribute_data_[i].connectivity_data;
+ }
return nullptr;
}
}
@@ -80,8 +81,9 @@ const MeshAttributeIndicesEncodingData *
MeshEdgebreakerEncoderImpl<TraversalEncoder>::GetAttributeEncodingData(
int att_id) const {
for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
- if (attribute_data_[i].attribute_index == att_id)
+ if (attribute_data_[i].attribute_index == att_id) {
return &attribute_data_[i].encoding_data;
+ }
}
return &pos_encoding_data_;
}
@@ -212,8 +214,9 @@ bool MeshEdgebreakerEncoderImpl<TraversalEncoder>::GenerateAttributesEncoder(
sequencer = std::move(traversal_sequencer);
}
- if (!sequencer)
+ if (!sequencer) {
return false;
+ }
if (att_data_id == -1) {
pos_traversal_method_ = traversal_method;
@@ -316,11 +319,13 @@ Status MeshEdgebreakerEncoderImpl<TraversalEncoder>::EncodeConnectivity() {
processed_connectivity_corners_.reserve(corner_table_->num_faces());
pos_encoding_data_.num_values = 0;
- if (!FindHoles())
+ if (!FindHoles()) {
return Status(Status::DRACO_ERROR, "Failed to process mesh holes.");
+ }
- if (!InitAttributeData())
+ if (!InitAttributeData()) {
return Status(Status::DRACO_ERROR, "Failed to initialize attribute data.");
+ }
const uint8_t num_attribute_data =
static_cast<uint8_t>(attribute_data_.size());
@@ -336,10 +341,12 @@ Status MeshEdgebreakerEncoderImpl<TraversalEncoder>::EncodeConnectivity() {
for (int c_id = 0; c_id < num_corners; ++c_id) {
CornerIndex corner_index(c_id);
const FaceIndex face_id = corner_table_->Face(corner_index);
- if (visited_faces_[face_id.value()])
+ if (visited_faces_[face_id.value()]) {
continue; // Face has been already processed.
- if (corner_table_->IsDegenerated(face_id))
+ }
+ if (corner_table_->IsDegenerated(face_id)) {
continue; // Ignore degenerated faces.
+ }
CornerIndex start_corner;
const bool interior_config =
@@ -375,8 +382,10 @@ Status MeshEdgebreakerEncoderImpl<TraversalEncoder>::EncodeConnectivity() {
const FaceIndex opp_face_id = corner_table_->Face(opp_id);
if (opp_face_id != kInvalidFaceIndex &&
!visited_faces_[opp_face_id.value()]) {
- if (!EncodeConnectivityFromCorner(opp_id))
- return Status(Status::DRACO_ERROR, "Failed to encode mesh component.");
+ if (!EncodeConnectivityFromCorner(opp_id)) {
+ return Status(Status::DRACO_ERROR,
+ "Failed to encode mesh component.");
+ }
}
} else {
// Boundary configuration. We start on a boundary rather than on a face.
@@ -384,8 +393,9 @@ Status MeshEdgebreakerEncoderImpl<TraversalEncoder>::EncodeConnectivity() {
EncodeHole(corner_table_->Next(start_corner), true);
// Start processing the face opposite to the boundary edge (the face
// containing the start_corner).
- if (!EncodeConnectivityFromCorner(start_corner))
+ if (!EncodeConnectivityFromCorner(start_corner)) {
return Status(Status::DRACO_ERROR, "Failed to encode mesh component.");
+ }
}
}
// Reverse the order of connectivity corners to match the order in which
@@ -416,8 +426,9 @@ Status MeshEdgebreakerEncoderImpl<TraversalEncoder>::EncodeConnectivity() {
EncodeVarint(num_split_symbols_, encoder_->buffer());
// Append the traversal buffer.
- if (!EncodeSplitData())
+ if (!EncodeSplitData()) {
return Status(Status::DRACO_ERROR, "Failed to encode split data.");
+ }
encoder_->buffer()->Encode(traversal_encoder_.buffer().data(),
traversal_encoder_.buffer().size());
@@ -542,17 +553,19 @@ bool MeshEdgebreakerEncoderImpl<TraversalEncoder>::EncodeConnectivityFromCorner(
if (IsRightFaceVisited(corner_id)) {
// Right face has been already visited.
// Check whether there is a topology split event.
- if (right_face_id != kInvalidFaceIndex)
+ if (right_face_id != kInvalidFaceIndex) {
CheckAndStoreTopologySplitEvent(last_encoded_symbol_id_,
face_id.value(), RIGHT_FACE_EDGE,
right_face_id.value());
+ }
if (IsLeftFaceVisited(corner_id)) {
// Both neighboring faces are visited. End reached.
// Check whether there is a topology split event on the left face.
- if (left_face_id != kInvalidFaceIndex)
+ if (left_face_id != kInvalidFaceIndex) {
CheckAndStoreTopologySplitEvent(last_encoded_symbol_id_,
face_id.value(), LEFT_FACE_EDGE,
left_face_id.value());
+ }
traversal_encoder_.EncodeSymbol(TOPOLOGY_E);
corner_traversal_stack_.pop_back();
break; // Break from the while (num_visited_faces < num_faces) loop.
@@ -565,10 +578,11 @@ bool MeshEdgebreakerEncoderImpl<TraversalEncoder>::EncodeConnectivityFromCorner(
// Right face was not visited.
if (IsLeftFaceVisited(corner_id)) {
// Check whether there is a topology split event on the left face.
- if (left_face_id != kInvalidFaceIndex)
+ if (left_face_id != kInvalidFaceIndex) {
CheckAndStoreTopologySplitEvent(last_encoded_symbol_id_,
face_id.value(), LEFT_FACE_EDGE,
left_face_id.value());
+ }
traversal_encoder_.EncodeSymbol(TOPOLOGY_L);
// Left face visited, go to the right one.
corner_id = right_corner_id;
@@ -669,8 +683,9 @@ bool MeshEdgebreakerEncoderImpl<TraversalEncoder>::IsRightFaceVisited(
CornerIndex corner_id) const {
const CornerIndex next_corner_id = corner_table_->Next(corner_id);
const CornerIndex opp_corner_id = corner_table_->Opposite(next_corner_id);
- if (opp_corner_id != kInvalidCornerIndex)
+ if (opp_corner_id != kInvalidCornerIndex) {
return visited_faces_[corner_table_->Face(opp_corner_id).value()];
+ }
// Else we are on a boundary.
return true;
}
@@ -680,8 +695,9 @@ bool MeshEdgebreakerEncoderImpl<TraversalEncoder>::IsLeftFaceVisited(
CornerIndex corner_id) const {
const CornerIndex prev_corner_id = corner_table_->Previous(corner_id);
const CornerIndex opp_corner_id = corner_table_->Opposite(prev_corner_id);
- if (opp_corner_id != kInvalidCornerIndex)
+ if (opp_corner_id != kInvalidCornerIndex) {
return visited_faces_[corner_table_->Face(opp_corner_id).value()];
+ }
// Else we are on a boundary.
return true;
}
@@ -692,8 +708,9 @@ bool MeshEdgebreakerEncoderImpl<TraversalEncoder>::FindHoles() {
const int num_corners = corner_table_->num_corners();
// Go over all corners and detect non-visited open boundaries
for (CornerIndex i(0); i < num_corners; ++i) {
- if (corner_table_->IsDegenerated(corner_table_->Face(i)))
+ if (corner_table_->IsDegenerated(corner_table_->Face(i))) {
continue; // Don't process corners assigned to degenerated faces.
+ }
if (corner_table_->Opposite(i) == kInvalidCornerIndex) {
// No opposite corner means no opposite face, so the opposite edge
// of the corner is an open boundary.
@@ -733,8 +750,9 @@ template <class TraversalEncoder>
int MeshEdgebreakerEncoderImpl<TraversalEncoder>::GetSplitSymbolIdOnFace(
int face_id) const {
auto it = face_to_split_symbol_map_.find(face_id);
- if (it == face_to_split_symbol_map_.end())
+ if (it == face_to_split_symbol_map_.end()) {
return -1;
+ }
return it->second;
}
@@ -745,8 +763,9 @@ void MeshEdgebreakerEncoderImpl<
EdgeFaceName src_edge,
int neighbor_face_id) {
const int symbol_id = GetSplitSymbolIdOnFace(neighbor_face_id);
- if (symbol_id == -1)
+ if (symbol_id == -1) {
return; // Not a split symbol, no topology split event could happen.
+ }
TopologySplitEventData event_data;
event_data.split_symbol_id = symbol_id;
@@ -757,20 +776,23 @@ void MeshEdgebreakerEncoderImpl<
template <class TraversalEncoder>
bool MeshEdgebreakerEncoderImpl<TraversalEncoder>::InitAttributeData() {
- if (use_single_connectivity_)
+ if (use_single_connectivity_) {
return true; // All attributes use the same connectivity.
+ }
const int num_attributes = mesh_->num_attributes();
// Ignore the position attribute. It's decoded separately.
attribute_data_.resize(num_attributes - 1);
- if (num_attributes == 1)
+ if (num_attributes == 1) {
return true;
+ }
int data_index = 0;
for (int i = 0; i < num_attributes; ++i) {
const int32_t att_index = i;
if (mesh_->attribute(att_index)->attribute_type() ==
- GeometryAttribute::POSITION)
+ GeometryAttribute::POSITION) {
continue;
+ }
const PointAttribute *const att = mesh_->attribute(att_index);
attribute_data_[data_index].attribute_index = att_index;
attribute_data_[data_index]
@@ -802,12 +824,14 @@ bool MeshEdgebreakerEncoderImpl<
visited_faces_[src_face_id.value()] = true;
for (int c = 0; c < 3; ++c) {
const CornerIndex opp_corner = corner_table_->Opposite(corners[c]);
- if (opp_corner == kInvalidCornerIndex)
+ if (opp_corner == kInvalidCornerIndex) {
continue; // Don't encode attribute seams on boundary edges.
+ }
const FaceIndex opp_face_id = corner_table_->Face(opp_corner);
// Don't encode edges when the opposite face has been already processed.
- if (visited_faces_[opp_face_id.value()])
+ if (visited_faces_[opp_face_id.value()]) {
continue;
+ }
for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
if (attribute_data_[i].connectivity_data.IsCornerOppositeToSeamEdge(
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h
index fb33771637e..fb33771637e 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl_interface.h b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl_interface.h
index 627d5126296..627d5126296 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl_interface.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_encoder_impl_interface.h
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_shared.h b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_shared.h
index cb3c29dd669..cb3c29dd669 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_shared.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_shared.h
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_decoder.h b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_decoder.h
index 128d7f5d988..ce91adc8747 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_decoder.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_decoder.h
@@ -15,12 +15,11 @@
#ifndef DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_TRAVERSAL_DECODER_H_
#define DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_TRAVERSAL_DECODER_H_
-#include "draco/draco_features.h"
-
#include "draco/compression/bit_coders/rans_bit_decoder.h"
#include "draco/compression/mesh/mesh_edgebreaker_decoder.h"
#include "draco/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h"
#include "draco/compression/mesh/mesh_edgebreaker_shared.h"
+#include "draco/draco_features.h"
namespace draco {
@@ -60,14 +59,17 @@ class MeshEdgebreakerTraversalDecoder {
bool Start(DecoderBuffer *out_buffer) {
// Decode symbols from the main buffer decoder and face configurations from
// the start_face_buffer decoder.
- if (!DecodeTraversalSymbols())
+ if (!DecodeTraversalSymbols()) {
return false;
+ }
- if (!DecodeStartFaces())
+ if (!DecodeStartFaces()) {
return false;
+ }
- if (!DecodeAttributeSeams())
+ if (!DecodeAttributeSeams()) {
return false;
+ }
*out_buffer = buffer_;
return true;
}
@@ -118,8 +120,9 @@ class MeshEdgebreakerTraversalDecoder {
// Called when the traversal is finished.
void Done() {
- if (symbol_buffer_.bit_decoder_active())
+ if (symbol_buffer_.bit_decoder_active()) {
symbol_buffer_.EndBitDecoding();
+ }
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (buffer_.bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
start_face_buffer_.EndBitDecoding();
@@ -137,11 +140,13 @@ class MeshEdgebreakerTraversalDecoder {
bool DecodeTraversalSymbols() {
uint64_t traversal_size;
symbol_buffer_ = buffer_;
- if (!symbol_buffer_.StartBitDecoding(true, &traversal_size))
+ if (!symbol_buffer_.StartBitDecoding(true, &traversal_size)) {
return false;
+ }
buffer_ = symbol_buffer_;
- if (traversal_size > static_cast<uint64_t>(buffer_.remaining_size()))
+ if (traversal_size > static_cast<uint64_t>(buffer_.remaining_size())) {
return false;
+ }
buffer_.Advance(traversal_size);
return true;
}
@@ -152,11 +157,13 @@ class MeshEdgebreakerTraversalDecoder {
if (buffer_.bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
start_face_buffer_ = buffer_;
uint64_t traversal_size;
- if (!start_face_buffer_.StartBitDecoding(true, &traversal_size))
+ if (!start_face_buffer_.StartBitDecoding(true, &traversal_size)) {
return false;
+ }
buffer_ = start_face_buffer_;
- if (traversal_size > static_cast<uint64_t>(buffer_.remaining_size()))
+ if (traversal_size > static_cast<uint64_t>(buffer_.remaining_size())) {
return false;
+ }
buffer_.Advance(traversal_size);
return true;
}
@@ -170,8 +177,9 @@ class MeshEdgebreakerTraversalDecoder {
attribute_connectivity_decoders_ = std::unique_ptr<BinaryDecoder[]>(
new BinaryDecoder[num_attribute_data_]);
for (int i = 0; i < num_attribute_data_; ++i) {
- if (!attribute_connectivity_decoders_[i].StartDecoding(&buffer_))
+ if (!attribute_connectivity_decoders_[i].StartDecoding(&buffer_)) {
return false;
+ }
}
}
return true;
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_encoder.h b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_encoder.h
index 08cb66e4cdc..08cb66e4cdc 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_encoder.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_decoder.h b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_decoder.h
index d3289e28c76..3f9004585c6 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_decoder.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_decoder.h
@@ -16,9 +16,8 @@
#ifndef DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_TRAVERSAL_PREDICTIVE_DECODER_H_
#define DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_TRAVERSAL_PREDICTIVE_DECODER_H_
-#include "draco/draco_features.h"
-
#include "draco/compression/mesh/mesh_edgebreaker_traversal_decoder.h"
+#include "draco/draco_features.h"
namespace draco {
@@ -41,17 +40,20 @@ class MeshEdgebreakerTraversalPredictiveDecoder
void SetNumEncodedVertices(int num_vertices) { num_vertices_ = num_vertices; }
bool Start(DecoderBuffer *out_buffer) {
- if (!MeshEdgebreakerTraversalDecoder::Start(out_buffer))
+ if (!MeshEdgebreakerTraversalDecoder::Start(out_buffer)) {
return false;
+ }
int32_t num_split_symbols;
if (!out_buffer->Decode(&num_split_symbols) || num_split_symbols < 0)
return false;
- if (num_split_symbols >= num_vertices_)
+ if (num_split_symbols >= num_vertices_) {
return false;
+ }
// Set the valences of all initial vertices to 0.
vertex_valences_.resize(num_vertices_, 0);
- if (!prediction_decoder_.StartDecoding(out_buffer))
+ if (!prediction_decoder_.StartDecoding(out_buffer)) {
return false;
+ }
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_encoder.h b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_encoder.h
index 118687cc769..eb937fe8080 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_encoder.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_encoder.h
@@ -36,8 +36,9 @@ class MeshEdgebreakerTraversalPredictiveEncoder
num_symbols_(0) {}
bool Init(MeshEdgebreakerEncoderImplInterface *encoder) {
- if (!MeshEdgebreakerTraversalEncoder::Init(encoder))
+ if (!MeshEdgebreakerTraversalEncoder::Init(encoder)) {
return false;
+ }
corner_table_ = encoder->GetCornerTable();
// Initialize valences of all vertices.
vertex_valences_.resize(corner_table_->num_vertices());
diff --git a/extern/draco/dracoenc/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 4da9d0e3a8b..621883a5f1f 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h
@@ -15,11 +15,10 @@
#ifndef DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_TRAVERSAL_VALENCE_DECODER_H_
#define DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_TRAVERSAL_VALENCE_DECODER_H_
-#include "draco/draco_features.h"
-
#include "draco/compression/entropy/symbol_decoding.h"
#include "draco/compression/mesh/mesh_edgebreaker_traversal_decoder.h"
#include "draco/core/varint_decoding.h"
+#include "draco/draco_features.h"
namespace draco {
@@ -46,32 +45,39 @@ class MeshEdgebreakerTraversalValenceDecoder
bool Start(DecoderBuffer *out_buffer) {
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (BitstreamVersion() < DRACO_BITSTREAM_VERSION(2, 2)) {
- if (!MeshEdgebreakerTraversalDecoder::DecodeTraversalSymbols())
+ if (!MeshEdgebreakerTraversalDecoder::DecodeTraversalSymbols()) {
return false;
+ }
}
#endif
- if (!MeshEdgebreakerTraversalDecoder::DecodeStartFaces())
+ if (!MeshEdgebreakerTraversalDecoder::DecodeStartFaces()) {
return false;
- if (!MeshEdgebreakerTraversalDecoder::DecodeAttributeSeams())
+ }
+ if (!MeshEdgebreakerTraversalDecoder::DecodeAttributeSeams()) {
return false;
+ }
*out_buffer = *buffer();
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (BitstreamVersion() < DRACO_BITSTREAM_VERSION(2, 2)) {
uint32_t num_split_symbols;
if (BitstreamVersion() < DRACO_BITSTREAM_VERSION(2, 0)) {
- if (!out_buffer->Decode(&num_split_symbols))
+ if (!out_buffer->Decode(&num_split_symbols)) {
return false;
+ }
} else {
- if (!DecodeVarint(&num_split_symbols, out_buffer))
+ if (!DecodeVarint(&num_split_symbols, out_buffer)) {
return false;
+ }
}
- if (num_split_symbols >= static_cast<uint32_t>(num_vertices_))
+ if (num_split_symbols >= static_cast<uint32_t>(num_vertices_)) {
return false;
+ }
int8_t mode;
- if (!out_buffer->Decode(&mode))
+ if (!out_buffer->Decode(&mode)) {
return false;
+ }
if (mode == EDGEBREAKER_VALENCE_MODE_2_7) {
min_valence_ = 2;
max_valence_ = 7;
@@ -87,8 +93,9 @@ class MeshEdgebreakerTraversalValenceDecoder
max_valence_ = 7;
}
- if (num_vertices_ < 0)
+ if (num_vertices_ < 0) {
return false;
+ }
// Set the valences of all initial vertices to 0.
vertex_valences_.resize(num_vertices_, 0);
@@ -114,8 +121,9 @@ class MeshEdgebreakerTraversalValenceDecoder
// First check if we have a valid context.
if (active_context_ != -1) {
const int context_counter = --context_counters_[active_context_];
- if (context_counter < 0)
+ if (context_counter < 0) {
return TOPOLOGY_INVALID;
+ }
const int symbol_id = context_symbols_[active_context_][context_counter];
last_symbol_ = edge_breaker_symbol_to_topology_id[symbol_id];
} else {
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_encoder.h b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_encoder.h
index ef3a86bf983..c492c84bb45 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_encoder.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_encoder.h
@@ -43,8 +43,9 @@ class MeshEdgebreakerTraversalValenceEncoder
max_valence_(7) {}
bool Init(MeshEdgebreakerEncoderImplInterface *encoder) {
- if (!MeshEdgebreakerTraversalEncoder::Init(encoder))
+ if (!MeshEdgebreakerTraversalEncoder::Init(encoder)) {
return false;
+ }
min_valence_ = 2;
max_valence_ = 7;
corner_table_ = encoder->GetCornerTable();
@@ -117,8 +118,9 @@ class MeshEdgebreakerTraversalValenceEncoder
int num_left_faces = 0;
CornerIndex act_c = corner_table_->Opposite(prev);
while (act_c != kInvalidCornerIndex) {
- if (encoder_impl()->IsFaceEncoded(corner_table_->Face(act_c)))
+ if (encoder_impl()->IsFaceEncoded(corner_table_->Face(act_c))) {
break; // Stop when we reach the first visited face.
+ }
++num_left_faces;
act_c = corner_table_->Opposite(corner_table_->Next(act_c));
}
@@ -132,8 +134,9 @@ class MeshEdgebreakerTraversalValenceEncoder
act_c = corner_table_->Opposite(next);
while (act_c != kInvalidCornerIndex) {
- if (encoder_impl()->IsFaceEncoded(corner_table_->Face(act_c)))
+ if (encoder_impl()->IsFaceEncoded(corner_table_->Face(act_c))) {
break; // Stop when we reach the first visited face.
+ }
++num_right_faces;
// Map corners on the right side to the newly created vertex.
corner_to_vertex_map_[corner_table_->Next(act_c)] = new_vert_id;
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_encoder.cc b/extern/draco/draco/src/draco/compression/mesh/mesh_encoder.cc
index 2da5de1fc82..483ea02a7bc 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_encoder.cc
@@ -25,8 +25,9 @@ void MeshEncoder::SetMesh(const Mesh &m) {
Status MeshEncoder::EncodeGeometryData() {
DRACO_RETURN_IF_ERROR(EncodeConnectivity());
- if (options()->GetGlobalBool("store_number_of_encoded_faces", false))
+ if (options()->GetGlobalBool("store_number_of_encoded_faces", false)) {
ComputeNumberOfEncodedFaces();
+ }
return OkStatus();
}
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_encoder.h b/extern/draco/draco/src/draco/compression/mesh/mesh_encoder.h
index 30ec4fa3492..30ec4fa3492 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_encoder.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_sequential_decoder.cc b/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_decoder.cc
index de71700e160..53f5e8651b8 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_sequential_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_decoder.cc
@@ -28,34 +28,42 @@ bool MeshSequentialDecoder::DecodeConnectivity() {
uint32_t num_points;
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
- if (!buffer()->Decode(&num_faces))
+ if (!buffer()->Decode(&num_faces)) {
return false;
- if (!buffer()->Decode(&num_points))
+ }
+ if (!buffer()->Decode(&num_points)) {
return false;
+ }
} else
#endif
{
- if (!DecodeVarint(&num_faces, buffer()))
+ if (!DecodeVarint(&num_faces, buffer())) {
return false;
- if (!DecodeVarint(&num_points, buffer()))
+ }
+ if (!DecodeVarint(&num_points, buffer())) {
return false;
+ }
}
// Check that num_faces and num_points are valid values.
const uint64_t faces_64 = static_cast<uint64_t>(num_faces);
const uint64_t points_64 = static_cast<uint64_t>(num_points);
// Compressed sequential encoding can only handle (2^32 - 1) / 3 indices.
- if (faces_64 > 0xffffffff / 3)
+ if (faces_64 > 0xffffffff / 3) {
return false;
- if (points_64 > faces_64 * 3)
+ }
+ if (points_64 > faces_64 * 3) {
return false;
+ }
uint8_t connectivity_method;
- if (!buffer()->Decode(&connectivity_method))
+ if (!buffer()->Decode(&connectivity_method)) {
return false;
+ }
if (connectivity_method == 0) {
- if (!DecodeAndDecompressIndices(num_faces))
+ if (!DecodeAndDecompressIndices(num_faces)) {
return false;
+ }
} else {
if (num_points < 256) {
// Decode indices as uint8_t.
@@ -63,8 +71,9 @@ bool MeshSequentialDecoder::DecodeConnectivity() {
Mesh::Face face;
for (int j = 0; j < 3; ++j) {
uint8_t val;
- if (!buffer()->Decode(&val))
+ if (!buffer()->Decode(&val)) {
return false;
+ }
face[j] = val;
}
mesh()->AddFace(face);
@@ -75,8 +84,9 @@ bool MeshSequentialDecoder::DecodeConnectivity() {
Mesh::Face face;
for (int j = 0; j < 3; ++j) {
uint16_t val;
- if (!buffer()->Decode(&val))
+ if (!buffer()->Decode(&val)) {
return false;
+ }
face[j] = val;
}
mesh()->AddFace(face);
@@ -88,8 +98,9 @@ bool MeshSequentialDecoder::DecodeConnectivity() {
Mesh::Face face;
for (int j = 0; j < 3; ++j) {
uint32_t val;
- if (!DecodeVarint(&val, buffer()))
+ if (!DecodeVarint(&val, buffer())) {
return false;
+ }
face[j] = val;
}
mesh()->AddFace(face);
@@ -100,8 +111,9 @@ bool MeshSequentialDecoder::DecodeConnectivity() {
Mesh::Face face;
for (int j = 0; j < 3; ++j) {
uint32_t val;
- if (!buffer()->Decode(&val))
+ if (!buffer()->Decode(&val)) {
return false;
+ }
face[j] = val;
}
mesh()->AddFace(face);
@@ -125,8 +137,9 @@ bool MeshSequentialDecoder::CreateAttributesDecoder(int32_t att_decoder_id) {
bool MeshSequentialDecoder::DecodeAndDecompressIndices(uint32_t num_faces) {
// Get decoded indices differences that were encoded with an entropy code.
std::vector<uint32_t> indices_buffer(num_faces * 3);
- if (!DecodeSymbols(num_faces * 3, 1, buffer(), indices_buffer.data()))
+ if (!DecodeSymbols(num_faces * 3, 1, buffer(), indices_buffer.data())) {
return false;
+ }
// Reconstruct the indices from the differences.
// See MeshSequentialEncoder::CompressAndEncodeIndices() for more details.
int32_t last_index_value = 0;
@@ -136,8 +149,9 @@ bool MeshSequentialDecoder::DecodeAndDecompressIndices(uint32_t num_faces) {
for (int j = 0; j < 3; ++j) {
const uint32_t encoded_val = indices_buffer[vertex_index++];
int32_t index_diff = (encoded_val >> 1);
- if (encoded_val & 1)
+ if (encoded_val & 1) {
index_diff = -index_diff;
+ }
const int32_t index_value = index_diff + last_index_value;
face[j] = index_value;
last_index_value = index_value;
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_sequential_decoder.h b/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_decoder.h
index 3a86c75d5e9..3a86c75d5e9 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_sequential_decoder.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_decoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_sequential_encoder.cc b/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_encoder.cc
index b53ff0c25a6..02ac7779ea3 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_sequential_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_encoder.cc
@@ -37,8 +37,9 @@ Status MeshSequentialEncoder::EncodeConnectivity() {
if (options()->GetGlobalBool("compress_connectivity", false)) {
// 0 = Encode compressed indices.
buffer()->Encode(static_cast<uint8_t>(0));
- if (!CompressAndEncodeIndices())
+ if (!CompressAndEncodeIndices()) {
return Status(Status::DRACO_ERROR, "Failed to compress connectivity.");
+ }
} else {
// 1 = Encode indices directly.
buffer()->Encode(static_cast<uint8_t>(1));
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_sequential_encoder.h b/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_encoder.h
index 672609642b0..672609642b0 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_sequential_encoder.h
+++ b/extern/draco/draco/src/draco/compression/mesh/mesh_sequential_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/traverser/depth_first_traverser.h b/extern/draco/draco/src/draco/compression/mesh/traverser/depth_first_traverser.h
index 84420cb3888..0b387ec3a70 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/traverser/depth_first_traverser.h
+++ b/extern/draco/draco/src/draco/compression/mesh/traverser/depth_first_traverser.h
@@ -57,8 +57,9 @@ class DepthFirstTraverser
void OnTraversalEnd() {}
bool TraverseFromCorner(CornerIndex corner_id) {
- if (this->IsFaceVisited(corner_id))
+ if (this->IsFaceVisited(corner_id)) {
return true; // Already traversed.
+ }
corner_traversal_stack_.clear();
corner_traversal_stack_.push_back(corner_id);
@@ -68,8 +69,9 @@ class DepthFirstTraverser
this->corner_table()->Vertex(this->corner_table()->Next(corner_id));
const VertexIndex prev_vert =
this->corner_table()->Vertex(this->corner_table()->Previous(corner_id));
- if (next_vert == kInvalidVertexIndex || prev_vert == kInvalidVertexIndex)
+ if (next_vert == kInvalidVertexIndex || prev_vert == kInvalidVertexIndex) {
return false;
+ }
if (!this->IsVertexVisited(next_vert)) {
this->MarkVertexVisited(next_vert);
this->traversal_observer().OnNewVertexVisited(
@@ -96,8 +98,9 @@ class DepthFirstTraverser
this->MarkFaceVisited(face_id);
this->traversal_observer().OnNewFaceVisited(face_id);
const VertexIndex vert_id = this->corner_table()->Vertex(corner_id);
- if (vert_id == kInvalidVertexIndex)
+ if (vert_id == kInvalidVertexIndex) {
return false;
+ }
if (!this->IsVertexVisited(vert_id)) {
const bool on_boundary = this->corner_table()->IsOnBoundary(vert_id);
this->MarkVertexVisited(vert_id);
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/traverser/max_prediction_degree_traverser.h b/extern/draco/draco/src/draco/compression/mesh/traverser/max_prediction_degree_traverser.h
index b60d2c159f2..514193eae73 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/traverser/max_prediction_degree_traverser.h
+++ b/extern/draco/draco/src/draco/compression/mesh/traverser/max_prediction_degree_traverser.h
@@ -63,8 +63,9 @@ class MaxPredictionDegreeTraverser
void OnTraversalEnd() {}
bool TraverseFromCorner(CornerIndex corner_id) {
- if (prediction_degree_.size() == 0)
+ if (prediction_degree_.size() == 0) {
return true;
+ }
// Traversal starts from the |corner_id|. It's going to follow either the
// right or the left neighboring faces to |corner_id| based on their
@@ -184,8 +185,9 @@ class MaxPredictionDegreeTraverser
inline void AddCornerToTraversalStack(CornerIndex ci, int priority) {
traversal_stacks_[priority].push_back(ci);
// Make sure that the best available priority is up to date.
- if (priority < best_priority_)
+ if (priority < best_priority_) {
best_priority_ = priority;
+ }
}
// Returns the priority of traversing edge leading to |corner_id|.
@@ -199,8 +201,9 @@ class MaxPredictionDegreeTraverser
priority = (degree > 1 ? 1 : 2);
}
// Clamp the priority to the maximum number of buckets.
- if (priority >= kMaxPriority)
+ if (priority >= kMaxPriority) {
priority = kMaxPriority - 1;
+ }
return priority;
}
diff --git a/extern/draco/dracoenc/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..e66dd14b238 100644
--- a/extern/draco/dracoenc/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
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h b/extern/draco/draco/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h
index fbcda53b792..ebe1d5f7a9e 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h
+++ b/extern/draco/draco/src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h
@@ -56,12 +56,13 @@ class MeshTraversalSequencer : public PointsSequencer {
const PointIndex point_id = face[p];
const VertexIndex vert_id =
corner_table->Vertex(CornerIndex(3 * f.value() + p));
- if (vert_id == kInvalidVertexIndex)
+ if (vert_id == kInvalidVertexIndex) {
return false;
+ }
const AttributeValueIndex att_entry_id(
encoding_data_
->vertex_to_encoded_attribute_value_index_map[vert_id.value()]);
- if (att_entry_id.value() >= num_points) {
+ if (point_id >= num_points || att_entry_id.value() >= num_points) {
// There cannot be more attribute values than the number of points.
return false;
}
@@ -80,14 +81,16 @@ class MeshTraversalSequencer : public PointsSequencer {
traverser_.OnTraversalStart();
if (corner_order_) {
for (uint32_t i = 0; i < corner_order_->size(); ++i) {
- if (!ProcessCorner(corner_order_->at(i)))
+ if (!ProcessCorner(corner_order_->at(i))) {
return false;
+ }
}
} else {
const int32_t num_faces = traverser_.corner_table()->num_faces();
for (int i = 0; i < num_faces; ++i) {
- if (!ProcessCorner(CornerIndex(3 * i)))
+ if (!ProcessCorner(CornerIndex(3 * i))) {
return false;
+ }
}
}
traverser_.OnTraversalEnd();
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/traverser/traverser_base.h b/extern/draco/draco/src/draco/compression/mesh/traverser/traverser_base.h
index 643c5db565b..f2f8da79d09 100644
--- a/extern/draco/dracoenc/src/draco/compression/mesh/traverser/traverser_base.h
+++ b/extern/draco/draco/src/draco/compression/mesh/traverser/traverser_base.h
@@ -43,15 +43,17 @@ class TraverserBase {
const CornerTable &GetCornerTable() const { return *corner_table_; }
inline bool IsFaceVisited(FaceIndex face_id) const {
- if (face_id == kInvalidFaceIndex)
+ if (face_id == kInvalidFaceIndex) {
return true; // Invalid faces are always considered as visited.
+ }
return is_face_visited_[face_id.value()];
}
// Returns true if the face containing the given corner was visited.
inline bool IsFaceVisited(CornerIndex corner_id) const {
- if (corner_id == kInvalidCornerIndex)
+ if (corner_id == kInvalidCornerIndex) {
return true; // Invalid faces are always considered as visited.
+ }
return is_face_visited_[corner_id.value() / 3];
}
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.cc b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.cc
index de46f05af67..de46f05af67 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.cc
diff --git a/extern/draco/dracoenc/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 61a153560ae..87bc2b7ef3e 100644
--- a/extern/draco/dracoenc/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
@@ -155,25 +155,36 @@ template <int compression_level_t>
template <class OutputIteratorT>
bool DynamicIntegerPointsKdTreeDecoder<compression_level_t>::DecodePoints(
DecoderBuffer *buffer, OutputIteratorT &oit) {
- buffer->Decode(&bit_length_);
- if (bit_length_ > 32)
+ if (!buffer->Decode(&bit_length_)) {
return false;
- buffer->Decode(&num_points_);
- if (num_points_ == 0)
+ }
+ if (bit_length_ > 32) {
+ return false;
+ }
+ if (!buffer->Decode(&num_points_)) {
+ return false;
+ }
+ if (num_points_ == 0) {
return true;
+ }
num_decoded_points_ = 0;
- if (!numbers_decoder_.StartDecoding(buffer))
+ if (!numbers_decoder_.StartDecoding(buffer)) {
return false;
- if (!remaining_bits_decoder_.StartDecoding(buffer))
+ }
+ if (!remaining_bits_decoder_.StartDecoding(buffer)) {
return false;
- if (!axis_decoder_.StartDecoding(buffer))
+ }
+ if (!axis_decoder_.StartDecoding(buffer)) {
return false;
- if (!half_decoder_.StartDecoding(buffer))
+ }
+ if (!half_decoder_.StartDecoding(buffer)) {
return false;
+ }
- if (!DecodeInternal(num_points_, oit))
+ if (!DecodeInternal(num_points_, oit)) {
return false;
+ }
numbers_decoder_.EndDecoding();
remaining_bits_decoder_.EndDecoding();
@@ -187,8 +198,9 @@ template <int compression_level_t>
uint32_t DynamicIntegerPointsKdTreeDecoder<compression_level_t>::GetAxis(
uint32_t num_remaining_points, const VectorUint32 &levels,
uint32_t last_axis) {
- if (!Policy::select_axis)
+ if (!Policy::select_axis) {
return DRACO_INCREMENT_MOD(last_axis, dimension_);
+ }
uint32_t best_axis = 0;
if (num_remaining_points < 64) {
@@ -226,12 +238,14 @@ bool DynamicIntegerPointsKdTreeDecoder<compression_level_t>::DecodeInternal(
const VectorUint32 &old_base = base_stack_[stack_pos];
const VectorUint32 &levels = levels_stack_[stack_pos];
- if (num_remaining_points > num_points)
+ if (num_remaining_points > num_points) {
return false;
+ }
const uint32_t axis = GetAxis(num_remaining_points, levels, last_axis);
- if (axis >= dimension_)
+ if (axis >= dimension_) {
return false;
+ }
const uint32_t level = levels[axis];
@@ -258,9 +272,10 @@ bool DynamicIntegerPointsKdTreeDecoder<compression_level_t>::DecodeInternal(
for (uint32_t j = 0; j < dimension_; j++) {
p_[axes_[j]] = 0;
const uint32_t num_remaining_bits = bit_length_ - levels[axes_[j]];
- if (num_remaining_bits)
+ if (num_remaining_bits) {
remaining_bits_decoder_.DecodeLeastSignificantBits32(
num_remaining_bits, &p_[axes_[j]]);
+ }
p_[axes_[j]] = old_base[axes_[j]] | p_[axes_[j]];
}
*oit = p_;
@@ -270,8 +285,9 @@ bool DynamicIntegerPointsKdTreeDecoder<compression_level_t>::DecodeInternal(
continue;
}
- if (num_decoded_points_ > num_points_)
+ if (num_decoded_points_ > num_points_) {
return false;
+ }
const int num_remaining_bits = bit_length_ - level;
const uint32_t modifier = 1 << (num_remaining_bits - 1);
@@ -286,16 +302,20 @@ bool DynamicIntegerPointsKdTreeDecoder<compression_level_t>::DecodeInternal(
uint32_t first_half = num_remaining_points / 2 - number;
uint32_t second_half = num_remaining_points - first_half;
- if (first_half != second_half)
- if (!half_decoder_.DecodeNextBit())
+ if (first_half != second_half) {
+ if (!half_decoder_.DecodeNextBit()) {
std::swap(first_half, second_half);
+ }
+ }
levels_stack_[stack_pos][axis] += 1;
levels_stack_[stack_pos + 1] = levels_stack_[stack_pos]; // copy
- if (first_half)
+ if (first_half) {
status_stack.push(DecodingStatus(first_half, axis, stack_pos));
- if (second_half)
+ }
+ if (second_half) {
status_stack.push(DecodingStatus(second_half, axis, stack_pos + 1));
+ }
}
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.cc b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.cc
index e7abf52c4a2..e7abf52c4a2 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.cc
diff --git a/extern/draco/dracoenc/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 47ac653c85f..14fa32d7083 100644
--- a/extern/draco/dracoenc/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
@@ -191,8 +191,9 @@ bool DynamicIntegerPointsKdTreeEncoder<compression_level_t>::EncodePoints(
buffer->Encode(bit_length_);
buffer->Encode(num_points_);
- if (num_points_ == 0)
+ if (num_points_ == 0) {
return true;
+ }
numbers_encoder_.StartEncoding();
remaining_bits_encoder_.StartEncoding();
@@ -215,8 +216,9 @@ DynamicIntegerPointsKdTreeEncoder<compression_level_t>::GetAndEncodeAxis(
RandomAccessIteratorT begin, RandomAccessIteratorT end,
const VectorUint32 &old_base, const VectorUint32 &levels,
uint32_t last_axis) {
- if (!Policy::select_axis)
+ if (!Policy::select_axis) {
return DRACO_INCREMENT_MOD(last_axis, dimension_);
+ }
// For many points this function selects the axis that should be used
// for the split by keeping as many points as possible bundled.
@@ -296,8 +298,9 @@ void DynamicIntegerPointsKdTreeEncoder<compression_level_t>::EncodeInternal(
const uint32_t num_remaining_points = static_cast<uint32_t>(end - begin);
// If this happens all axis are subdivided to the end.
- if ((bit_length_ - level) == 0)
+ if ((bit_length_ - level) == 0) {
continue;
+ }
// Fast encoding of remaining bits if number of points is 1 or 2.
// Doing this also for 2 gives a slight additional speed up.
@@ -338,8 +341,9 @@ void DynamicIntegerPointsKdTreeEncoder<compression_level_t>::EncodeInternal(
const uint32_t second_half = static_cast<uint32_t>(end - split);
const bool left = first_half < second_half;
- if (first_half != second_half)
+ if (first_half != second_half) {
half_encoder_.EncodeBit(left);
+ }
if (left) {
EncodeNumber(required_bits, num_remaining_points / 2 - first_half);
@@ -349,10 +353,12 @@ void DynamicIntegerPointsKdTreeEncoder<compression_level_t>::EncodeInternal(
levels_stack_[stack_pos][axis] += 1;
levels_stack_[stack_pos + 1] = levels_stack_[stack_pos]; // copy
- if (split != begin)
+ if (split != begin) {
status_stack.push(Status(begin, split, axis, stack_pos));
- if (split != end)
+ }
+ if (split != end) {
status_stack.push(Status(split, end, axis, stack_pos + 1));
+ }
}
}
extern template class DynamicIntegerPointsKdTreeEncoder<0>;
diff --git a/extern/draco/dracoenc/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 98526c4e63d..9e8d895f176 100644
--- a/extern/draco/dracoenc/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
@@ -62,23 +62,20 @@ class ConversionOutputIterator {
};
FloatPointsTreeDecoder::FloatPointsTreeDecoder()
- : num_points_(0), compression_level_(0) {
+ : num_points_(0), compression_level_(0), num_points_from_header_(0) {
qinfo_.quantization_bits = 0;
qinfo_.range = 0;
}
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 (!buffer->Decode(&compression_level_))
+ 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_)
return false;
+ if (!buffer->Decode(&compression_level_)) return false;
// Only allow compression level in [0..6].
if (6 < compression_level_) {
@@ -135,8 +132,9 @@ bool FloatPointsTreeDecoder::DecodePointCloudKdTreeInternal(
}
}
- if (qpoints->size() != num_points_)
+ if (qpoints->size() != num_points_) {
return false;
+ }
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.h b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.h
index d3425696a5a..4f09ed2c31d 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.h
@@ -43,8 +43,9 @@ class FloatPointsTreeDecoder {
template <class OutputIteratorT>
bool DecodePointCloud(const char *data, size_t data_size,
OutputIteratorT out) {
- if (data == 0 || data_size <= 0)
+ if (data == 0 || data_size <= 0) {
return false;
+ }
DecoderBuffer buffer;
buffer.Init(data, data_size);
@@ -65,6 +66,10 @@ class FloatPointsTreeDecoder {
}
}
+ void set_num_points_from_header(uint32_t num_points) {
+ num_points_from_header_ = num_points;
+ }
+
private:
bool DecodePointCloudKdTreeInternal(DecoderBuffer *buffer,
std::vector<Point3ui> *qpoints);
@@ -74,6 +79,11 @@ class FloatPointsTreeDecoder {
PointCloudCompressionMethod method_;
uint32_t num_points_;
uint32_t compression_level_;
+
+ // Member variable to check if the number of points from the file header
+ // matches the number of points in the compression header. If
+ // |num_points_from_header_| is 0, do not perform the check. Defaults to 0.
+ uint32_t num_points_from_header_;
};
#ifndef DRACO_OLD_GCC
@@ -93,26 +103,30 @@ bool FloatPointsTreeDecoder::DecodePointCloud(DecoderBuffer *buffer,
std::vector<Point3ui> qpoints;
uint32_t decoded_version;
- if (!buffer->Decode(&decoded_version))
+ if (!buffer->Decode(&decoded_version)) {
return false;
+ }
if (decoded_version == 3) {
int8_t method_number;
- if (!buffer->Decode(&method_number))
+ if (!buffer->Decode(&method_number)) {
return false;
+ }
method_ = static_cast<PointCloudCompressionMethod>(method_number);
if (method_ == KDTREE) {
- if (!DecodePointCloudKdTreeInternal(buffer, &qpoints))
+ if (!DecodePointCloudKdTreeInternal(buffer, &qpoints)) {
return false;
+ }
} else { // Unsupported method.
fprintf(stderr, "Method not supported. \n");
return false;
}
} else if (decoded_version == 2) { // Version 2 only uses KDTREE method.
- if (!DecodePointCloudKdTreeInternal(buffer, &qpoints))
+ if (!DecodePointCloudKdTreeInternal(buffer, &qpoints)) {
return false;
+ }
} else { // Unsupported version.
fprintf(stderr, "Version not supported. \n");
return false;
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.cc b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.cc
index 317430f2b8e..317430f2b8e 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.cc
diff --git a/extern/draco/dracoenc/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 1fd807427f5..26ba94f1f59 100644
--- a/extern/draco/dracoenc/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
@@ -105,11 +105,13 @@ bool FloatPointsTreeEncoder::EncodePointCloud(InputIteratorT points_begin,
buffer()->Encode(qinfo_.range);
buffer()->Encode(num_points_);
- if (method_ == KDTREE)
+ if (method_ == KDTREE) {
buffer()->Encode(compression_level_);
+ }
- if (num_points_ == 0)
+ if (num_points_ == 0) {
return true;
+ }
if (method_ == KDTREE) {
return EncodePointCloudKdTreeInternal(&qpoints);
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.cc b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.cc
index d0428a28e6a..d0428a28e6a 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.cc
diff --git a/extern/draco/dracoenc/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 06ee718e0f5..94e523cadaf 100644
--- a/extern/draco/dracoenc/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
@@ -153,19 +153,28 @@ template <class PointDiT, int compression_level_t>
template <class OutputIteratorT>
bool IntegerPointsKdTreeDecoder<PointDiT, compression_level_t>::DecodePoints(
DecoderBuffer *buffer, OutputIteratorT oit) {
- buffer->Decode(&bit_length_);
- buffer->Decode(&num_points_);
- if (num_points_ == 0)
+ if (!buffer->Decode(&bit_length_)) {
+ return false;
+ }
+ if (!buffer->Decode(&num_points_)) {
+ return false;
+ }
+ if (num_points_ == 0) {
return true;
+ }
- if (!numbers_decoder_.StartDecoding(buffer))
+ if (!numbers_decoder_.StartDecoding(buffer)) {
return false;
- if (!remaining_bits_decoder_.StartDecoding(buffer))
+ }
+ if (!remaining_bits_decoder_.StartDecoding(buffer)) {
return false;
- if (!axis_decoder_.StartDecoding(buffer))
+ }
+ if (!axis_decoder_.StartDecoding(buffer)) {
return false;
- if (!half_decoder_.StartDecoding(buffer))
+ }
+ if (!half_decoder_.StartDecoding(buffer)) {
return false;
+ }
DecodeInternal(num_points_, PointTraits<PointDiT>::Origin(),
PointTraits<PointDiT>::ZeroArray(), 0, oit);
@@ -182,8 +191,9 @@ template <class PointDiT, int compression_level_t>
uint32_t IntegerPointsKdTreeDecoder<PointDiT, compression_level_t>::GetAxis(
uint32_t num_remaining_points, const PointDiT & /* base */,
std::array<uint32_t, D> levels, uint32_t last_axis) {
- if (!Policy::select_axis)
+ if (!Policy::select_axis) {
return DRACO_INCREMENT_MOD(last_axis, D);
+ }
uint32_t best_axis = 0;
if (num_remaining_points < 64) {
@@ -247,9 +257,10 @@ void IntegerPointsKdTreeDecoder<PointDiT, compression_level_t>::DecodeInternal(
// Get remaining bits, mind the carry if not starting at x.
PointDiT p = PointTraits<PointDiT>::Origin();
for (int j = 0; j < static_cast<int>(D); j++) {
- if (num_remaining_bits[j])
+ if (num_remaining_bits[j]) {
remaining_bits_decoder_.DecodeLeastSignificantBits32(
num_remaining_bits[j], &p[axes[j]]);
+ }
p[axes[j]] = old_base[axes[j]] | p[axes[j]];
}
*oit++ = p;
@@ -270,15 +281,19 @@ void IntegerPointsKdTreeDecoder<PointDiT, compression_level_t>::DecodeInternal(
uint32_t first_half = num_remaining_points / 2 - number;
uint32_t second_half = num_remaining_points - first_half;
- if (first_half != second_half)
- if (!half_decoder_.DecodeNextBit())
+ if (first_half != second_half) {
+ if (!half_decoder_.DecodeNextBit()) {
std::swap(first_half, second_half);
+ }
+ }
levels[axis] += 1;
- if (first_half)
+ if (first_half) {
status_q.push(DecodingStatus(first_half, old_base, levels, axis));
- if (second_half)
+ }
+ if (second_half) {
status_q.push(DecodingStatus(second_half, new_base, levels, axis));
+ }
}
}
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.cc b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.cc
index ee10595003b..ee10595003b 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.cc
diff --git a/extern/draco/dracoenc/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 9a3e8d76f8c..b8811092ed7 100644
--- a/extern/draco/dracoenc/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
@@ -204,8 +204,9 @@ bool IntegerPointsKdTreeEncoder<PointDiT, compression_level_t>::EncodePoints(
buffer->Encode(bit_length_);
buffer->Encode(num_points_);
- if (num_points_ == 0)
+ if (num_points_ == 0) {
return true;
+ }
numbers_encoder_.StartEncoding();
remaining_bits_encoder_.StartEncoding();
@@ -228,8 +229,9 @@ uint32_t IntegerPointsKdTreeEncoder<PointDiT, compression_level_t>::GetAxis(
RandomAccessIteratorT begin, RandomAccessIteratorT end,
const PointDiT &old_base, std::array<uint32_t, D> levels,
uint32_t last_axis) {
- if (!Policy::select_axis)
+ if (!Policy::select_axis) {
return DRACO_INCREMENT_MOD(last_axis, D);
+ }
// For many points this function selects the axis that should be used
// for the split by keeping as many points as possible bundled.
@@ -256,8 +258,9 @@ uint32_t IntegerPointsKdTreeEncoder<PointDiT, compression_level_t>::GetAxis(
PointDiT split(old_base);
for (int i = 0; i < D; i++) {
- if (num_remaining_bits[i])
+ if (num_remaining_bits[i]) {
split[i] += 1 << (num_remaining_bits[i] - 1);
+ }
}
std::array<uint32_t, D> deviations = PointTraits<PointDiT>::ZeroArray();
@@ -316,8 +319,9 @@ void IntegerPointsKdTreeEncoder<PointDiT, compression_level_t>::EncodeInternal(
const uint32_t num_remaining_points = end - begin;
// If this happens all axis are subdivided to the end.
- if ((bit_length_ - level) == 0)
+ if ((bit_length_ - level) == 0) {
continue;
+ }
// Fast encoding of remaining bits if number of points is 1.
// Doing this also for 2 gives a slight additional speed up.
@@ -361,8 +365,9 @@ void IntegerPointsKdTreeEncoder<PointDiT, compression_level_t>::EncodeInternal(
const uint32_t second_half = end - split;
const bool left = first_half < second_half;
- if (first_half != second_half)
+ if (first_half != second_half) {
half_encoder_.EncodeBit(left);
+ }
if (left) {
EncodeNumber(required_bits, num_remaining_points / 2 - first_half);
@@ -371,12 +376,14 @@ void IntegerPointsKdTreeEncoder<PointDiT, compression_level_t>::EncodeInternal(
}
levels[axis] += 1;
- if (split != begin)
+ if (split != begin) {
status_q.push(EncodingStatus<RandomAccessIteratorT>(
begin, split, old_base, levels, axis));
- if (split != end)
+ }
+ if (split != end) {
status_q.push(EncodingStatus<RandomAccessIteratorT>(split, end, new_base,
levels, axis));
+ }
}
}
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/point_cloud_compression_method.h b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/point_cloud_compression_method.h
index 9541c966856..9541c966856 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/point_cloud_compression_method.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/point_cloud_compression_method.h
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/point_cloud_types.h b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/point_cloud_types.h
index 3ed1d13e054..893efbefa32 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/point_cloud_types.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/point_cloud_types.h
@@ -16,6 +16,7 @@
#define DRACO_COMPRESSION_POINT_CLOUD_ALGORITHMS_POINT_CLOUD_TYPES_H_
#include <inttypes.h>
+
#include <vector>
#include "draco/core/vector_d.h"
diff --git a/extern/draco/dracoenc/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 771173032f6..01943ad9e6c 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/quantize_points_3.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/quantize_points_3.h
@@ -16,6 +16,7 @@
#define DRACO_COMPRESSION_POINT_CLOUD_ALGORITHMS_QUANTIZE_POINTS_3_H_
#include <inttypes.h>
+
#include "draco/compression/point_cloud/algorithms/point_cloud_types.h"
#include "draco/core/quantization_utils.h"
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/queuing_policy.h b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/queuing_policy.h
index 2db0ea213b8..2db0ea213b8 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/algorithms/queuing_policy.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/algorithms/queuing_policy.h
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_decoder.cc b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_decoder.cc
index cf5d997e67a..5196edf960c 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_decoder.cc
@@ -28,20 +28,27 @@ PointCloudDecoder::PointCloudDecoder()
Status PointCloudDecoder::DecodeHeader(DecoderBuffer *buffer,
DracoHeader *out_header) {
constexpr char kIoErrorMsg[] = "Failed to parse Draco header.";
- if (!buffer->Decode(out_header->draco_string, 5))
+ if (!buffer->Decode(out_header->draco_string, 5)) {
return Status(Status::IO_ERROR, kIoErrorMsg);
- if (memcmp(out_header->draco_string, "DRACO", 5) != 0)
+ }
+ if (memcmp(out_header->draco_string, "DRACO", 5) != 0) {
return Status(Status::DRACO_ERROR, "Not a Draco file.");
- if (!buffer->Decode(&(out_header->version_major)))
+ }
+ if (!buffer->Decode(&(out_header->version_major))) {
return Status(Status::IO_ERROR, kIoErrorMsg);
- if (!buffer->Decode(&(out_header->version_minor)))
+ }
+ if (!buffer->Decode(&(out_header->version_minor))) {
return Status(Status::IO_ERROR, kIoErrorMsg);
- if (!buffer->Decode(&(out_header->encoder_type)))
+ }
+ if (!buffer->Decode(&(out_header->encoder_type))) {
return Status(Status::IO_ERROR, kIoErrorMsg);
- if (!buffer->Decode(&(out_header->encoder_method)))
+ }
+ if (!buffer->Decode(&(out_header->encoder_method))) {
return Status(Status::IO_ERROR, kIoErrorMsg);
- if (!buffer->Decode(&(out_header->flags)))
+ }
+ if (!buffer->Decode(&(out_header->flags))) {
return Status(Status::IO_ERROR, kIoErrorMsg);
+ }
return OkStatus();
}
@@ -49,8 +56,9 @@ Status PointCloudDecoder::DecodeMetadata() {
std::unique_ptr<GeometryMetadata> metadata =
std::unique_ptr<GeometryMetadata>(new GeometryMetadata());
MetadataDecoder metadata_decoder;
- if (!metadata_decoder.DecodeGeometryMetadata(buffer_, metadata.get()))
+ if (!metadata_decoder.DecodeGeometryMetadata(buffer_, metadata.get())) {
return Status(Status::DRACO_ERROR, "Failed to decode metadata.");
+ }
point_cloud_->AddMetadata(std::move(metadata));
return OkStatus();
}
@@ -65,9 +73,10 @@ Status PointCloudDecoder::Decode(const DecoderOptions &options,
DRACO_RETURN_IF_ERROR(DecodeHeader(buffer_, &header))
// Sanity check that we are really using the right decoder (mostly for cases
// where the Decode method was called manually outside of our main API.
- if (header.encoder_type != GetGeometryType())
+ if (header.encoder_type != GetGeometryType()) {
return Status(Status::DRACO_ERROR,
"Using incompatible decoder for the input geometry.");
+ }
// TODO(ostava): We should check the method as well, but currently decoders
// don't expose the decoding method id.
version_major_ = header.version_major;
@@ -80,11 +89,13 @@ Status PointCloudDecoder::Decode(const DecoderOptions &options,
header.encoder_type == POINT_CLOUD ? kDracoPointCloudBitstreamVersionMinor
: kDracoMeshBitstreamVersionMinor;
// Check for version compatibility.
- if (version_major_ < 1 || version_major_ > max_supported_major_version)
+ if (version_major_ < 1 || version_major_ > max_supported_major_version) {
return Status(Status::UNKNOWN_VERSION, "Unknown major version.");
+ }
if (version_major_ == max_supported_major_version &&
- version_minor_ > max_supported_minor_version)
+ version_minor_ > max_supported_minor_version) {
return Status(Status::UNKNOWN_VERSION, "Unknown minor version.");
+ }
buffer_->set_bitstream_version(
DRACO_BITSTREAM_VERSION(version_major_, version_minor_));
@@ -92,37 +103,44 @@ Status PointCloudDecoder::Decode(const DecoderOptions &options,
(header.flags & METADATA_FLAG_MASK)) {
DRACO_RETURN_IF_ERROR(DecodeMetadata())
}
- if (!InitializeDecoder())
+ if (!InitializeDecoder()) {
return Status(Status::DRACO_ERROR, "Failed to initialize the decoder.");
- if (!DecodeGeometryData())
+ }
+ if (!DecodeGeometryData()) {
return Status(Status::DRACO_ERROR, "Failed to decode geometry data.");
- if (!DecodePointAttributes())
+ }
+ if (!DecodePointAttributes()) {
return Status(Status::DRACO_ERROR, "Failed to decode point attributes.");
+ }
return OkStatus();
}
bool PointCloudDecoder::DecodePointAttributes() {
uint8_t num_attributes_decoders;
- if (!buffer_->Decode(&num_attributes_decoders))
+ if (!buffer_->Decode(&num_attributes_decoders)) {
return false;
+ }
// Create all attribute decoders. This is implementation specific and the
// derived classes can use any data encoded in the
// PointCloudEncoder::EncodeAttributesEncoderIdentifier() call.
for (int i = 0; i < num_attributes_decoders; ++i) {
- if (!CreateAttributesDecoder(i))
+ if (!CreateAttributesDecoder(i)) {
return false;
+ }
}
// Initialize all attributes decoders. No data is decoded here.
for (auto &att_dec : attributes_decoders_) {
- if (!att_dec->Init(this, point_cloud_))
+ if (!att_dec->Init(this, point_cloud_)) {
return false;
+ }
}
// Decode any data needed by the attribute decoders.
for (int i = 0; i < num_attributes_decoders; ++i) {
- if (!attributes_decoders_[i]->DecodeAttributesDecoderData(buffer_))
+ if (!attributes_decoders_[i]->DecodeAttributesDecoderData(buffer_)) {
return false;
+ }
}
// Create map between attribute and decoder ids.
@@ -138,26 +156,30 @@ bool PointCloudDecoder::DecodePointAttributes() {
}
// Decode the actual attributes using the created attribute decoders.
- if (!DecodeAllAttributes())
+ if (!DecodeAllAttributes()) {
return false;
+ }
- if (!OnAttributesDecoded())
+ if (!OnAttributesDecoded()) {
return false;
+ }
return true;
}
bool PointCloudDecoder::DecodeAllAttributes() {
for (auto &att_dec : attributes_decoders_) {
- if (!att_dec->DecodeAttributes(buffer_))
+ if (!att_dec->DecodeAttributes(buffer_)) {
return false;
+ }
}
return true;
}
const PointAttribute *PointCloudDecoder::GetPortableAttribute(
int32_t parent_att_id) {
- if (parent_att_id < 0 || parent_att_id >= point_cloud_->num_attributes())
+ if (parent_att_id < 0 || parent_att_id >= point_cloud_->num_attributes()) {
return nullptr;
+ }
const int32_t parent_att_decoder_id =
attribute_to_decoder_map_[parent_att_id];
return attributes_decoders_[parent_att_decoder_id]->GetPortableAttribute(
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_decoder.h b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_decoder.h
index abcb5e068f7..4af7f5cd32c 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_decoder.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_decoder.h
@@ -42,10 +42,12 @@ class PointCloudDecoder {
bool SetAttributesDecoder(
int att_decoder_id, std::unique_ptr<AttributesDecoderInterface> decoder) {
- if (att_decoder_id < 0)
+ if (att_decoder_id < 0) {
return false;
- if (att_decoder_id >= static_cast<int>(attributes_decoders_.size()))
+ }
+ if (att_decoder_id >= static_cast<int>(attributes_decoders_.size())) {
attributes_decoders_.resize(att_decoder_id + 1);
+ }
attributes_decoders_[att_decoder_id] = std::move(decoder);
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_encoder.cc b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_encoder.cc
index 986706582f0..b4b0ee94093 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_encoder.cc
@@ -35,19 +35,24 @@ Status PointCloudEncoder::Encode(const EncoderOptions &options,
attribute_to_encoder_map_.clear();
attributes_encoder_ids_order_.clear();
- if (!point_cloud_)
+ if (!point_cloud_) {
return Status(Status::DRACO_ERROR, "Invalid input geometry.");
+ }
DRACO_RETURN_IF_ERROR(EncodeHeader())
DRACO_RETURN_IF_ERROR(EncodeMetadata())
- if (!InitializeEncoder())
+ if (!InitializeEncoder()) {
return Status(Status::DRACO_ERROR, "Failed to initialize encoder.");
- if (!EncodeEncoderData())
+ }
+ if (!EncodeEncoderData()) {
return Status(Status::DRACO_ERROR, "Failed to encode internal data.");
+ }
DRACO_RETURN_IF_ERROR(EncodeGeometryData());
- if (!EncodePointAttributes())
+ if (!EncodePointAttributes()) {
return Status(Status::DRACO_ERROR, "Failed to encode point attributes.");
- if (options.GetGlobalBool("store_number_of_encoded_points", false))
+ }
+ if (options.GetGlobalBool("store_number_of_encoded_points", false)) {
ComputeNumberOfEncodedPoints();
+ }
return OkStatus();
}
@@ -92,8 +97,9 @@ Status PointCloudEncoder::EncodeMetadata() {
}
bool PointCloudEncoder::EncodePointAttributes() {
- if (!GenerateAttributesEncoders())
+ if (!GenerateAttributesEncoders()) {
return false;
+ }
// Encode the number of attribute encoders.
buffer_->Encode(static_cast<uint8_t>(attributes_encoders_.size()));
@@ -101,39 +107,45 @@ bool PointCloudEncoder::EncodePointAttributes() {
// Initialize all the encoders (this is used for example to init attribute
// dependencies, no data is encoded in this step).
for (auto &att_enc : attributes_encoders_) {
- if (!att_enc->Init(this, point_cloud_))
+ if (!att_enc->Init(this, point_cloud_)) {
return false;
+ }
}
// Rearrange attributes to respect dependencies between individual attributes.
- if (!RearrangeAttributesEncoders())
+ if (!RearrangeAttributesEncoders()) {
return false;
+ }
// Encode any data that is necessary to create the corresponding attribute
// decoder.
for (int att_encoder_id : attributes_encoder_ids_order_) {
- if (!EncodeAttributesEncoderIdentifier(att_encoder_id))
+ if (!EncodeAttributesEncoderIdentifier(att_encoder_id)) {
return false;
+ }
}
// Also encode any attribute encoder data (such as the info about encoded
// attributes).
for (int att_encoder_id : attributes_encoder_ids_order_) {
if (!attributes_encoders_[att_encoder_id]->EncodeAttributesEncoderData(
- buffer_))
+ buffer_)) {
return false;
+ }
}
// Lastly encode all the attributes using the provided attribute encoders.
- if (!EncodeAllAttributes())
+ if (!EncodeAllAttributes()) {
return false;
+ }
return true;
}
bool PointCloudEncoder::GenerateAttributesEncoders() {
for (int i = 0; i < point_cloud_->num_attributes(); ++i) {
- if (!GenerateAttributesEncoder(i))
+ if (!GenerateAttributesEncoder(i)) {
return false;
+ }
}
attribute_to_encoder_map_.resize(point_cloud_->num_attributes());
for (uint32_t i = 0; i < attributes_encoders_.size(); ++i) {
@@ -146,27 +158,31 @@ bool PointCloudEncoder::GenerateAttributesEncoders() {
bool PointCloudEncoder::EncodeAllAttributes() {
for (int att_encoder_id : attributes_encoder_ids_order_) {
- if (!attributes_encoders_[att_encoder_id]->EncodeAttributes(buffer_))
+ if (!attributes_encoders_[att_encoder_id]->EncodeAttributes(buffer_)) {
return false;
+ }
}
return true;
}
bool PointCloudEncoder::MarkParentAttribute(int32_t parent_att_id) {
- if (parent_att_id < 0 || parent_att_id >= point_cloud_->num_attributes())
+ if (parent_att_id < 0 || parent_att_id >= point_cloud_->num_attributes()) {
return false;
+ }
const int32_t parent_att_encoder_id =
attribute_to_encoder_map_[parent_att_id];
if (!attributes_encoders_[parent_att_encoder_id]->MarkParentAttribute(
- parent_att_id))
+ parent_att_id)) {
return false;
+ }
return true;
}
const PointAttribute *PointCloudEncoder::GetPortableAttribute(
int32_t parent_att_id) {
- if (parent_att_id < 0 || parent_att_id >= point_cloud_->num_attributes())
+ if (parent_att_id < 0 || parent_att_id >= point_cloud_->num_attributes()) {
return nullptr;
+ }
const int32_t parent_att_encoder_id =
attribute_to_encoder_map_[parent_att_id];
return attributes_encoders_[parent_att_encoder_id]->GetPortableAttribute(
@@ -193,8 +209,9 @@ bool PointCloudEncoder::RearrangeAttributesEncoders() {
// Flagged when any of the encoder get processed.
bool encoder_processed = false;
for (uint32_t i = 0; i < attributes_encoders_.size(); ++i) {
- if (is_encoder_processed[i])
+ if (is_encoder_processed[i]) {
continue; // Encoder already processed.
+ }
// Check if all parent encoders are already processed.
bool can_be_processed = true;
for (uint32_t p = 0; p < attributes_encoders_[i]->num_attributes(); ++p) {
@@ -211,8 +228,9 @@ bool PointCloudEncoder::RearrangeAttributesEncoders() {
}
}
}
- if (!can_be_processed)
+ if (!can_be_processed) {
continue; // Try to process the encoder in the next iteration.
+ }
// Encoder can be processed. Update the encoding order.
attributes_encoder_ids_order_[num_processed_encoders++] = i;
is_encoder_processed[i] = true;
@@ -238,8 +256,9 @@ bool PointCloudEncoder::RearrangeAttributesEncoders() {
const int ae = attributes_encoder_ids_order_[ae_order];
const int32_t num_encoder_attributes =
attributes_encoders_[ae]->num_attributes();
- if (num_encoder_attributes < 2)
+ if (num_encoder_attributes < 2) {
continue; // No need to resolve dependencies for a single attribute.
+ }
num_processed_attributes = 0;
attribute_encoding_order.resize(num_encoder_attributes);
while (num_processed_attributes < num_encoder_attributes) {
@@ -247,8 +266,9 @@ bool PointCloudEncoder::RearrangeAttributesEncoders() {
bool attribute_processed = false;
for (int i = 0; i < num_encoder_attributes; ++i) {
const int32_t att_id = attributes_encoders_[ae]->GetAttributeId(i);
- if (is_attribute_processed[i])
+ if (is_attribute_processed[i]) {
continue; // Attribute already processed.
+ }
// Check if all parent attributes are already processed.
bool can_be_processed = true;
for (int p = 0;
@@ -260,8 +280,9 @@ bool PointCloudEncoder::RearrangeAttributesEncoders() {
break;
}
}
- if (!can_be_processed)
+ if (!can_be_processed) {
continue; // Try to process the attribute in the next iteration.
+ }
// Attribute can be processed. Update the encoding order.
attribute_encoding_order[num_processed_attributes++] = i;
is_attribute_processed[i] = true;
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_encoder.h b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_encoder.h
index 8883f17a789..8883f17a789 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_encoder.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.cc b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.cc
index c35fd79df60..2deebbc4853 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.cc
@@ -20,10 +20,12 @@ namespace draco {
bool PointCloudKdTreeDecoder::DecodeGeometryData() {
int32_t num_points;
- if (!buffer()->Decode(&num_points))
+ if (!buffer()->Decode(&num_points)) {
return false;
- if (num_points < 0)
+ }
+ if (num_points < 0) {
return false;
+ }
point_cloud()->set_num_points(num_points);
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.h b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.h
index 6e192f2a5a0..6e192f2a5a0 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.cc b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.cc
index 6d0446baad1..92b6c84cd63 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.cc
@@ -13,6 +13,7 @@
// limitations under the License.
//
#include "draco/compression/point_cloud/point_cloud_kd_tree_encoder.h"
+
#include "draco/compression/attributes/kd_tree_attributes_encoder.h"
namespace draco {
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.h b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.h
index 6acbb949d40..6acbb949d40 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_sequential_decoder.cc b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_sequential_decoder.cc
index 614cf37b266..b9382d31070 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_sequential_decoder.cc
+++ b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_sequential_decoder.cc
@@ -21,8 +21,9 @@ namespace draco {
bool PointCloudSequentialDecoder::DecodeGeometryData() {
int32_t num_points;
- if (!buffer()->Decode(&num_points))
+ if (!buffer()->Decode(&num_points)) {
return false;
+ }
point_cloud()->set_num_points(num_points);
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_sequential_decoder.h b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_sequential_decoder.h
index 9968dc27517..9968dc27517 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_sequential_decoder.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_sequential_decoder.h
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_sequential_encoder.cc b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_sequential_encoder.cc
index fa7b6fd905c..fa7b6fd905c 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_sequential_encoder.cc
+++ b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_sequential_encoder.cc
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_sequential_encoder.h b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_sequential_encoder.h
index 40d8edcdbb0..40d8edcdbb0 100644
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_sequential_encoder.h
+++ b/extern/draco/draco/src/draco/compression/point_cloud/point_cloud_sequential_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/core/bit_utils.cc b/extern/draco/draco/src/draco/core/bit_utils.cc
index 37119a7171b..37119a7171b 100644
--- a/extern/draco/dracoenc/src/draco/core/bit_utils.cc
+++ b/extern/draco/draco/src/draco/core/bit_utils.cc
diff --git a/extern/draco/dracoenc/src/draco/core/bit_utils.h b/extern/draco/draco/src/draco/core/bit_utils.h
index f63cd0750c9..a102095c719 100644
--- a/extern/draco/dracoenc/src/draco/core/bit_utils.h
+++ b/extern/draco/draco/src/draco/core/bit_utils.h
@@ -20,6 +20,7 @@
#include <inttypes.h>
#include <stdint.h>
+
#include <type_traits>
#if defined(_MSC_VER)
diff --git a/extern/draco/dracoenc/src/draco/core/bounding_box.cc b/extern/draco/draco/src/draco/core/bounding_box.cc
index d95b1e90759..d95b1e90759 100644
--- a/extern/draco/dracoenc/src/draco/core/bounding_box.cc
+++ b/extern/draco/draco/src/draco/core/bounding_box.cc
diff --git a/extern/draco/dracoenc/src/draco/core/bounding_box.h b/extern/draco/draco/src/draco/core/bounding_box.h
index 0259267c99c..1c20fad8bf2 100644
--- a/extern/draco/dracoenc/src/draco/core/bounding_box.h
+++ b/extern/draco/draco/src/draco/core/bounding_box.h
@@ -36,10 +36,12 @@ class BoundingBox {
// argument to an iterator.
inline void update_bounding_box(const Vector3f &new_point) {
for (int i = 0; i < 3; i++) {
- if (new_point[i] < min_point_[i])
+ if (new_point[i] < min_point_[i]) {
min_point_[i] = new_point[i];
- if (new_point[i] > max_point_[i])
+ }
+ if (new_point[i] > max_point_[i]) {
max_point_[i] = new_point[i];
+ }
}
}
diff --git a/extern/draco/dracoenc/src/draco/core/cycle_timer.cc b/extern/draco/draco/src/draco/core/cycle_timer.cc
index 1eea9f59702..94b4b28b2f9 100644
--- a/extern/draco/dracoenc/src/draco/core/cycle_timer.cc
+++ b/extern/draco/draco/src/draco/core/cycle_timer.cc
@@ -19,7 +19,7 @@ void DracoTimer::Start() {
#ifdef _WIN32
QueryPerformanceCounter(&tv_start);
#else
- gettimeofday(&tv_start, NULL);
+ gettimeofday(&tv_start, nullptr);
#endif
}
@@ -27,7 +27,7 @@ void DracoTimer::Stop() {
#ifdef _WIN32
QueryPerformanceCounter(&tv_end);
#else
- gettimeofday(&tv_end, NULL);
+ gettimeofday(&tv_end, nullptr);
#endif
}
diff --git a/extern/draco/dracoenc/src/draco/core/cycle_timer.h b/extern/draco/draco/src/draco/core/cycle_timer.h
index 172f1c2e9b5..172f1c2e9b5 100644
--- a/extern/draco/dracoenc/src/draco/core/cycle_timer.h
+++ b/extern/draco/draco/src/draco/core/cycle_timer.h
diff --git a/extern/draco/dracoenc/src/draco/core/data_buffer.cc b/extern/draco/draco/src/draco/core/data_buffer.cc
index 867760a6fcc..f0b43d67dbd 100644
--- a/extern/draco/dracoenc/src/draco/core/data_buffer.cc
+++ b/extern/draco/draco/src/draco/core/data_buffer.cc
@@ -13,6 +13,7 @@
// limitations under the License.
//
#include "draco/core/data_buffer.h"
+
#include <algorithm>
namespace draco {
@@ -26,15 +27,18 @@ bool DataBuffer::Update(const void *data, int64_t size) {
bool DataBuffer::Update(const void *data, int64_t size, int64_t offset) {
if (data == nullptr) {
- if (size + offset < 0)
+ if (size + offset < 0) {
return false;
+ }
// If no data is provided, just resize the buffer.
data_.resize(size + offset);
} else {
- if (size < 0)
+ if (size < 0) {
return false;
- if (size + offset > static_cast<int64_t>(data_.size()))
+ }
+ if (size + offset > static_cast<int64_t>(data_.size())) {
data_.resize(size + offset);
+ }
const uint8_t *const byte_data = static_cast<const uint8_t *>(data);
std::copy(byte_data, byte_data + size, data_.data() + offset);
}
@@ -48,8 +52,9 @@ void DataBuffer::Resize(int64_t size) {
}
void DataBuffer::WriteDataToStream(std::ostream &stream) {
- if (data_.size() == 0)
+ if (data_.size() == 0) {
return;
+ }
stream.write(reinterpret_cast<char *>(data_.data()), data_.size());
}
diff --git a/extern/draco/dracoenc/src/draco/core/data_buffer.h b/extern/draco/draco/src/draco/core/data_buffer.h
index 8ee690540bc..8ee690540bc 100644
--- a/extern/draco/dracoenc/src/draco/core/data_buffer.h
+++ b/extern/draco/draco/src/draco/core/data_buffer.h
diff --git a/extern/draco/dracoenc/src/draco/core/decoder_buffer.cc b/extern/draco/draco/src/draco/core/decoder_buffer.cc
index 5ce1f064ac2..4e8ed618d92 100644
--- a/extern/draco/dracoenc/src/draco/core/decoder_buffer.cc
+++ b/extern/draco/draco/src/draco/core/decoder_buffer.cc
@@ -41,13 +41,15 @@ bool DecoderBuffer::StartBitDecoding(bool decode_size, uint64_t *out_size) {
if (decode_size) {
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (bitstream_version_ < DRACO_BITSTREAM_VERSION(2, 2)) {
- if (!Decode(out_size))
+ if (!Decode(out_size)) {
return false;
+ }
} else
#endif
{
- if (!DecodeVarint(out_size, this))
+ if (!DecodeVarint(out_size, this)) {
return false;
+ }
}
}
bit_mode_ = true;
diff --git a/extern/draco/dracoenc/src/draco/core/decoder_buffer.h b/extern/draco/draco/src/draco/core/decoder_buffer.h
index 5e3d1ac738d..0559abbe415 100644
--- a/extern/draco/dracoenc/src/draco/core/decoder_buffer.h
+++ b/extern/draco/draco/src/draco/core/decoder_buffer.h
@@ -16,12 +16,12 @@
#define DRACO_CORE_DECODER_BUFFER_H_
#include <stdint.h>
+
#include <cstring>
#include <memory>
-#include "draco/draco_features.h"
-
#include "draco/core/macros.h"
+#include "draco/draco_features.h"
namespace draco {
@@ -55,8 +55,9 @@ 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) {
- if (!bit_decoder_active())
+ if (!bit_decoder_active()) {
return false;
+ }
bit_decoder_.GetBits(nbits, out_value);
return true;
}
@@ -66,15 +67,17 @@ class DecoderBuffer {
// Returns false on error.
template <typename T>
bool Decode(T *out_val) {
- if (!Peek(out_val))
+ if (!Peek(out_val)) {
return false;
+ }
pos_ += sizeof(T);
return true;
}
bool Decode(void *out_data, size_t size_to_decode) {
- if (data_size_ < static_cast<int64_t>(pos_ + size_to_decode))
+ if (data_size_ < static_cast<int64_t>(pos_ + size_to_decode)) {
return false; // Buffer overflow.
+ }
memcpy(out_data, (data_ + pos_), size_to_decode);
pos_ += size_to_decode;
return true;
@@ -84,15 +87,17 @@ class DecoderBuffer {
template <typename T>
bool Peek(T *out_val) {
const size_t size_to_decode = sizeof(T);
- if (data_size_ < static_cast<int64_t>(pos_ + size_to_decode))
+ if (data_size_ < static_cast<int64_t>(pos_ + size_to_decode)) {
return false; // Buffer overflow.
+ }
memcpy(out_val, (data_ + pos_), size_to_decode);
return true;
}
bool Peek(void *out_data, size_t size_to_peek) {
- if (data_size_ < static_cast<int64_t>(pos_ + size_to_peek))
+ if (data_size_ < static_cast<int64_t>(pos_ + size_to_peek)) {
return false; // Buffer overflow.
+ }
memcpy(out_data, (data_ + pos_), size_to_peek);
return true;
}
@@ -157,8 +162,9 @@ class DecoderBuffer {
DRACO_DCHECK_GE(nbits, 0);
DRACO_DCHECK_LE(nbits, 32);
uint32_t value = 0;
- for (int32_t bit = 0; bit < nbits; ++bit)
+ for (int32_t bit = 0; bit < nbits; ++bit) {
value |= GetBit() << bit;
+ }
*x = value;
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/core/divide.cc b/extern/draco/draco/src/draco/core/divide.cc
index 6d2e57120c8..6d2e57120c8 100644
--- a/extern/draco/dracoenc/src/draco/core/divide.cc
+++ b/extern/draco/draco/src/draco/core/divide.cc
diff --git a/extern/draco/dracoenc/src/draco/core/divide.h b/extern/draco/draco/src/draco/core/divide.h
index 2217c861e0b..7e3838a008c 100644
--- a/extern/draco/dracoenc/src/draco/core/divide.h
+++ b/extern/draco/draco/src/draco/core/divide.h
@@ -19,6 +19,7 @@
// This file is based off libvpx's divide.h.
#include <stdint.h>
+
#include <climits>
namespace draco {
diff --git a/extern/draco/dracoenc/src/draco/core/draco_index_type.h b/extern/draco/draco/src/draco/core/draco_index_type.h
index d9dd3f64fa8..d9dd3f64fa8 100644
--- a/extern/draco/dracoenc/src/draco/core/draco_index_type.h
+++ b/extern/draco/draco/src/draco/core/draco_index_type.h
diff --git a/extern/draco/dracoenc/src/draco/core/draco_index_type_vector.h b/extern/draco/draco/src/draco/core/draco_index_type_vector.h
index e2062ef3f35..d47ab3b04eb 100644
--- a/extern/draco/dracoenc/src/draco/core/draco_index_type_vector.h
+++ b/extern/draco/draco/src/draco/core/draco_index_type_vector.h
@@ -28,7 +28,7 @@ namespace draco {
// draco_index_type.h .
// TODO(ostava): Make the interface more complete. It's currently missing
// features such as iterators.
-// TODO(draco-eng): Make unit tests for this class.
+// TODO(vytyaz): Add more unit tests for this class.
template <class IndexTypeT, class ValueTypeT>
class IndexTypeVector {
public:
@@ -50,10 +50,16 @@ class IndexTypeVector {
}
size_t size() const { return vector_.size(); }
+ bool empty() const { return vector_.empty(); }
void push_back(const ValueTypeT &val) { vector_.push_back(val); }
void push_back(ValueTypeT &&val) { vector_.push_back(std::move(val)); }
+ template <typename... Args>
+ void emplace_back(Args &&... args) {
+ vector_.emplace_back(std::forward<Args>(args)...);
+ }
+
inline reference operator[](const IndexTypeT &index) {
return vector_[index.value()];
}
diff --git a/extern/draco/dracoenc/src/draco/core/draco_types.cc b/extern/draco/draco/src/draco/core/draco_types.cc
index 9bde05fda80..9bde05fda80 100644
--- a/extern/draco/dracoenc/src/draco/core/draco_types.cc
+++ b/extern/draco/draco/src/draco/core/draco_types.cc
diff --git a/extern/draco/dracoenc/src/draco/core/draco_types.h b/extern/draco/draco/src/draco/core/draco_types.h
index f5a21e4f1d0..d14437a0214 100644
--- a/extern/draco/dracoenc/src/draco/core/draco_types.h
+++ b/extern/draco/draco/src/draco/core/draco_types.h
@@ -16,6 +16,7 @@
#define DRACO_CORE_DRACO_TYPES_H_
#include <stdint.h>
+
#include <string>
#include "draco/draco_features.h"
diff --git a/extern/draco/dracoenc/src/draco/core/draco_version.h b/extern/draco/draco/src/draco/core/draco_version.h
index 9d3a67e4f8e..ffd7948c64d 100644
--- a/extern/draco/dracoenc/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.5";
+static const char kDracoVersion[] = "1.3.6";
const char *Version() { return kDracoVersion; }
diff --git a/extern/draco/dracoenc/src/draco/core/encoder_buffer.cc b/extern/draco/draco/src/draco/core/encoder_buffer.cc
index a5e936fd89b..df98677a85b 100644
--- a/extern/draco/dracoenc/src/draco/core/encoder_buffer.cc
+++ b/extern/draco/draco/src/draco/core/encoder_buffer.cc
@@ -31,10 +31,12 @@ void EncoderBuffer::Clear() {
void EncoderBuffer::Resize(int64_t nbytes) { buffer_.resize(nbytes); }
bool EncoderBuffer::StartBitEncoding(int64_t required_bits, bool encode_size) {
- if (bit_encoder_active())
+ if (bit_encoder_active()) {
return false; // Bit encoding mode already active.
- if (required_bits <= 0)
+ }
+ if (required_bits <= 0) {
return false; // Invalid size.
+ }
encode_bit_sequence_size_ = encode_size;
const int64_t required_bytes = (required_bits + 7) / 8;
bit_encoder_reserved_bytes_ = required_bytes;
@@ -54,8 +56,9 @@ bool EncoderBuffer::StartBitEncoding(int64_t required_bits, bool encode_size) {
}
void EncoderBuffer::EndBitEncoding() {
- if (!bit_encoder_active())
+ if (!bit_encoder_active()) {
return;
+ }
// Get the number of encoded bits and bytes (rounded up).
const uint64_t encoded_bits = bit_encoder_->Bits();
const uint64_t encoded_bytes = (encoded_bits + 7) / 8;
diff --git a/extern/draco/dracoenc/src/draco/core/encoder_buffer.h b/extern/draco/draco/src/draco/core/encoder_buffer.h
index ff3e89ba270..b153a629792 100644
--- a/extern/draco/dracoenc/src/draco/core/encoder_buffer.h
+++ b/extern/draco/draco/src/draco/core/encoder_buffer.h
@@ -47,8 +47,9 @@ class EncoderBuffer {
// Encode up to 32 bits into the buffer. Can be called only in between
// StartBitEncoding and EndBitEncoding. Otherwise returns false.
bool EncodeLeastSignificantBits32(int nbits, uint32_t value) {
- if (!bit_encoder_active())
+ if (!bit_encoder_active()) {
return false;
+ }
bit_encoder_->PutBits(value, nbits);
return true;
}
@@ -57,15 +58,17 @@ class EncoderBuffer {
// Returns false when the value couldn't be encoded.
template <typename T>
bool Encode(const T &data) {
- if (bit_encoder_active())
+ if (bit_encoder_active()) {
return false;
+ }
const uint8_t *src_data = reinterpret_cast<const uint8_t *>(&data);
buffer_.insert(buffer_.end(), src_data, src_data + sizeof(T));
return true;
}
bool Encode(const void *data, size_t data_size) {
- if (bit_encoder_active())
+ if (bit_encoder_active()) {
return false;
+ }
const uint8_t *src_data = reinterpret_cast<const uint8_t *>(data);
buffer_.insert(buffer_.end(), src_data, src_data + data_size);
return true;
@@ -87,8 +90,9 @@ class EncoderBuffer {
void PutBits(uint32_t data, int32_t nbits) {
DRACO_DCHECK_GE(nbits, 0);
DRACO_DCHECK_LE(nbits, 32);
- for (int32_t bit = 0; bit < nbits; ++bit)
+ for (int32_t bit = 0; bit < nbits; ++bit) {
PutBit((data >> bit) & 1);
+ }
}
// Return number of bits encoded so far.
diff --git a/extern/draco/dracoenc/src/draco/core/hash_utils.cc b/extern/draco/draco/src/draco/core/hash_utils.cc
index 9a78c2cfafd..fbbd653f369 100644
--- a/extern/draco/dracoenc/src/draco/core/hash_utils.cc
+++ b/extern/draco/draco/src/draco/core/hash_utils.cc
@@ -50,8 +50,9 @@ uint64_t FingerprintString(const char *s, size_t len) {
hash = HashCombine(new_hash, hash);
}
- if (hash < std::numeric_limits<uint64_t>::max() - 1)
+ if (hash < std::numeric_limits<uint64_t>::max() - 1) {
hash += 2;
+ }
return hash;
}
} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/core/hash_utils.h b/extern/draco/draco/src/draco/core/hash_utils.h
index 0e8da60aa54..aa61523e7fe 100644
--- a/extern/draco/dracoenc/src/draco/core/hash_utils.h
+++ b/extern/draco/draco/src/draco/core/hash_utils.h
@@ -16,9 +16,9 @@
#define DRACO_CORE_HASH_UTILS_H_
#include <stdint.h>
-#include <functional>
-// TODO(fgalligan): Move this to core.
+#include <cstddef>
+#include <functional>
namespace draco {
diff --git a/extern/draco/dracoenc/src/draco/core/macros.h b/extern/draco/draco/src/draco/core/macros.h
index 09819e63969..89b706e53a5 100644
--- a/extern/draco/dracoenc/src/draco/core/macros.h
+++ b/extern/draco/draco/src/draco/core/macros.h
@@ -16,7 +16,6 @@
#define DRACO_CORE_MACROS_H_
#include "assert.h"
-
#include "draco/draco_features.h"
#ifdef ANDROID_LOGGING
diff --git a/extern/draco/dracoenc/src/draco/core/math_utils.h b/extern/draco/draco/src/draco/core/math_utils.h
index 50cf5d57199..7f382fa34d4 100644
--- a/extern/draco/dracoenc/src/draco/core/math_utils.h
+++ b/extern/draco/draco/src/draco/core/math_utils.h
@@ -27,8 +27,9 @@
// replacement for std::sqrt() for general cases. IntSqrt is in fact about 3X
// slower compared to most implementation of std::sqrt().
inline uint64_t IntSqrt(uint64_t number) {
- if (number == 0)
+ if (number == 0) {
return 0;
+ }
// First estimate good initial value of the square root as log2(number).
uint64_t act_number = number;
uint64_t square_root = 1;
diff --git a/extern/draco/dracoenc/src/draco/core/options.cc b/extern/draco/draco/src/draco/core/options.cc
index a9ce14b9837..9b81db48987 100644
--- a/extern/draco/dracoenc/src/draco/core/options.cc
+++ b/extern/draco/draco/src/draco/core/options.cc
@@ -23,8 +23,9 @@ namespace draco {
Options::Options() {}
void Options::MergeAndReplace(const Options &other_options) {
- for (const auto &item : other_options.options_)
+ for (const auto &item : other_options.options_) {
options_[item.first] = item.second;
+ }
}
void Options::SetInt(const std::string &name, int val) {
@@ -47,8 +48,9 @@ int Options::GetInt(const std::string &name) const { return GetInt(name, -1); }
int Options::GetInt(const std::string &name, int default_val) const {
const auto it = options_.find(name);
- if (it == options_.end())
+ if (it == options_.end()) {
return default_val;
+ }
return std::atoi(it->second.c_str());
}
@@ -58,8 +60,9 @@ float Options::GetFloat(const std::string &name) const {
float Options::GetFloat(const std::string &name, float default_val) const {
const auto it = options_.find(name);
- if (it == options_.end())
+ if (it == options_.end()) {
return default_val;
+ }
return static_cast<float>(std::atof(it->second.c_str()));
}
@@ -69,8 +72,9 @@ bool Options::GetBool(const std::string &name) const {
bool Options::GetBool(const std::string &name, bool default_val) const {
const int ret = GetInt(name, -1);
- if (ret == -1)
+ if (ret == -1) {
return default_val;
+ }
return static_cast<bool>(ret);
}
@@ -81,8 +85,9 @@ std::string Options::GetString(const std::string &name) const {
std::string Options::GetString(const std::string &name,
const std::string &default_val) const {
const auto it = options_.find(name);
- if (it == options_.end())
+ if (it == options_.end()) {
return default_val;
+ }
return it->second;
}
diff --git a/extern/draco/dracoenc/src/draco/core/options.h b/extern/draco/draco/src/draco/core/options.h
index 4995299633c..1bc4dc0fb7b 100644
--- a/extern/draco/dracoenc/src/draco/core/options.h
+++ b/extern/draco/draco/src/draco/core/options.h
@@ -81,8 +81,9 @@ void Options::SetVector(const std::string &name, const DataTypeT *vec,
int num_dims) {
std::string out;
for (int i = 0; i < num_dims; ++i) {
- if (i > 0)
+ if (i > 0) {
out += " ";
+ }
// GNU STL on android doesn't include a proper std::to_string, but the libc++
// version does
@@ -107,11 +108,13 @@ template <typename DataTypeT>
bool Options::GetVector(const std::string &name, int num_dims,
DataTypeT *out_val) const {
const auto it = options_.find(name);
- if (it == options_.end())
+ if (it == options_.end()) {
return false;
+ }
const std::string value = it->second;
- if (value.length() == 0)
+ if (value.length() == 0) {
return true; // Option set but no data is present
+ }
const char *act_str = value.c_str();
char *next_str;
for (int i = 0; i < num_dims; ++i) {
@@ -119,10 +122,11 @@ bool Options::GetVector(const std::string &name, int num_dims,
#ifdef ANDROID
const int val = strtol(act_str, &next_str, 10);
#else
- const int val = std::strtol(act_str, &next_str, 10);
+ const int val = static_cast<int>(std::strtol(act_str, &next_str, 10));
#endif
- if (act_str == next_str)
+ if (act_str == next_str) {
return true; // End reached.
+ }
act_str = next_str;
out_val[i] = static_cast<DataTypeT>(val);
} else {
@@ -131,8 +135,9 @@ bool Options::GetVector(const std::string &name, int num_dims,
#else
const float val = std::strtof(act_str, &next_str);
#endif
- if (act_str == next_str)
+ if (act_str == next_str) {
return true; // End reached.
+ }
act_str = next_str;
out_val[i] = static_cast<DataTypeT>(val);
}
diff --git a/extern/draco/dracoenc/src/draco/core/quantization_utils.cc b/extern/draco/draco/src/draco/core/quantization_utils.cc
index 26417b01998..58dcf5c8c20 100644
--- a/extern/draco/dracoenc/src/draco/core/quantization_utils.cc
+++ b/extern/draco/draco/src/draco/core/quantization_utils.cc
@@ -27,8 +27,9 @@ void Quantizer::Init(float delta) { inverse_delta_ = 1.f / delta; }
Dequantizer::Dequantizer() : delta_(1.f) {}
bool Dequantizer::Init(float range, int32_t max_quantized_value) {
- if (max_quantized_value <= 0)
+ if (max_quantized_value <= 0) {
return false;
+ }
delta_ = range / static_cast<float>(max_quantized_value);
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/core/quantization_utils.h b/extern/draco/draco/src/draco/core/quantization_utils.h
index 54910467407..0f60f1e1b17 100644
--- a/extern/draco/dracoenc/src/draco/core/quantization_utils.h
+++ b/extern/draco/draco/src/draco/core/quantization_utils.h
@@ -22,6 +22,7 @@
#define DRACO_CORE_QUANTIZATION_UTILS_H_
#include <stdint.h>
+
#include <cmath>
#include "draco/core/macros.h"
diff --git a/extern/draco/dracoenc/src/draco/core/status.h b/extern/draco/draco/src/draco/core/status.h
index 9ac3def7cd1..449ad8566de 100644
--- a/extern/draco/dracoenc/src/draco/core/status.h
+++ b/extern/draco/draco/src/draco/core/status.h
@@ -31,6 +31,7 @@ class Status {
UNSUPPORTED_VERSION = -4, // Input not compatible with the current version.
UNKNOWN_VERSION = -5, // Input was created with an unknown version of
// the library.
+ UNSUPPORTED_FEATURE = -6, // Input contains feature that is not supported.
};
Status() : code_(OK) {}
@@ -66,8 +67,9 @@ inline Status OkStatus() { return Status(Status::OK); }
#define DRACO_RETURN_IF_ERROR(expression) \
{ \
const draco::Status _local_status = (expression); \
- if (!_local_status.ok()) \
+ if (!_local_status.ok()) { \
return _local_status; \
+ } \
}
} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/core/status_or.h b/extern/draco/draco/src/draco/core/status_or.h
index 156b9bc02a7..156b9bc02a7 100644
--- a/extern/draco/dracoenc/src/draco/core/status_or.h
+++ b/extern/draco/draco/src/draco/core/status_or.h
diff --git a/extern/draco/dracoenc/src/draco/core/varint_decoding.h b/extern/draco/draco/src/draco/core/varint_decoding.h
index 6cd41b29220..4e86df732e0 100644
--- a/extern/draco/dracoenc/src/draco/core/varint_decoding.h
+++ b/extern/draco/draco/src/draco/core/varint_decoding.h
@@ -22,33 +22,54 @@
namespace draco {
+namespace {
+
+// Decodes a specified unsigned integer as varint. |depth| is the current
+// recursion call depth. The first call to the function must be 1.
+template <typename IntTypeT>
+bool DecodeVarintUnsigned(int depth, IntTypeT *out_val, DecoderBuffer *buffer) {
+ constexpr IntTypeT max_depth = sizeof(IntTypeT) + 1 + (sizeof(IntTypeT) >> 3);
+ if (depth > max_depth) {
+ return false;
+ }
+ // Coding of unsigned values.
+ // 0-6 bit - data
+ // 7 bit - next byte?
+ uint8_t in;
+ if (!buffer->Decode(&in)) {
+ return false;
+ }
+ if (in & (1 << 7)) {
+ // Next byte is available, decode it first.
+ if (!DecodeVarintUnsigned<IntTypeT>(depth + 1, out_val, buffer)) {
+ return false;
+ }
+ // Append decoded info from this byte.
+ *out_val <<= 7;
+ *out_val |= in & ((1 << 7) - 1);
+ } else {
+ // Last byte reached
+ *out_val = in;
+ }
+ return true;
+}
+
+} // namespace
+
// Decodes a specified integer as varint. Note that the IntTypeT must be the
// same as the one used in the corresponding EncodeVarint() call.
template <typename IntTypeT>
bool DecodeVarint(IntTypeT *out_val, DecoderBuffer *buffer) {
if (std::is_unsigned<IntTypeT>::value) {
- // Coding of unsigned values.
- // 0-6 bit - data
- // 7 bit - next byte?
- uint8_t in;
- if (!buffer->Decode(&in))
+ if (!DecodeVarintUnsigned<IntTypeT>(1, out_val, buffer)) {
return false;
- if (in & (1 << 7)) {
- // Next byte is available, decode it first.
- if (!DecodeVarint<IntTypeT>(out_val, buffer))
- return false;
- // Append decoded info from this byte.
- *out_val <<= 7;
- *out_val |= in & ((1 << 7) - 1);
- } else {
- // Last byte reached
- *out_val = in;
}
} else {
// IntTypeT is a signed value. Decode the symbol and convert to signed.
typename std::make_unsigned<IntTypeT>::type symbol;
- if (!DecodeVarint(&symbol, buffer))
+ if (!DecodeVarintUnsigned(1, &symbol, buffer)) {
return false;
+ }
*out_val = ConvertSymbolToSignedInt(symbol);
}
return true;
diff --git a/extern/draco/dracoenc/src/draco/core/varint_encoding.h b/extern/draco/draco/src/draco/core/varint_encoding.h
index b9b6dcab78d..9a8a5393698 100644
--- a/extern/draco/dracoenc/src/draco/core/varint_encoding.h
+++ b/extern/draco/draco/src/draco/core/varint_encoding.h
@@ -34,20 +34,24 @@ bool EncodeVarint(IntTypeT val, EncoderBuffer *out_buffer) {
out |= val & ((1 << 7) - 1);
if (val >= (1 << 7)) {
out |= (1 << 7);
- if (!out_buffer->Encode(out))
+ if (!out_buffer->Encode(out)) {
return false;
- if (!EncodeVarint<IntTypeT>(val >> 7, out_buffer))
+ }
+ if (!EncodeVarint<IntTypeT>(val >> 7, out_buffer)) {
return false;
+ }
return true;
}
- if (!out_buffer->Encode(out))
+ if (!out_buffer->Encode(out)) {
return false;
+ }
} else {
// IntTypeT is a signed value. Convert to unsigned symbol and encode.
const typename std::make_unsigned<IntTypeT>::type symbol =
ConvertSignedIntToSymbol(val);
- if (!EncodeVarint(symbol, out_buffer))
+ if (!EncodeVarint(symbol, out_buffer)) {
return false;
+ }
}
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/core/vector_d.h b/extern/draco/draco/src/draco/core/vector_d.h
index 189517f3928..bed97304feb 100644
--- a/extern/draco/dracoenc/src/draco/core/vector_d.h
+++ b/extern/draco/draco/src/draco/core/vector_d.h
@@ -16,6 +16,7 @@
#define DRACO_CORE_VECTOR_D_H_
#include <inttypes.h>
+
#include <algorithm>
#include <array>
#include <cmath>
@@ -36,8 +37,9 @@ class VectorD {
typedef ScalarT CoefficientType;
VectorD() {
- for (int i = 0; i < dimension; ++i)
+ for (int i = 0; i < dimension; ++i) {
(*this)[i] = Scalar(0);
+ }
}
// The following constructor does not compile in opt mode, which for now led
@@ -83,8 +85,9 @@ class VectorD {
}
VectorD(const Self &o) {
- for (int i = 0; i < dimension; ++i)
+ for (int i = 0; i < dimension; ++i) {
(*this)[i] = o[i];
+ }
}
// Constructs the vector from another vector with a different data type or a
@@ -97,10 +100,11 @@ class VectorD {
template <class OtherScalarT, int other_dimension_t>
explicit VectorD(const VectorD<OtherScalarT, other_dimension_t> &src_vector) {
for (int i = 0; i < dimension; ++i) {
- if (i < other_dimension_t)
+ if (i < other_dimension_t) {
v_[i] = Scalar(src_vector[i]);
- else
+ } else {
v_[i] = Scalar(0);
+ }
}
}
@@ -137,6 +141,35 @@ class VectorD {
return ret;
}
+ Self operator*(const Self &o) const {
+ Self ret;
+ for (int i = 0; i < dimension; ++i) {
+ ret[i] = (*this)[i] * o[i];
+ }
+ return ret;
+ }
+
+ Self &operator+=(const Self &o) {
+ for (int i = 0; i < dimension; ++i) {
+ (*this)[i] += o[i];
+ }
+ return *this;
+ }
+
+ Self &operator-=(const Self &o) {
+ for (int i = 0; i < dimension; ++i) {
+ (*this)[i] -= o[i];
+ }
+ return *this;
+ }
+
+ Self &operator*=(const Self &o) {
+ for (int i = 0; i < dimension; ++i) {
+ (*this)[i] *= o[i];
+ }
+ return *this;
+ }
+
Self operator*(const Scalar &o) const {
Self ret;
for (int i = 0; i < dimension; ++i) {
@@ -171,8 +204,9 @@ class VectorD {
bool operator==(const Self &o) const {
for (int i = 0; i < dimension; ++i) {
- if ((*this)[i] != o[i])
+ if ((*this)[i] != o[i]) {
return false;
+ }
}
return true;
}
@@ -181,14 +215,17 @@ class VectorD {
bool operator<(const Self &x) const {
for (int i = 0; i < dimension - 1; ++i) {
- if (v_[i] < x.v_[i])
+ if (v_[i] < x.v_[i]) {
return true;
- if (v_[i] > x.v_[i])
+ }
+ if (v_[i] > x.v_[i]) {
return false;
+ }
}
// Only one check needed for the last dimension.
- if (v_[dimension - 1] < x.v_[dimension - 1])
+ if (v_[dimension - 1] < x.v_[dimension - 1]) {
return true;
+ }
return false;
}
@@ -222,6 +259,12 @@ class VectorD {
}
}
+ Self GetNormalized() const {
+ Self ret(*this);
+ ret.Normalize();
+ return ret;
+ }
+
const Scalar &MaxCoeff() const {
return *std::max_element(v_.begin(), v_.end());
}
@@ -231,6 +274,7 @@ class VectorD {
}
Scalar *data() { return &(v_[0]); }
+ const Scalar *data() const { return &(v_[0]); }
private:
std::array<Scalar, dimension> v_;
diff --git a/extern/draco/draco/src/draco/draco_features.h b/extern/draco/draco/src/draco/draco_features.h
new file mode 100644
index 00000000000..27e3d7f136a
--- /dev/null
+++ b/extern/draco/draco/src/draco/draco_features.h
@@ -0,0 +1,10 @@
+#ifndef DRACO_FEATURES_H_
+#define DRACO_FEATURES_H_
+
+#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/dracoenc/src/draco/mesh/corner_table.cc b/extern/draco/draco/src/draco/mesh/corner_table.cc
index dcfd7967c0b..6066e58bd8b 100644
--- a/extern/draco/dracoenc/src/draco/mesh/corner_table.cc
+++ b/extern/draco/draco/src/draco/mesh/corner_table.cc
@@ -30,8 +30,9 @@ CornerTable::CornerTable()
std::unique_ptr<CornerTable> CornerTable::Create(
const IndexTypeVector<FaceIndex, FaceType> &faces) {
std::unique_ptr<CornerTable> ct(new CornerTable());
- if (!ct->Init(faces))
+ if (!ct->Init(faces)) {
return nullptr;
+ }
return ct;
}
@@ -45,12 +46,15 @@ bool CornerTable::Init(const IndexTypeVector<FaceIndex, FaceType> &faces) {
}
}
int num_vertices = -1;
- if (!ComputeOppositeCorners(&num_vertices))
+ if (!ComputeOppositeCorners(&num_vertices)) {
return false;
- if (!BreakNonManifoldEdges())
+ }
+ if (!BreakNonManifoldEdges()) {
return false;
- if (!ComputeVertexCorners(num_vertices))
+ }
+ if (!ComputeVertexCorners(num_vertices)) {
return false;
+ }
return true;
}
@@ -59,11 +63,13 @@ bool CornerTable::Reset(int num_faces) {
}
bool CornerTable::Reset(int num_faces, int num_vertices) {
- if (num_faces < 0 || num_vertices < 0)
+ if (num_faces < 0 || num_vertices < 0) {
return false;
+ }
if (static_cast<unsigned int>(num_faces) >
- std::numeric_limits<CornerIndex::ValueType>::max() / 3)
+ 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);
vertex_corners_.reserve(num_vertices);
@@ -74,8 +80,9 @@ bool CornerTable::Reset(int num_faces, int num_vertices) {
bool CornerTable::ComputeOppositeCorners(int *num_vertices) {
DRACO_DCHECK(GetValenceCache().IsCacheEmpty());
- if (num_vertices == nullptr)
+ if (num_vertices == nullptr) {
return false;
+ }
opposite_corners_.resize(num_corners(), kInvalidCornerIndex);
// Out implementation for finding opposite corners is based on keeping track
@@ -92,8 +99,9 @@ bool CornerTable::ComputeOppositeCorners(int *num_vertices) {
num_corners_on_vertices.reserve(num_corners());
for (CornerIndex c(0); c < num_corners(); ++c) {
const VertexIndex v1 = Vertex(c);
- if (v1.value() >= static_cast<int>(num_corners_on_vertices.size()))
+ if (v1.value() >= static_cast<int>(num_corners_on_vertices.size())) {
num_corners_on_vertices.resize(v1.value() + 1, 0);
+ }
// For each corner there is always exactly one outgoing half-edge attached
// to its vertex.
num_corners_on_vertices[v1.value()]++;
@@ -150,11 +158,13 @@ bool CornerTable::ComputeOppositeCorners(int *num_vertices) {
offset = vertex_offset[sink_v.value()];
for (int i = 0; i < num_corners_on_vert; ++i, ++offset) {
const VertexIndex other_v = vertex_edges[offset].sink_vert;
- if (other_v == kInvalidVertexIndex)
+ if (other_v == kInvalidVertexIndex) {
break; // No matching half-edge found on the sink vertex.
+ }
if (other_v == source_v) {
- if (tip_v == Vertex(vertex_edges[offset].edge_corner))
+ if (tip_v == Vertex(vertex_edges[offset].edge_corner)) {
continue; // Don't connect mirrored faces.
+ }
// A matching half-edge was found on the sink vertex. Mark the
// half-edge's opposite corner.
opposite_c = vertex_edges[offset].edge_corner;
@@ -165,8 +175,9 @@ bool CornerTable::ComputeOppositeCorners(int *num_vertices) {
// slot.
for (int j = i + 1; j < num_corners_on_vert; ++j, ++offset) {
vertex_edges[offset] = vertex_edges[offset + 1];
- if (vertex_edges[offset].sink_vert == kInvalidVertexIndex)
+ if (vertex_edges[offset].sink_vert == kInvalidVertexIndex) {
break; // Unused half-edge reached.
+ }
}
// Mark the last entry as unused.
vertex_edges[offset].sink_vert = kInvalidVertexIndex;
@@ -217,8 +228,9 @@ bool CornerTable::BreakNonManifoldEdges() {
do {
mesh_connectivity_updated = false;
for (CornerIndex c(0); c < num_corners(); ++c) {
- if (visited_corners[c.value()])
+ if (visited_corners[c.value()]) {
continue;
+ }
sink_vertices.clear();
// First swing all the way to find the left-most corner connected to the
@@ -267,10 +279,12 @@ bool CornerTable::BreakNonManifoldEdges() {
// that the final surface would be manifold.
const CornerIndex opp_other_edge_corner =
Opposite(other_edge_corner);
- if (opp_edge_corner != kInvalidCornerIndex)
+ if (opp_edge_corner != kInvalidCornerIndex) {
SetOppositeCorner(opp_edge_corner, kInvalidCornerIndex);
- if (opp_other_edge_corner != kInvalidCornerIndex)
+ }
+ if (opp_other_edge_corner != kInvalidCornerIndex) {
SetOppositeCorner(opp_other_edge_corner, kInvalidCornerIndex);
+ }
SetOppositeCorner(edge_corner, kInvalidCornerIndex);
SetOppositeCorner(other_edge_corner, kInvalidCornerIndex);
@@ -312,13 +326,15 @@ bool CornerTable::ComputeVertexCorners(int num_vertices) {
for (FaceIndex f(0); f < num_faces(); ++f) {
const CornerIndex first_face_corner = FirstCorner(f);
// Check whether the face is degenerated. If so ignore it.
- if (IsDegenerated(f))
+ if (IsDegenerated(f)) {
continue;
+ }
for (int k = 0; k < 3; ++k) {
const CornerIndex c = first_face_corner + k;
- if (visited_corners[c.value()])
+ if (visited_corners[c.value()]) {
continue;
+ }
VertexIndex v = corner_to_vertex_map_[c];
// Note that one vertex maps to many corners, but we just keep track
// of the vertex which has a boundary on the left if the vertex lies on
@@ -350,8 +366,9 @@ bool CornerTable::ComputeVertexCorners(int num_vertices) {
corner_to_vertex_map_[act_c] = v;
}
act_c = SwingLeft(act_c);
- if (act_c == c)
+ if (act_c == c) {
break; // Full circle reached.
+ }
}
if (act_c == kInvalidCornerIndex) {
// If we have reached an open boundary we need to swing right from the
@@ -372,27 +389,31 @@ bool CornerTable::ComputeVertexCorners(int num_vertices) {
// Count the number of isolated (unprocessed) vertices.
num_isolated_vertices_ = 0;
for (bool visited : visited_vertices) {
- if (!visited)
+ if (!visited) {
++num_isolated_vertices_;
+ }
}
return true;
}
bool CornerTable::IsDegenerated(FaceIndex face) const {
- if (face == kInvalidFaceIndex)
+ if (face == kInvalidFaceIndex) {
return true;
+ }
const CornerIndex first_face_corner = FirstCorner(face);
const VertexIndex v0 = Vertex(first_face_corner);
const VertexIndex v1 = Vertex(Next(first_face_corner));
const VertexIndex v2 = Vertex(Previous(first_face_corner));
- if (v0 == v1 || v0 == v2 || v1 == v2)
+ if (v0 == v1 || v0 == v2 || v1 == v2) {
return true;
+ }
return false;
}
int CornerTable::Valence(VertexIndex v) const {
- if (v == kInvalidVertexIndex)
+ if (v == kInvalidVertexIndex) {
return -1;
+ }
return ConfidentValence(v);
}
diff --git a/extern/draco/dracoenc/src/draco/mesh/corner_table.h b/extern/draco/draco/src/draco/mesh/corner_table.h
index 704a7b1b5c4..3aa720fdeb9 100644
--- a/extern/draco/dracoenc/src/draco/mesh/corner_table.h
+++ b/extern/draco/draco/src/draco/mesh/corner_table.h
@@ -80,23 +80,27 @@ class CornerTable {
}
inline CornerIndex Opposite(CornerIndex corner) const {
- if (corner == kInvalidCornerIndex)
+ if (corner == kInvalidCornerIndex) {
return corner;
+ }
return opposite_corners_[corner];
}
inline CornerIndex Next(CornerIndex corner) const {
- if (corner == kInvalidCornerIndex)
+ if (corner == kInvalidCornerIndex) {
return corner;
+ }
return LocalIndex(++corner) ? corner : corner - 3;
}
inline CornerIndex Previous(CornerIndex corner) const {
- if (corner == kInvalidCornerIndex)
+ if (corner == kInvalidCornerIndex) {
return corner;
+ }
return LocalIndex(corner) ? corner - 1 : corner + 2;
}
inline VertexIndex Vertex(CornerIndex corner) const {
- if (corner == kInvalidCornerIndex)
+ if (corner == kInvalidCornerIndex) {
return kInvalidVertexIndex;
+ }
return ConfidentVertex(corner);
}
inline VertexIndex ConfidentVertex(CornerIndex corner) const {
@@ -105,13 +109,15 @@ class CornerTable {
return corner_to_vertex_map_[corner];
}
inline FaceIndex Face(CornerIndex corner) const {
- if (corner == kInvalidCornerIndex)
+ if (corner == kInvalidCornerIndex) {
return kInvalidFaceIndex;
+ }
return FaceIndex(corner.value() / 3);
}
inline CornerIndex FirstCorner(FaceIndex face) const {
- if (face == kInvalidFaceIndex)
+ if (face == kInvalidFaceIndex) {
return kInvalidCornerIndex;
+ }
return CornerIndex(face.value() * 3);
}
inline std::array<CornerIndex, 3> AllCorners(FaceIndex face) const {
@@ -146,8 +152,9 @@ class CornerTable {
// Returns the parent vertex index of a given corner table vertex.
VertexIndex VertexParent(VertexIndex vertex) const {
- if (vertex.value() < static_cast<uint32_t>(num_original_vertices_))
+ if (vertex.value() < static_cast<uint32_t>(num_original_vertices_)) {
return vertex;
+ }
return non_manifold_vertex_parents_[vertex - num_original_vertices_];
}
@@ -163,8 +170,9 @@ class CornerTable {
int ConfidentValence(VertexIndex v) const;
// Returns the valence of the vertex at the given corner.
inline int Valence(CornerIndex c) const {
- if (c == kInvalidCornerIndex)
+ if (c == kInvalidCornerIndex) {
return -1;
+ }
return ConfidentValence(c);
}
inline int ConfidentValence(CornerIndex c) const {
@@ -175,8 +183,9 @@ class CornerTable {
// Returns true if the specified vertex is on a boundary.
inline bool IsOnBoundary(VertexIndex vert) const {
const CornerIndex corner = LeftMostCorner(vert);
- if (SwingLeft(corner) == kInvalidCornerIndex)
+ if (SwingLeft(corner) == kInvalidCornerIndex) {
return true;
+ }
return false;
}
@@ -205,13 +214,15 @@ class CornerTable {
// \ / \ /
// *-------*
inline CornerIndex GetLeftCorner(CornerIndex corner_id) const {
- if (corner_id == kInvalidCornerIndex)
+ if (corner_id == kInvalidCornerIndex) {
return kInvalidCornerIndex;
+ }
return Opposite(Previous(corner_id));
}
inline CornerIndex GetRightCorner(CornerIndex corner_id) const {
- if (corner_id == kInvalidCornerIndex)
+ if (corner_id == kInvalidCornerIndex) {
return kInvalidCornerIndex;
+ }
return Opposite(Next(corner_id));
}
@@ -241,10 +252,12 @@ class CornerTable {
// Sets opposite corners for both input corners.
inline void SetOppositeCorners(CornerIndex corner_0, CornerIndex corner_1) {
DRACO_DCHECK(GetValenceCache().IsCacheEmpty());
- if (corner_0 != kInvalidCornerIndex)
+ if (corner_0 != kInvalidCornerIndex) {
SetOppositeCorner(corner_0, corner_1);
- if (corner_1 != kInvalidCornerIndex)
+ }
+ if (corner_1 != kInvalidCornerIndex) {
SetOppositeCorner(corner_1, corner_0);
+ }
}
// Updates mapping between a corner and a vertex.
@@ -260,11 +273,26 @@ class CornerTable {
return VertexIndex(static_cast<uint32_t>(vertex_corners_.size() - 1));
}
+ // Adds a new face connected to three vertices. Note that connectivity is not
+ // automatically updated and all opposite corners need to be set explicitly.
+ FaceIndex AddNewFace(const std::array<VertexIndex, 3> &vertices) {
+ // Add a new invalid face.
+ const FaceIndex new_face_index(num_faces());
+ for (int i = 0; i < 3; ++i) {
+ corner_to_vertex_map_.push_back(vertices[i]);
+ SetLeftMostCorner(vertices[i],
+ CornerIndex(corner_to_vertex_map_.size() - 1));
+ }
+ opposite_corners_.resize(corner_to_vertex_map_.size(), kInvalidCornerIndex);
+ return new_face_index;
+ }
+
// Sets a new left most corner for a given vertex.
void SetLeftMostCorner(VertexIndex vert, CornerIndex corner) {
DRACO_DCHECK(GetValenceCache().IsCacheEmpty());
- if (vert != kInvalidVertexIndex)
+ if (vert != kInvalidVertexIndex) {
vertex_corners_[vert] = corner;
+ }
}
// Updates the vertex to corner map on a specified vertex. This should be
@@ -273,8 +301,9 @@ class CornerTable {
void UpdateVertexToCornerMap(VertexIndex vert) {
DRACO_DCHECK(GetValenceCache().IsCacheEmpty());
const CornerIndex first_c = vertex_corners_[vert];
- if (first_c == kInvalidCornerIndex)
+ if (first_c == kInvalidCornerIndex) {
return; // Isolated vertex.
+ }
CornerIndex act_c = SwingLeft(first_c);
CornerIndex c = first_c;
while (act_c != kInvalidCornerIndex && act_c != first_c) {
diff --git a/extern/draco/dracoenc/src/draco/mesh/corner_table_iterators.h b/extern/draco/draco/src/draco/mesh/corner_table_iterators.h
index 65869dbe109..7122aa1be0f 100644
--- a/extern/draco/dracoenc/src/draco/mesh/corner_table_iterators.h
+++ b/extern/draco/draco/src/draco/mesh/corner_table_iterators.h
@@ -45,6 +45,13 @@ class VertexRingIterator
return corner_table_->Vertex(ring_corner);
}
+ // Returns one of the corners opposite to the edge connecting the currently
+ // iterated ring vertex with the central vertex.
+ CornerIndex EdgeCorner() const {
+ return left_traversal_ ? corner_table_->Next(corner_)
+ : corner_table_->Previous(corner_);
+ }
+
// Returns true when all ring vertices have been visited.
bool End() const { return corner_ == kInvalidCornerIndex; }
@@ -120,8 +127,9 @@ class FaceAdjacencyIterator
corner_(start_corner_) {
// We need to start with a corner that has a valid opposite face (if
// there is any such corner).
- if (corner_table_->Opposite(corner_) == kInvalidCornerIndex)
+ if (corner_table_->Opposite(corner_) == kInvalidCornerIndex) {
FindNextFaceNeighbor();
+ }
}
// Gets the last visited adjacent face.
diff --git a/extern/draco/dracoenc/src/draco/mesh/mesh.cc b/extern/draco/draco/src/draco/mesh/mesh.cc
index a78a6ec96a8..3be4b1494ec 100644
--- a/extern/draco/dracoenc/src/draco/mesh/mesh.cc
+++ b/extern/draco/draco/src/draco/mesh/mesh.cc
@@ -15,12 +15,9 @@
#include "draco/mesh/mesh.h"
#include <array>
-#include <unordered_map>
namespace draco {
-using std::unordered_map;
-
// Shortcut for typed conditionals.
template <bool B, class T, class F>
using conditional_t = typename std::conditional<B, T, F>::type;
diff --git a/extern/draco/dracoenc/src/draco/mesh/mesh.h b/extern/draco/draco/src/draco/mesh/mesh.h
index b8ca5353a81..f4506da81c9 100644
--- a/extern/draco/dracoenc/src/draco/mesh/mesh.h
+++ b/extern/draco/draco/src/draco/mesh/mesh.h
@@ -93,8 +93,9 @@ class Mesh : public PointCloud {
// Returns the point id of for a corner |ci|.
inline PointIndex CornerToPointId(int ci) const {
- if (ci == kInvalidCornerIndex.value())
+ if (ci < 0 || static_cast<uint32_t>(ci) == kInvalidCornerIndex.value()) {
return kInvalidPointIndex;
+ }
return this->face(FaceIndex(ci / 3))[ci % 3];
}
diff --git a/extern/draco/dracoenc/src/draco/mesh/mesh_are_equivalent.cc b/extern/draco/draco/src/draco/mesh/mesh_are_equivalent.cc
index deb68940a54..b832379afe4 100644
--- a/extern/draco/dracoenc/src/draco/mesh/mesh_are_equivalent.cc
+++ b/extern/draco/draco/src/draco/mesh/mesh_are_equivalent.cc
@@ -101,10 +101,12 @@ void MeshAreEquivalent::Init(const Mesh &mesh0, const Mesh &mesh1) {
}
bool MeshAreEquivalent::operator()(const Mesh &mesh0, const Mesh &mesh1) {
- if (mesh0.num_faces() != mesh1.num_faces())
+ if (mesh0.num_faces() != mesh1.num_faces()) {
return false;
- if (mesh0.num_attributes() != mesh1.num_attributes())
+ }
+ if (mesh0.num_attributes() != mesh1.num_attributes()) {
return false;
+ }
// The following function inits mesh info, i.e., computes the order of
// faces with respect to the lex order. This way one can then compare the
@@ -121,20 +123,27 @@ bool MeshAreEquivalent::operator()(const Mesh &mesh0, const Mesh &mesh1) {
mesh0.GetNamedAttribute(AttributeType(att_id));
const PointAttribute *const att1 =
mesh1.GetNamedAttribute(AttributeType(att_id));
- if (att0 == nullptr && att1 == nullptr)
+ if (att0 == nullptr && att1 == nullptr) {
continue;
- if (att0 == nullptr)
+ }
+ if (att0 == nullptr) {
return false;
- if (att1 == nullptr)
+ }
+ if (att1 == nullptr) {
return false;
- if (att0->data_type() != att1->data_type())
+ }
+ if (att0->data_type() != att1->data_type()) {
return false;
- if (att0->num_components() != att1->num_components())
+ }
+ if (att0->num_components() != att1->num_components()) {
return false;
- if (att0->normalized() != att1->normalized())
+ }
+ if (att0->normalized() != att1->normalized()) {
return false;
- if (att0->byte_stride() != att1->byte_stride())
+ }
+ if (att0->byte_stride() != att1->byte_stride()) {
return false;
+ }
DRACO_DCHECK(att0->IsValid());
DRACO_DCHECK(att1->IsValid());
@@ -162,8 +171,9 @@ bool MeshAreEquivalent::operator()(const Mesh &mesh0, const Mesh &mesh1) {
att0->GetValue(index0, data0.get());
att1->GetValue(index1, data1.get());
// Compare the data as is in memory.
- if (memcmp(data0.get(), data1.get(), att0->byte_stride()) != 0)
+ if (memcmp(data0.get(), data1.get(), att0->byte_stride()) != 0) {
return false;
+ }
}
}
}
@@ -172,18 +182,21 @@ bool MeshAreEquivalent::operator()(const Mesh &mesh0, const Mesh &mesh1) {
bool MeshAreEquivalent::FaceIndexLess::operator()(FaceIndex f0,
FaceIndex f1) const {
- if (f0 == f1)
+ if (f0 == f1) {
return false;
+ }
const int c0 = mesh_info.corner_index_of_smallest_vertex[f0];
const int c1 = mesh_info.corner_index_of_smallest_vertex[f1];
for (int i = 0; i < 3; ++i) {
const Vector3f vf0 = GetPosition(mesh_info.mesh, f0, (c0 + i) % 3);
const Vector3f vf1 = GetPosition(mesh_info.mesh, f1, (c1 + i) % 3);
- if (vf0 < vf1)
+ if (vf0 < vf1) {
return true;
- if (vf1 < vf0)
+ }
+ if (vf1 < vf0) {
return false;
+ }
}
// In case the two faces are equivalent.
return false;
diff --git a/extern/draco/dracoenc/src/draco/mesh/mesh_are_equivalent.h b/extern/draco/draco/src/draco/mesh/mesh_are_equivalent.h
index 71ef4a93c12..71ef4a93c12 100644
--- a/extern/draco/dracoenc/src/draco/mesh/mesh_are_equivalent.h
+++ b/extern/draco/draco/src/draco/mesh/mesh_are_equivalent.h
diff --git a/extern/draco/dracoenc/src/draco/mesh/mesh_attribute_corner_table.cc b/extern/draco/draco/src/draco/mesh/mesh_attribute_corner_table.cc
index 768d5f5e28e..28b68d5fd40 100644
--- a/extern/draco/dracoenc/src/draco/mesh/mesh_attribute_corner_table.cc
+++ b/extern/draco/draco/src/draco/mesh/mesh_attribute_corner_table.cc
@@ -13,6 +13,7 @@
// limitations under the License.
//
#include "draco/mesh/mesh_attribute_corner_table.h"
+
#include "draco/mesh/corner_table_iterators.h"
#include "draco/mesh/mesh_misc_functions.h"
@@ -22,8 +23,9 @@ MeshAttributeCornerTable::MeshAttributeCornerTable()
: no_interior_seams_(true), corner_table_(nullptr), valence_cache_(*this) {}
bool MeshAttributeCornerTable::InitEmpty(const CornerTable *table) {
- if (table == nullptr)
+ if (table == nullptr) {
return false;
+ }
valence_cache_.ClearValenceCache();
valence_cache_.ClearValenceCacheInaccurate();
is_edge_on_seam_.assign(table->num_corners(), false);
@@ -39,8 +41,9 @@ bool MeshAttributeCornerTable::InitEmpty(const CornerTable *table) {
bool MeshAttributeCornerTable::InitFromAttribute(const Mesh *mesh,
const CornerTable *table,
const PointAttribute *att) {
- if (!InitEmpty(table))
+ if (!InitEmpty(table)) {
return false;
+ }
valence_cache_.ClearValenceCache();
valence_cache_.ClearValenceCacheInaccurate();
@@ -49,8 +52,9 @@ bool MeshAttributeCornerTable::InitFromAttribute(const Mesh *mesh,
// special handling.
for (CornerIndex c(0); c < corner_table_->num_corners(); ++c) {
const FaceIndex f = corner_table_->Face(c);
- if (corner_table_->IsDegenerated(f))
+ if (corner_table_->IsDegenerated(f)) {
continue; // Ignore corners on degenerated faces.
+ }
const CornerIndex opp_corner = corner_table_->Opposite(c);
if (opp_corner == kInvalidCornerIndex) {
// Boundary. Mark it as seam edge.
@@ -63,8 +67,9 @@ bool MeshAttributeCornerTable::InitFromAttribute(const Mesh *mesh,
is_vertex_on_seam_[v.value()] = true;
continue;
}
- if (opp_corner < c)
+ if (opp_corner < c) {
continue; // Opposite corner was already processed.
+ }
CornerIndex act_c(c), act_sibling_c(opp_corner);
for (int i = 0; i < 2; ++i) {
@@ -135,11 +140,14 @@ template <bool init_vertex_to_attribute_entry_map>
void MeshAttributeCornerTable::RecomputeVerticesInternal(
const Mesh *mesh, const PointAttribute *att) {
DRACO_DCHECK(GetValenceCache().IsCacheEmpty());
+ vertex_to_attribute_entry_id_map_.clear();
+ vertex_to_left_most_corner_map_.clear();
int num_new_vertices = 0;
for (VertexIndex v(0); v < corner_table_->num_vertices(); ++v) {
const CornerIndex c = corner_table_->LeftMostCorner(v);
- if (c == kInvalidCornerIndex)
+ if (c == kInvalidCornerIndex) {
continue; // Isolated vertex?
+ }
AttributeValueIndex first_vert_id(num_new_vertices++);
if (init_vertex_to_attribute_entry_map) {
const PointIndex point_id = mesh->CornerToPointId(c.value());
@@ -184,8 +192,9 @@ void MeshAttributeCornerTable::RecomputeVerticesInternal(
}
int MeshAttributeCornerTable::Valence(VertexIndex v) const {
- if (v == kInvalidVertexIndex)
+ if (v == kInvalidVertexIndex) {
return -1;
+ }
return ConfidentValence(v);
}
diff --git a/extern/draco/dracoenc/src/draco/mesh/mesh_attribute_corner_table.h b/extern/draco/draco/src/draco/mesh/mesh_attribute_corner_table.h
index b9e938f5b7d..7dad25cf1d2 100644
--- a/extern/draco/dracoenc/src/draco/mesh/mesh_attribute_corner_table.h
+++ b/extern/draco/draco/src/draco/mesh/mesh_attribute_corner_table.h
@@ -47,8 +47,9 @@ class MeshAttributeCornerTable {
}
inline CornerIndex Opposite(CornerIndex corner) const {
- if (corner == kInvalidCornerIndex || IsCornerOppositeToSeamEdge(corner))
+ if (corner == kInvalidCornerIndex || IsCornerOppositeToSeamEdge(corner)) {
return kInvalidCornerIndex;
+ }
return corner_table_->Opposite(corner);
}
@@ -88,6 +89,7 @@ class MeshAttributeCornerTable {
return static_cast<int>(vertex_to_attribute_entry_id_map_.size());
}
int num_faces() const { return static_cast<int>(corner_table_->num_faces()); }
+ int num_corners() const { return corner_table_->num_corners(); }
VertexIndex Vertex(CornerIndex corner) const {
DRACO_DCHECK_LT(corner.value(), corner_to_vertex_map_.size());
@@ -105,11 +107,27 @@ class MeshAttributeCornerTable {
return vertex_to_left_most_corner_map_[v.value()];
}
+ inline FaceIndex Face(CornerIndex corner) const {
+ return corner_table_->Face(corner);
+ }
+
+ inline CornerIndex FirstCorner(FaceIndex face) const {
+ return corner_table_->FirstCorner(face);
+ }
+
+ inline std::array<CornerIndex, 3> AllCorners(FaceIndex face) const {
+ return corner_table_->AllCorners(face);
+ }
+
inline bool IsOnBoundary(VertexIndex vert) const {
const CornerIndex corner = LeftMostCorner(vert);
- if (corner == kInvalidCornerIndex)
+ if (corner == kInvalidCornerIndex) {
+ return true;
+ }
+ if (SwingLeft(corner) == kInvalidCornerIndex) {
return true;
- return IsCornerOnSeam(corner);
+ }
+ return false;
}
bool no_interior_seams() const { return no_interior_seams_; }
@@ -126,8 +144,9 @@ class MeshAttributeCornerTable {
// Returns the valence of the vertex at the given corner.
inline int Valence(CornerIndex c) const {
DRACO_DCHECK_LT(c.value(), corner_table_->num_corners());
- if (c == kInvalidCornerIndex)
+ if (c == kInvalidCornerIndex) {
return -1;
+ }
return ConfidentValence(c);
}
inline int ConfidentValence(CornerIndex c) const {
diff --git a/extern/draco/dracoenc/src/draco/mesh/mesh_cleanup.cc b/extern/draco/draco/src/draco/mesh/mesh_cleanup.cc
index 8e2d393b8f3..773c1e18fe6 100644
--- a/extern/draco/dracoenc/src/draco/mesh/mesh_cleanup.cc
+++ b/extern/draco/draco/src/draco/mesh/mesh_cleanup.cc
@@ -17,12 +17,14 @@
namespace draco {
bool MeshCleanup::operator()(Mesh *mesh, const MeshCleanupOptions &options) {
- if (!options.remove_degenerated_faces && !options.remove_unused_attributes)
+ if (!options.remove_degenerated_faces && !options.remove_unused_attributes) {
return true; // Nothing to cleanup.
+ }
const PointAttribute *const pos_att =
mesh->GetNamedAttribute(GeometryAttribute::POSITION);
- if (pos_att == nullptr)
+ if (pos_att == nullptr) {
return false;
+ }
// Array that is going to store whether a corresponding point is used.
std::vector<bool> is_point_used;
if (options.remove_unused_attributes) {
@@ -161,8 +163,9 @@ bool MeshCleanup::operator()(Mesh *mesh, const MeshCleanupOptions &options) {
// 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)
+ if (new_point_id == kInvalidPointIndex) {
continue;
+ }
// Index of the currently processed attribute entry in the original
// mesh.
const AttributeValueIndex original_entry_index =
diff --git a/extern/draco/dracoenc/src/draco/mesh/mesh_cleanup.h b/extern/draco/draco/src/draco/mesh/mesh_cleanup.h
index b56129dce58..b56129dce58 100644
--- a/extern/draco/dracoenc/src/draco/mesh/mesh_cleanup.h
+++ b/extern/draco/draco/src/draco/mesh/mesh_cleanup.h
diff --git a/extern/draco/dracoenc/src/draco/mesh/mesh_misc_functions.cc b/extern/draco/draco/src/draco/mesh/mesh_misc_functions.cc
index b55527aa85e..4485b3369ac 100644
--- a/extern/draco/dracoenc/src/draco/mesh/mesh_misc_functions.cc
+++ b/extern/draco/draco/src/draco/mesh/mesh_misc_functions.cc
@@ -18,18 +18,23 @@ namespace draco {
std::unique_ptr<CornerTable> CreateCornerTableFromPositionAttribute(
const Mesh *mesh) {
+ return CreateCornerTableFromAttribute(mesh, GeometryAttribute::POSITION);
+}
+
+std::unique_ptr<CornerTable> CreateCornerTableFromAttribute(
+ const Mesh *mesh, GeometryAttribute::Type type) {
typedef CornerTable::FaceType FaceType;
- const PointAttribute *const att =
- mesh->GetNamedAttribute(GeometryAttribute::POSITION);
- if (att == nullptr)
+ const PointAttribute *const att = mesh->GetNamedAttribute(type);
+ if (att == nullptr) {
return nullptr;
+ }
IndexTypeVector<FaceIndex, FaceType> faces(mesh->num_faces());
FaceType new_face;
for (FaceIndex i(0); i < mesh->num_faces(); ++i) {
const Mesh::Face &face = mesh->face(i);
for (int j = 0; j < 3; ++j) {
- // Map general vertex indices to position indices.
+ // Map general vertex indices to attribute indices.
new_face[j] = att->mapped_index(face[j]).value();
}
faces[FaceIndex(i)] = new_face;
diff --git a/extern/draco/dracoenc/src/draco/mesh/mesh_misc_functions.h b/extern/draco/draco/src/draco/mesh/mesh_misc_functions.h
index b972109e679..b450bc80cd8 100644
--- a/extern/draco/dracoenc/src/draco/mesh/mesh_misc_functions.h
+++ b/extern/draco/draco/src/draco/mesh/mesh_misc_functions.h
@@ -29,6 +29,11 @@ namespace draco {
std::unique_ptr<CornerTable> CreateCornerTableFromPositionAttribute(
const Mesh *mesh);
+// Creates a CornerTable from the first named attribute of |mesh| with a given
+// type. Returns nullptr on error.
+std::unique_ptr<CornerTable> CreateCornerTableFromAttribute(
+ const Mesh *mesh, GeometryAttribute::Type type);
+
// Creates a CornerTable from all attributes of |mesh|. Boundaries are
// automatically introduced on all attribute seams. Returns nullptr on error.
std::unique_ptr<CornerTable> CreateCornerTableFromAllAttributes(
@@ -40,19 +45,22 @@ inline bool IsCornerOppositeToAttributeSeam(CornerIndex ci,
const Mesh &mesh,
const CornerTable &ct) {
const CornerIndex opp_ci = ct.Opposite(ci);
- if (opp_ci == kInvalidCornerIndex)
+ if (opp_ci == kInvalidCornerIndex) {
return false; // No opposite corner == no attribute seam.
+ }
// Compare attribute value indices on both ends of the opposite edge.
CornerIndex c0 = ct.Next(ci);
CornerIndex c1 = ct.Previous(opp_ci);
if (att.mapped_index(mesh.CornerToPointId(c0)) !=
- att.mapped_index(mesh.CornerToPointId(c1)))
+ att.mapped_index(mesh.CornerToPointId(c1))) {
return true;
+ }
c0 = ct.Previous(ci);
c1 = ct.Next(opp_ci);
if (att.mapped_index(mesh.CornerToPointId(c0)) !=
- att.mapped_index(mesh.CornerToPointId(c1)))
+ att.mapped_index(mesh.CornerToPointId(c1))) {
return true;
+ }
return false;
}
@@ -71,8 +79,18 @@ InterpolatedVectorT ComputeInterpolatedAttributeValueOnMeshFace(
attribute.GetMappedValue(face[c], &(val[c][0]));
}
// Return an interpolated value.
- return barycentric_coord[0] * val[0] + barycentric_coord[1] * val[1] +
- barycentric_coord[2] * val[2];
+ InterpolatedVectorT res;
+ for (int d = 0; d < InterpolatedVectorT::dimension; ++d) {
+ const float interpolated_component = barycentric_coord[0] * val[0][d] +
+ barycentric_coord[1] * val[1][d] +
+ barycentric_coord[2] * val[2][d];
+ if (std::is_integral<typename InterpolatedVectorT::Scalar>::value) {
+ res[d] = std::floor(interpolated_component + 0.5f);
+ } else {
+ res[d] = interpolated_component;
+ }
+ }
+ return res;
}
} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/mesh/mesh_stripifier.cc b/extern/draco/draco/src/draco/mesh/mesh_stripifier.cc
index 5b63da3023d..f68062eba68 100644
--- a/extern/draco/dracoenc/src/draco/mesh/mesh_stripifier.cc
+++ b/extern/draco/draco/src/draco/mesh/mesh_stripifier.cc
@@ -41,13 +41,15 @@ void MeshStripifier::GenerateStripsFromCorner(int local_strip_id,
// Perform the backward pass only when there is no attribute seam between
// the initial face and the first face of the backward traversal.
if (GetOppositeCorner(corner_table_->Previous(start_ci)) ==
- kInvalidCornerIndex)
+ kInvalidCornerIndex) {
break; // Attribute seam or a boundary.
+ }
ci = corner_table_->Next(start_ci);
ci = corner_table_->SwingLeft(ci);
- if (ci == kInvalidCornerIndex)
+ if (ci == kInvalidCornerIndex) {
break;
+ }
fi = corner_table_->Face(ci);
}
@@ -74,8 +76,9 @@ void MeshStripifier::GenerateStripsFromCorner(int local_strip_id,
}
}
ci = GetOppositeCorner(ci);
- if (ci == kInvalidCornerIndex)
+ if (ci == kInvalidCornerIndex) {
break;
+ }
fi = corner_table_->Face(ci);
}
// Strip end reached.
diff --git a/extern/draco/dracoenc/src/draco/mesh/mesh_stripifier.h b/extern/draco/draco/src/draco/mesh/mesh_stripifier.h
index f7c1ead4c44..0c298f48e86 100644
--- a/extern/draco/dracoenc/src/draco/mesh/mesh_stripifier.h
+++ b/extern/draco/draco/src/draco/mesh/mesh_stripifier.h
@@ -74,8 +74,9 @@ class MeshStripifier {
// 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)
+ if (corner_table_ == nullptr) {
return false;
+ }
// Mark all faces as unvisited.
is_face_visited_.assign(mesh.num_faces(), false);
@@ -144,16 +145,19 @@ class MeshStripifier {
// across an attribute seam. Otherwise return kInvalidCornerIndex.
CornerIndex GetOppositeCorner(CornerIndex ci) const {
const CornerIndex oci = corner_table_->Opposite(ci);
- if (oci < 0)
+ if (oci < 0) {
return kInvalidCornerIndex;
+ }
// Ensure the point ids are same on both sides of the shared edge between
// the triangles.
if (CornerToPointIndex(corner_table_->Next(ci)) !=
- CornerToPointIndex(corner_table_->Previous(oci)))
+ CornerToPointIndex(corner_table_->Previous(oci))) {
return kInvalidCornerIndex;
+ }
if (CornerToPointIndex(corner_table_->Previous(ci)) !=
- CornerToPointIndex(corner_table_->Next(oci)))
+ CornerToPointIndex(corner_table_->Next(oci))) {
return kInvalidCornerIndex;
+ }
return oci;
}
@@ -179,13 +183,15 @@ template <typename OutputIteratorT, typename IndexTypeT>
bool MeshStripifier::GenerateTriangleStripsWithPrimitiveRestart(
const Mesh &mesh, IndexTypeT primitive_restart_index,
OutputIteratorT out_it) {
- if (!Prepare(mesh))
+ if (!Prepare(mesh)) {
return false;
+ }
// Go over all faces and generate strips from the first unvisited one.
for (FaceIndex fi(0); fi < mesh.num_faces(); ++fi) {
- if (is_face_visited_[fi])
+ if (is_face_visited_[fi]) {
continue;
+ }
const int longest_strip_id = FindLongestStripFromFace(fi);
@@ -203,13 +209,15 @@ bool MeshStripifier::GenerateTriangleStripsWithPrimitiveRestart(
template <typename OutputIteratorT>
bool MeshStripifier::GenerateTriangleStripsWithDegenerateTriangles(
const Mesh &mesh, OutputIteratorT out_it) {
- if (!Prepare(mesh))
+ if (!Prepare(mesh)) {
return false;
+ }
// Go over all faces and generate strips from the first unvisited one.
for (FaceIndex fi(0); fi < mesh.num_faces(); ++fi) {
- if (is_face_visited_[fi])
+ if (is_face_visited_[fi]) {
continue;
+ }
const int longest_strip_id = FindLongestStripFromFace(fi);
diff --git a/extern/draco/dracoenc/src/draco/mesh/triangle_soup_mesh_builder.cc b/extern/draco/draco/src/draco/mesh/triangle_soup_mesh_builder.cc
index 7a76745342b..60b0c50b8d5 100644
--- a/extern/draco/dracoenc/src/draco/mesh/triangle_soup_mesh_builder.cc
+++ b/extern/draco/draco/src/draco/mesh/triangle_soup_mesh_builder.cc
@@ -60,15 +60,17 @@ void TriangleSoupMeshBuilder::SetPerFaceAttributeValueForFace(
{{PointIndex(start_index), PointIndex(start_index + 1),
PointIndex(start_index + 2)}});
int8_t &element_type = attribute_element_types_[att_id];
- if (element_type < 0)
+ if (element_type < 0) {
element_type = MESH_FACE_ATTRIBUTE;
+ }
}
std::unique_ptr<Mesh> TriangleSoupMeshBuilder::Finalize() {
#ifdef DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED
// First deduplicate attribute values.
- if (!mesh_->DeduplicateAttributeValues())
+ if (!mesh_->DeduplicateAttributeValues()) {
return nullptr;
+ }
#endif
#ifdef DRACO_ATTRIBUTE_INDICES_DEDUPLICATION_SUPPORTED
// Also deduplicate vertex indices.
diff --git a/extern/draco/dracoenc/src/draco/mesh/triangle_soup_mesh_builder.h b/extern/draco/draco/src/draco/mesh/triangle_soup_mesh_builder.h
index 3ae652cfeee..89466e1d849 100644
--- a/extern/draco/dracoenc/src/draco/mesh/triangle_soup_mesh_builder.h
+++ b/extern/draco/draco/src/draco/mesh/triangle_soup_mesh_builder.h
@@ -16,7 +16,6 @@
#define DRACO_MESH_TRIANGLE_SOUP_MESH_BUILDER_H_
#include "draco/draco_features.h"
-
#include "draco/mesh/mesh.h"
namespace draco {
diff --git a/extern/draco/dracoenc/src/draco/mesh/valence_cache.h b/extern/draco/draco/src/draco/mesh/valence_cache.h
index f75d66f4b99..3540377db81 100644
--- a/extern/draco/dracoenc/src/draco/mesh/valence_cache.h
+++ b/extern/draco/draco/src/draco/mesh/valence_cache.h
@@ -36,13 +36,15 @@ class ValenceCache {
// Do not call before CacheValences() / CacheValencesInaccurate().
inline int8_t ValenceFromCacheInaccurate(CornerIndex c) const {
- if (c == kInvalidCornerIndex)
+ if (c == kInvalidCornerIndex) {
return -1;
+ }
return ValenceFromCacheInaccurate(table_.Vertex(c));
}
inline int32_t ValenceFromCache(CornerIndex c) const {
- if (c == kInvalidCornerIndex)
+ if (c == kInvalidCornerIndex) {
return -1;
+ }
return ValenceFromCache(table_.Vertex(c));
}
@@ -65,18 +67,20 @@ class ValenceCache {
if (vertex_valence_cache_8_bit_.size() == 0) {
const VertexIndex vertex_count = VertexIndex(table_.num_vertices());
vertex_valence_cache_8_bit_.resize(vertex_count.value());
- for (VertexIndex v = VertexIndex(0); v < vertex_count; v += 1)
+ for (VertexIndex v = VertexIndex(0); v < vertex_count; v += 1) {
vertex_valence_cache_8_bit_[v] = static_cast<int8_t>(
(std::min)(static_cast<int32_t>(std::numeric_limits<int8_t>::max()),
table_.Valence(v)));
+ }
}
}
void CacheValences() const {
if (vertex_valence_cache_32_bit_.size() == 0) {
const VertexIndex vertex_count = VertexIndex(table_.num_vertices());
vertex_valence_cache_32_bit_.resize(vertex_count.value());
- for (VertexIndex v = VertexIndex(0); v < vertex_count; v += 1)
+ for (VertexIndex v = VertexIndex(0); v < vertex_count; v += 1) {
vertex_valence_cache_32_bit_[v] = table_.Valence(v);
+ }
}
}
@@ -90,8 +94,9 @@ class ValenceCache {
}
inline int8_t ValenceFromCacheInaccurate(VertexIndex v) const {
DRACO_DCHECK_EQ(vertex_valence_cache_8_bit_.size(), table_.num_vertices());
- if (v == kInvalidVertexIndex || v.value() >= table_.num_vertices())
+ if (v == kInvalidVertexIndex || v.value() >= table_.num_vertices()) {
return -1;
+ }
return ConfidentValenceFromCacheInaccurate(v);
}
inline int8_t ConfidentValenceFromCacheInaccurate(VertexIndex v) const {
@@ -103,8 +108,9 @@ class ValenceCache {
// TODO(draco-eng) Add unit tests for ValenceCache functions.
inline int32_t ValenceFromCache(VertexIndex v) const {
DRACO_DCHECK_EQ(vertex_valence_cache_32_bit_.size(), table_.num_vertices());
- if (v == kInvalidVertexIndex || v.value() >= table_.num_vertices())
+ if (v == kInvalidVertexIndex || v.value() >= table_.num_vertices()) {
return -1;
+ }
return ConfidentValenceFromCache(v);
}
diff --git a/extern/draco/dracoenc/src/draco/metadata/geometry_metadata.cc b/extern/draco/draco/src/draco/metadata/geometry_metadata.cc
index 896663ae8ab..b83898140ae 100644
--- a/extern/draco/dracoenc/src/draco/metadata/geometry_metadata.cc
+++ b/extern/draco/draco/src/draco/metadata/geometry_metadata.cc
@@ -13,6 +13,7 @@
// limitations under the License.
//
#include "draco/metadata/geometry_metadata.h"
+
#include <utility>
namespace draco {
@@ -21,10 +22,12 @@ const AttributeMetadata *GeometryMetadata::GetAttributeMetadataByStringEntry(
const std::string &entry_name, const std::string &entry_value) const {
for (auto &&att_metadata : att_metadatas_) {
std::string value;
- if (!att_metadata->GetEntryString(entry_name, &value))
+ if (!att_metadata->GetEntryString(entry_name, &value)) {
continue;
- if (value == entry_value)
+ }
+ if (value == entry_value) {
return att_metadata.get();
+ }
}
// No attribute has the requested entry.
return nullptr;
@@ -32,8 +35,9 @@ const AttributeMetadata *GeometryMetadata::GetAttributeMetadataByStringEntry(
bool GeometryMetadata::AddAttributeMetadata(
std::unique_ptr<AttributeMetadata> att_metadata) {
- if (!att_metadata.get())
+ if (!att_metadata.get()) {
return false;
+ }
att_metadatas_.push_back(std::move(att_metadata));
return true;
}
diff --git a/extern/draco/dracoenc/src/draco/metadata/geometry_metadata.h b/extern/draco/draco/src/draco/metadata/geometry_metadata.h
index 9f668f7fa15..ec7ecb9ee68 100644
--- a/extern/draco/dracoenc/src/draco/metadata/geometry_metadata.h
+++ b/extern/draco/draco/src/draco/metadata/geometry_metadata.h
@@ -51,11 +51,12 @@ struct AttributeMetadataHasher {
return hash;
}
};
+
// Class for representing the metadata for a point cloud. It could have a list
// of attribute metadata.
class GeometryMetadata : public Metadata {
public:
- GeometryMetadata(){};
+ GeometryMetadata() {}
explicit GeometryMetadata(const Metadata &metadata) : Metadata(metadata) {}
const AttributeMetadata *GetAttributeMetadataByStringEntry(
@@ -63,9 +64,12 @@ class GeometryMetadata : public Metadata {
bool AddAttributeMetadata(std::unique_ptr<AttributeMetadata> att_metadata);
void DeleteAttributeMetadataByUniqueId(int32_t att_unique_id) {
+ if (att_unique_id < 0) {
+ return;
+ }
for (auto itr = att_metadatas_.begin(); itr != att_metadatas_.end();
++itr) {
- if (itr->get()->att_unique_id() == att_unique_id) {
+ if (itr->get()->att_unique_id() == static_cast<uint32_t>(att_unique_id)) {
att_metadatas_.erase(itr);
return;
}
@@ -74,10 +78,15 @@ class GeometryMetadata : public Metadata {
const AttributeMetadata *GetAttributeMetadataByUniqueId(
int32_t att_unique_id) const {
+ if (att_unique_id < 0) {
+ return nullptr;
+ }
+
// TODO(draco-eng): Consider using unordered_map instead of vector to store
// attribute metadata.
for (auto &&att_metadata : att_metadatas_) {
- if (att_metadata->att_unique_id() == att_unique_id) {
+ if (att_metadata->att_unique_id() ==
+ static_cast<uint32_t>(att_unique_id)) {
return att_metadata.get();
}
}
@@ -85,10 +94,15 @@ class GeometryMetadata : public Metadata {
}
AttributeMetadata *attribute_metadata(int32_t att_unique_id) {
+ if (att_unique_id < 0) {
+ return nullptr;
+ }
+
// TODO(draco-eng): Consider use unordered_map instead of vector to store
// attribute metadata.
for (auto &&att_metadata : att_metadatas_) {
- if (att_metadata->att_unique_id() == att_unique_id) {
+ if (att_metadata->att_unique_id() ==
+ static_cast<uint32_t>(att_unique_id)) {
return att_metadata.get();
}
}
diff --git a/extern/draco/dracoenc/src/draco/metadata/metadata.cc b/extern/draco/draco/src/draco/metadata/metadata.cc
index ca82d163bf8..9141907ed71 100644
--- a/extern/draco/dracoenc/src/draco/metadata/metadata.cc
+++ b/extern/draco/draco/src/draco/metadata/metadata.cc
@@ -13,6 +13,7 @@
// limitations under the License.
//
#include "draco/metadata/metadata.h"
+
#include <utility>
namespace draco {
@@ -29,8 +30,9 @@ EntryValue::EntryValue(const std::string &value) {
template <>
bool EntryValue::GetValue(std::string *value) const {
- if (data_.empty())
+ if (data_.empty()) {
return false;
+ }
value->resize(data_.size());
memcpy(&value->at(0), &data_[0], data_.size());
return true;
diff --git a/extern/draco/dracoenc/src/draco/metadata/metadata.h b/extern/draco/draco/src/draco/metadata/metadata.h
index bf0be36f3b1..56d05e46a3e 100644
--- a/extern/draco/dracoenc/src/draco/metadata/metadata.h
+++ b/extern/draco/draco/src/draco/metadata/metadata.h
@@ -16,9 +16,9 @@
#define DRACO_METADATA_METADATA_H_
#include <cstring>
+#include <map>
#include <memory>
#include <string>
-#include <map>
#include <vector>
#include "draco/core/hash_utils.h"
@@ -59,8 +59,9 @@ class EntryValue {
template <typename DataTypeT>
bool GetValue(std::vector<DataTypeT> *value) const {
- if (data_.empty())
+ if (data_.empty()) {
return false;
+ }
const size_t data_type_size = sizeof(DataTypeT);
if (data_.size() % data_type_size != 0) {
return false;
@@ -82,7 +83,7 @@ class EntryValue {
struct EntryValueHasher {
size_t operator()(const EntryValue &ev) const {
size_t hash = ev.data_.size();
- for (int i = 0; i < ev.data_.size(); ++i) {
+ for (size_t i = 0; i < ev.data_.size(); ++i) {
hash = HashCombine(ev.data_[i], hash);
}
return hash;
@@ -150,11 +151,9 @@ class Metadata {
void RemoveEntry(const std::string &name);
int num_entries() const { return static_cast<int>(entries_.size()); }
- const std::map<std::string, EntryValue> &entries() const {
- return entries_;
- }
- const std::map<std::string, std::unique_ptr<Metadata>>
- &sub_metadatas() const {
+ const std::map<std::string, EntryValue> &entries() const { return entries_; }
+ const std::map<std::string, std::unique_ptr<Metadata>> &sub_metadatas()
+ const {
return sub_metadatas_;
}
@@ -163,8 +162,9 @@ class Metadata {
template <typename DataTypeT>
void AddEntry(const std::string &entry_name, const DataTypeT &entry_value) {
const auto itr = entries_.find(entry_name);
- if (itr != entries_.end())
+ if (itr != entries_.end()) {
entries_.erase(itr);
+ }
entries_.insert(std::make_pair(entry_name, EntryValue(entry_value)));
}
diff --git a/extern/draco/dracoenc/src/draco/metadata/metadata_decoder.cc b/extern/draco/draco/src/draco/metadata/metadata_decoder.cc
index 62acc26772a..e664e4fa524 100644
--- a/extern/draco/dracoenc/src/draco/metadata/metadata_decoder.cc
+++ b/extern/draco/draco/src/draco/metadata/metadata_decoder.cc
@@ -24,80 +24,119 @@ MetadataDecoder::MetadataDecoder() : buffer_(nullptr) {}
bool MetadataDecoder::DecodeMetadata(DecoderBuffer *in_buffer,
Metadata *metadata) {
- if (!metadata)
+ if (!metadata) {
return false;
+ }
buffer_ = in_buffer;
return DecodeMetadata(metadata);
}
bool MetadataDecoder::DecodeGeometryMetadata(DecoderBuffer *in_buffer,
GeometryMetadata *metadata) {
- if (!metadata)
+ if (!metadata) {
return false;
+ }
buffer_ = in_buffer;
uint32_t num_att_metadata = 0;
- DecodeVarint(&num_att_metadata, buffer_);
+ if (!DecodeVarint(&num_att_metadata, buffer_)) {
+ return false;
+ }
// Decode attribute metadata.
for (uint32_t i = 0; i < num_att_metadata; ++i) {
uint32_t att_unique_id;
- DecodeVarint(&att_unique_id, buffer_);
+ if (!DecodeVarint(&att_unique_id, buffer_)) {
+ return false;
+ }
std::unique_ptr<AttributeMetadata> att_metadata =
std::unique_ptr<AttributeMetadata>(new AttributeMetadata());
att_metadata->set_att_unique_id(att_unique_id);
- if (!DecodeMetadata(static_cast<Metadata *>(att_metadata.get())))
+ if (!DecodeMetadata(static_cast<Metadata *>(att_metadata.get()))) {
return false;
+ }
metadata->AddAttributeMetadata(std::move(att_metadata));
}
return DecodeMetadata(static_cast<Metadata *>(metadata));
}
bool MetadataDecoder::DecodeMetadata(Metadata *metadata) {
- uint32_t num_entries = 0;
- DecodeVarint(&num_entries, buffer_);
- for (uint32_t i = 0; i < num_entries; ++i) {
- if (!DecodeEntry(metadata))
+ struct MetadataPair {
+ Metadata *parent_metadata;
+ Metadata *decoded_metadata;
+ };
+ std::vector<MetadataPair> metadata_stack;
+ metadata_stack.push_back({nullptr, metadata});
+ while (!metadata_stack.empty()) {
+ const MetadataPair mp = metadata_stack.back();
+ metadata_stack.pop_back();
+ metadata = mp.decoded_metadata;
+
+ if (mp.parent_metadata != nullptr) {
+ std::string sub_metadata_name;
+ if (!DecodeName(&sub_metadata_name)) {
+ return false;
+ }
+ 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 (metadata == nullptr) {
return false;
- }
- uint32_t num_sub_metadata = 0;
- DecodeVarint(&num_sub_metadata, buffer_);
- for (uint32_t i = 0; i < num_sub_metadata; ++i) {
- std::string sub_metadata_name;
- if (!DecodeName(&sub_metadata_name))
+ }
+
+ uint32_t num_entries = 0;
+ if (!DecodeVarint(&num_entries, buffer_)) {
return false;
- std::unique_ptr<Metadata> sub_metadata =
- std::unique_ptr<Metadata>(new Metadata());
- if (!DecodeMetadata(sub_metadata.get()))
+ }
+ for (uint32_t i = 0; i < num_entries; ++i) {
+ if (!DecodeEntry(metadata)) {
+ return false;
+ }
+ }
+ uint32_t num_sub_metadata = 0;
+ if (!DecodeVarint(&num_sub_metadata, buffer_)) {
return false;
- metadata->AddSubMetadata(sub_metadata_name, std::move(sub_metadata));
+ }
+ for (uint32_t i = 0; i < num_sub_metadata; ++i) {
+ metadata_stack.push_back({metadata, nullptr});
+ }
}
return true;
}
bool MetadataDecoder::DecodeEntry(Metadata *metadata) {
std::string entry_name;
- if (!DecodeName(&entry_name))
+ if (!DecodeName(&entry_name)) {
return false;
+ }
uint32_t data_size = 0;
- if (!DecodeVarint(&data_size, buffer_))
+ if (!DecodeVarint(&data_size, buffer_)) {
return false;
- if (data_size == 0)
+ }
+ if (data_size == 0) {
return false;
+ }
std::vector<uint8_t> entry_value(data_size);
- if (!buffer_->Decode(&entry_value[0], data_size))
+ if (!buffer_->Decode(&entry_value[0], data_size)) {
return false;
+ }
metadata->AddEntryBinary(entry_name, entry_value);
return true;
}
bool MetadataDecoder::DecodeName(std::string *name) {
uint8_t name_len = 0;
- if (!buffer_->Decode(&name_len))
+ if (!buffer_->Decode(&name_len)) {
return false;
+ }
name->resize(name_len);
- if (name_len == 0)
+ if (name_len == 0) {
return true;
- if (!buffer_->Decode(&name->at(0), name_len))
+ }
+ if (!buffer_->Decode(&name->at(0), name_len)) {
return false;
+ }
return true;
}
} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/metadata/metadata_decoder.h b/extern/draco/draco/src/draco/metadata/metadata_decoder.h
index b4c4943fbaa..b4c4943fbaa 100644
--- a/extern/draco/dracoenc/src/draco/metadata/metadata_decoder.h
+++ b/extern/draco/draco/src/draco/metadata/metadata_decoder.h
diff --git a/extern/draco/dracoenc/src/draco/metadata/metadata_encoder.cc b/extern/draco/draco/src/draco/metadata/metadata_encoder.cc
index 6e85ce6f9d9..168be83c6b2 100644
--- a/extern/draco/dracoenc/src/draco/metadata/metadata_encoder.cc
+++ b/extern/draco/draco/src/draco/metadata/metadata_encoder.cc
@@ -25,8 +25,9 @@ bool MetadataEncoder::EncodeMetadata(EncoderBuffer *out_buffer,
EncodeVarint(static_cast<uint32_t>(metadata->num_entries()), out_buffer);
// Encode all entries.
for (const auto &entry : entries) {
- if (!EncodeString(out_buffer, entry.first))
+ if (!EncodeString(out_buffer, entry.first)) {
return false;
+ }
const std::vector<uint8_t> &entry_value = entry.second.data();
const uint32_t data_size = static_cast<uint32_t>(entry_value.size());
EncodeVarint(data_size, out_buffer);
@@ -38,8 +39,9 @@ bool MetadataEncoder::EncodeMetadata(EncoderBuffer *out_buffer,
EncodeVarint(static_cast<uint32_t>(sub_metadatas.size()), out_buffer);
// Encode each sub-metadata
for (auto &&sub_metadata_entry : sub_metadatas) {
- if (!EncodeString(out_buffer, sub_metadata_entry.first))
+ if (!EncodeString(out_buffer, sub_metadata_entry.first)) {
return false;
+ }
EncodeMetadata(out_buffer, sub_metadata_entry.second.get());
}
@@ -48,8 +50,9 @@ bool MetadataEncoder::EncodeMetadata(EncoderBuffer *out_buffer,
bool MetadataEncoder::EncodeAttributeMetadata(
EncoderBuffer *out_buffer, const AttributeMetadata *metadata) {
- if (!metadata)
+ if (!metadata) {
return false;
+ }
// Encode attribute id.
EncodeVarint(metadata->att_unique_id(), out_buffer);
EncodeMetadata(out_buffer, static_cast<const Metadata *>(metadata));
@@ -58,8 +61,9 @@ bool MetadataEncoder::EncodeAttributeMetadata(
bool MetadataEncoder::EncodeGeometryMetadata(EncoderBuffer *out_buffer,
const GeometryMetadata *metadata) {
- if (!metadata)
+ if (!metadata) {
return false;
+ }
// Encode number of attribute metadata.
const std::vector<std::unique_ptr<AttributeMetadata>> &att_metadatas =
metadata->attribute_metadatas();
@@ -79,8 +83,9 @@ bool MetadataEncoder::EncodeString(EncoderBuffer *out_buffer,
const std::string &str) {
// We only support string of maximum length 255 which is using one byte to
// encode the length.
- if (str.size() > 255)
+ if (str.size() > 255) {
return false;
+ }
if (str.empty()) {
out_buffer->Encode(static_cast<uint8_t>(0));
} else {
diff --git a/extern/draco/dracoenc/src/draco/metadata/metadata_encoder.h b/extern/draco/draco/src/draco/metadata/metadata_encoder.h
index 5bce5d5b50e..5bce5d5b50e 100644
--- a/extern/draco/dracoenc/src/draco/metadata/metadata_encoder.h
+++ b/extern/draco/draco/src/draco/metadata/metadata_encoder.h
diff --git a/extern/draco/dracoenc/src/draco/point_cloud/point_cloud.cc b/extern/draco/draco/src/draco/point_cloud/point_cloud.cc
index 9552654be16..8eb638f80d4 100644
--- a/extern/draco/dracoenc/src/draco/point_cloud/point_cloud.cc
+++ b/extern/draco/draco/src/draco/point_cloud/point_cloud.cc
@@ -23,8 +23,9 @@ PointCloud::PointCloud() : num_points_(0) {}
int32_t PointCloud::NumNamedAttributes(GeometryAttribute::Type type) const {
if (type == GeometryAttribute::INVALID ||
- type >= GeometryAttribute::NAMED_ATTRIBUTES_COUNT)
+ type >= GeometryAttribute::NAMED_ATTRIBUTES_COUNT) {
return 0;
+ }
return static_cast<int32_t>(named_attribute_index_[type].size());
}
@@ -34,8 +35,9 @@ int32_t PointCloud::GetNamedAttributeId(GeometryAttribute::Type type) const {
int32_t PointCloud::GetNamedAttributeId(GeometryAttribute::Type type,
int i) const {
- if (NumNamedAttributes(type) <= i)
+ if (NumNamedAttributes(type) <= i) {
return -1;
+ }
return named_attribute_index_[type][i];
}
@@ -47,8 +49,9 @@ const PointAttribute *PointCloud::GetNamedAttribute(
const PointAttribute *PointCloud::GetNamedAttribute(
GeometryAttribute::Type type, int i) const {
const int32_t att_id = GetNamedAttributeId(type, i);
- if (att_id == -1)
+ if (att_id == -1) {
return nullptr;
+ }
return attributes_[att_id].get();
}
@@ -57,8 +60,9 @@ const PointAttribute *PointCloud::GetNamedAttributeByUniqueId(
for (size_t att_id = 0; att_id < named_attribute_index_[type].size();
++att_id) {
if (attributes_[named_attribute_index_[type][att_id]]->unique_id() ==
- unique_id)
+ unique_id) {
return attributes_[named_attribute_index_[type][att_id]].get();
+ }
}
return nullptr;
}
@@ -66,15 +70,17 @@ const PointAttribute *PointCloud::GetNamedAttributeByUniqueId(
const PointAttribute *PointCloud::GetAttributeByUniqueId(
uint32_t unique_id) const {
const int32_t att_id = GetAttributeIdByUniqueId(unique_id);
- if (att_id == -1)
+ if (att_id == -1) {
return nullptr;
+ }
return attributes_[att_id].get();
}
int32_t PointCloud::GetAttributeIdByUniqueId(uint32_t unique_id) const {
for (size_t att_id = 0; att_id < attributes_.size(); ++att_id) {
- if (attributes_[att_id]->unique_id() == unique_id)
+ if (attributes_[att_id]->unique_id() == unique_id) {
return static_cast<int32_t>(att_id);
+ }
}
return -1;
}
@@ -88,8 +94,9 @@ int PointCloud::AddAttribute(
const GeometryAttribute &att, bool identity_mapping,
AttributeValueIndex::ValueType num_attribute_values) {
auto pa = CreateAttribute(att, identity_mapping, num_attribute_values);
- if (!pa)
+ if (!pa) {
return -1;
+ }
const int32_t att_id = AddAttribute(std::move(pa));
return att_id;
}
@@ -97,8 +104,9 @@ int PointCloud::AddAttribute(
std::unique_ptr<PointAttribute> PointCloud::CreateAttribute(
const GeometryAttribute &att, bool identity_mapping,
AttributeValueIndex::ValueType num_attribute_values) const {
- if (att.attribute_type() == GeometryAttribute::INVALID)
+ if (att.attribute_type() == GeometryAttribute::INVALID) {
return nullptr;
+ }
std::unique_ptr<PointAttribute> pa =
std::unique_ptr<PointAttribute>(new PointAttribute(att));
// Initialize point cloud specific attribute data.
@@ -107,7 +115,7 @@ std::unique_ptr<PointAttribute> PointCloud::CreateAttribute(
pa->SetExplicitMapping(num_points_);
} else {
pa->SetIdentityMapping();
- pa->Resize(num_points_);
+ num_attribute_values = std::max(num_points_, num_attribute_values);
}
if (num_attribute_values > 0) {
pa->Reset(num_attribute_values);
@@ -128,8 +136,9 @@ void PointCloud::SetAttribute(int att_id, std::unique_ptr<PointAttribute> pa) {
}
void PointCloud::DeleteAttribute(int att_id) {
- if (att_id < 0 || att_id >= attributes_.size())
+ if (att_id < 0 || att_id >= attributes_.size()) {
return; // Attribute does not exist.
+ }
const GeometryAttribute::Type att_type =
attributes_[att_id]->attribute_type();
const uint32_t unique_id = attribute(att_id)->unique_id();
@@ -143,8 +152,9 @@ void PointCloud::DeleteAttribute(int att_id) {
if (att_type < GeometryAttribute::NAMED_ATTRIBUTES_COUNT) {
const auto it = std::find(named_attribute_index_[att_type].begin(),
named_attribute_index_[att_type].end(), att_id);
- if (it != named_attribute_index_[att_type].end())
+ if (it != named_attribute_index_[att_type].end()) {
named_attribute_index_[att_type].erase(it);
+ }
}
// Update ids of all subsequent named attributes (decrease them by one).
@@ -173,8 +183,9 @@ void PointCloud::DeduplicatePointIds() {
for (int32_t i = 0; i < this->num_attributes(); ++i) {
const AttributeValueIndex att_id0 = attribute(i)->mapped_index(p0);
const AttributeValueIndex att_id1 = attribute(i)->mapped_index(p1);
- if (att_id0 != att_id1)
+ if (att_id0 != att_id1) {
return false;
+ }
}
return true;
};
@@ -196,8 +207,9 @@ void PointCloud::DeduplicatePointIds() {
unique_points.push_back(i);
}
}
- if (num_unique_points == num_points_)
+ if (num_unique_points == num_points_) {
return; // All vertices are already unique.
+ }
ApplyPointIdDeduplication(index_map, unique_points);
set_num_points(num_unique_points);
@@ -228,12 +240,14 @@ void PointCloud::ApplyPointIdDeduplication(
#ifdef DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED
bool PointCloud::DeduplicateAttributeValues() {
// Go over all attributes and create mapping between duplicate entries.
- if (num_points() == 0)
+ if (num_points() == 0) {
return false; // Unexpected attribute size.
+ }
// Deduplicate all attributes.
for (int32_t att_id = 0; att_id < num_attributes(); ++att_id) {
- if (!attribute(att_id)->DeduplicateValues(*attribute(att_id)))
+ if (!attribute(att_id)->DeduplicateValues(*attribute(att_id))) {
return false;
+ }
}
return true;
}
@@ -257,7 +271,8 @@ BoundingBox PointCloud::ComputeBoundingBox() const {
// Consider using pc_att->ConvertValue<float, 3>(i, &p[0]) (Enforced
// transformation from Vector with any dimension to Vector3f)
Vector3f p;
- for (AttributeValueIndex i(0); i < pc_att->size(); ++i) {
+ 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);
}
diff --git a/extern/draco/dracoenc/src/draco/point_cloud/point_cloud.h b/extern/draco/draco/src/draco/point_cloud/point_cloud.h
index e15206f17c4..d11bd47a366 100644
--- a/extern/draco/dracoenc/src/draco/point_cloud/point_cloud.h
+++ b/extern/draco/draco/src/draco/point_cloud/point_cloud.h
@@ -15,11 +15,10 @@
#ifndef DRACO_POINT_CLOUD_POINT_CLOUD_H_
#define DRACO_POINT_CLOUD_POINT_CLOUD_H_
-#include "draco/draco_features.h"
-
#include "draco/attributes/point_attribute.h"
#include "draco/core/bounding_box.h"
#include "draco/core/vector_d.h"
+#include "draco/draco_features.h"
#include "draco/metadata/geometry_metadata.h"
namespace draco {
@@ -131,7 +130,7 @@ class PointCloud {
// Add metadata for an attribute.
void AddAttributeMetadata(int32_t att_id,
std::unique_ptr<AttributeMetadata> metadata) {
- if (!metadata_.get()) {
+ if (!metadata_) {
metadata_ = std::unique_ptr<GeometryMetadata>(new GeometryMetadata());
}
const int32_t att_unique_id = attribute(att_id)->unique_id();
@@ -141,8 +140,9 @@ class PointCloud {
const AttributeMetadata *GetAttributeMetadataByAttributeId(
int32_t att_id) const {
- if (metadata_ == nullptr)
+ if (metadata_ == nullptr) {
return nullptr;
+ }
const uint32_t unique_id = attribute(att_id)->unique_id();
return metadata_->GetAttributeMetadataByUniqueId(unique_id);
}
@@ -150,20 +150,23 @@ class PointCloud {
// Returns the attribute metadata that has the requested metadata entry.
const AttributeMetadata *GetAttributeMetadataByStringEntry(
const std::string &name, const std::string &value) const {
- if (metadata_ == nullptr)
+ if (metadata_ == nullptr) {
return nullptr;
+ }
return metadata_->GetAttributeMetadataByStringEntry(name, value);
}
// Returns the first attribute that has the requested metadata entry.
int GetAttributeIdByMetadataEntry(const std::string &name,
const std::string &value) const {
- if (metadata_ == nullptr)
+ if (metadata_ == nullptr) {
return -1;
+ }
const AttributeMetadata *att_metadata =
metadata_->GetAttributeMetadataByStringEntry(name, value);
- if (!att_metadata)
+ if (!att_metadata) {
return -1;
+ }
return GetAttributeIdByUniqueId(att_metadata->att_unique_id());
}
@@ -229,8 +232,8 @@ struct PointCloudHasher {
}
// Hash metadata.
GeometryMetadataHasher metadata_hasher;
- if (pc.metadata_.get()) {
- hash = HashCombine(metadata_hasher(*pc.metadata_.get()), hash);
+ if (pc.metadata_) {
+ hash = HashCombine(metadata_hasher(*pc.metadata_), hash);
}
return hash;
}
diff --git a/extern/draco/dracoenc/src/draco/point_cloud/point_cloud_builder.cc b/extern/draco/draco/src/draco/point_cloud/point_cloud_builder.cc
index a0381631cfd..431ae505f5f 100644
--- a/extern/draco/dracoenc/src/draco/point_cloud/point_cloud_builder.cc
+++ b/extern/draco/draco/src/draco/point_cloud/point_cloud_builder.cc
@@ -43,8 +43,9 @@ void PointCloudBuilder::SetAttributeValuesForAllPoints(
PointAttribute *const att = point_cloud_->attribute(att_id);
const int data_stride =
DataTypeLength(att->data_type()) * att->num_components();
- if (stride == 0)
+ if (stride == 0) {
stride = data_stride;
+ }
if (stride == data_stride) {
// Fast copy path.
att->buffer()->Write(0, attribute_values,
diff --git a/extern/draco/dracoenc/src/draco/point_cloud/point_cloud_builder.h b/extern/draco/draco/src/draco/point_cloud/point_cloud_builder.h
index cf55a728b15..cf55a728b15 100644
--- a/extern/draco/dracoenc/src/draco/point_cloud/point_cloud_builder.h
+++ b/extern/draco/draco/src/draco/point_cloud/point_cloud_builder.h
diff --git a/extern/draco/dracoenc/cmake/DracoConfig.cmake b/extern/draco/dracoenc/cmake/DracoConfig.cmake
deleted file mode 100644
index be5e1faefe2..00000000000
--- a/extern/draco/dracoenc/cmake/DracoConfig.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-@PACKAGE_INIT@
-set_and_check(draco_INCLUDE_DIR "@PACKAGE_draco_include_install_dir@")
-set_and_check(draco_LIBRARY_DIR "@PACKAGE_draco_lib_install_dir@")
diff --git a/extern/draco/dracoenc/cmake/FindDraco.cmake b/extern/draco/dracoenc/cmake/FindDraco.cmake
deleted file mode 100644
index 5f27bf29390..00000000000
--- a/extern/draco/dracoenc/cmake/FindDraco.cmake
+++ /dev/null
@@ -1,58 +0,0 @@
-# Finddraco
-#
-# Locates draco and sets the following variables:
-#
-# draco_FOUND
-# draco_INCLUDE_DIRS
-# draco_LIBARY_DIRS
-# draco_LIBRARIES
-# draco_VERSION_STRING
-#
-# draco_FOUND is set to YES only when all other variables are successfully
-# configured.
-
-unset(draco_FOUND)
-unset(draco_INCLUDE_DIRS)
-unset(draco_LIBRARY_DIRS)
-unset(draco_LIBRARIES)
-unset(draco_VERSION_STRING)
-
-mark_as_advanced(draco_FOUND)
-mark_as_advanced(draco_INCLUDE_DIRS)
-mark_as_advanced(draco_LIBRARY_DIRS)
-mark_as_advanced(draco_LIBRARIES)
-mark_as_advanced(draco_VERSION_STRING)
-
-set(draco_version_file_no_prefix "draco/src/draco/core/draco_version.h")
-
-# Set draco_INCLUDE_DIRS
-find_path(draco_INCLUDE_DIRS NAMES "${draco_version_file_no_prefix}")
-
-# Extract the version string from draco_version.h.
-if (draco_INCLUDE_DIRS)
- set(draco_version_file
- "${draco_INCLUDE_DIRS}/draco/src/draco/core/draco_version.h")
- file(STRINGS "${draco_version_file}" draco_version
- REGEX "kdracoVersion")
- list(GET draco_version 0 draco_version)
- string(REPLACE "static const char kdracoVersion[] = " "" draco_version
- "${draco_version}")
- string(REPLACE ";" "" draco_version "${draco_version}")
- string(REPLACE "\"" "" draco_version "${draco_version}")
- set(draco_VERSION_STRING ${draco_version})
-endif ()
-
-# Find the library.
-if (BUILD_SHARED_LIBS)
- find_library(draco_LIBRARIES NAMES draco.dll libdraco.dylib libdraco.so)
-else ()
- find_library(draco_LIBRARIES NAMES draco.lib libdraco.a)
-endif ()
-
-# Store path to library.
-get_filename_component(draco_LIBRARY_DIRS ${draco_LIBRARIES} DIRECTORY)
-
-if (draco_INCLUDE_DIRS AND draco_LIBRARY_DIRS AND draco_LIBRARIES AND
- draco_VERSION_STRING)
- set(draco_FOUND YES)
-endif ()
diff --git a/extern/draco/dracoenc/cmake/compiler_flags.cmake b/extern/draco/dracoenc/cmake/compiler_flags.cmake
deleted file mode 100644
index bbfb069d2d3..00000000000
--- a/extern/draco/dracoenc/cmake/compiler_flags.cmake
+++ /dev/null
@@ -1,216 +0,0 @@
-if (NOT DRACO_CMAKE_COMPILER_FLAGS_CMAKE_)
-set(DRACO_CMAKE_COMPILER_FLAGS_CMAKE_ 1)
-
-include(CheckCCompilerFlag)
-include(CheckCXXCompilerFlag)
-include("${draco_root}/cmake/compiler_tests.cmake")
-
-# Strings used to cache failed C/CXX flags.
-set(DRACO_FAILED_C_FLAGS)
-set(DRACO_FAILED_CXX_FLAGS)
-
-# Checks C compiler for support of $c_flag. Adds $c_flag to $CMAKE_C_FLAGS when
-# the compile test passes. Caches $c_flag in $DRACO_FAILED_C_FLAGS when the test
-# fails.
-macro (add_c_flag_if_supported c_flag)
- unset(C_FLAG_FOUND CACHE)
- string(FIND "${CMAKE_C_FLAGS}" "${c_flag}" C_FLAG_FOUND)
- unset(C_FLAG_FAILED CACHE)
- string(FIND "${DRACO_FAILED_C_FLAGS}" "${c_flag}" C_FLAG_FAILED)
-
- if (${C_FLAG_FOUND} EQUAL -1 AND ${C_FLAG_FAILED} EQUAL -1)
- unset(C_FLAG_SUPPORTED CACHE)
- message("Checking C compiler flag support for: " ${c_flag})
- check_c_compiler_flag("${c_flag}" C_FLAG_SUPPORTED)
- if (${C_FLAG_SUPPORTED})
- string(APPEND CMAKE_C_FLAGS " ${c_flag}" CACHE STRING "")
- else ()
- string(APPEND DRACO_FAILED_C_FLAGS " ${c_flag}" CACHE STRING
- "" FORCE)
- endif ()
- endif ()
-endmacro ()
-
-# Checks C++ compiler for support of $cxx_flag. Adds $cxx_flag to
-# $CMAKE_CXX_FLAGS when the compile test passes. Caches $c_flag in
-# $DRACO_FAILED_CXX_FLAGS when the test fails.
-macro (add_cxx_flag_if_supported cxx_flag)
- unset(CXX_FLAG_FOUND CACHE)
- string(FIND "${CMAKE_CXX_FLAGS}" "${cxx_flag}" CXX_FLAG_FOUND)
- unset(CXX_FLAG_FAILED CACHE)
- string(FIND "${DRACO_FAILED_CXX_FLAGS}" "${cxx_flag}" CXX_FLAG_FAILED)
-
- if (${CXX_FLAG_FOUND} EQUAL -1 AND ${CXX_FLAG_FAILED} EQUAL -1)
- unset(CXX_FLAG_SUPPORTED CACHE)
- message("Checking CXX compiler flag support for: " ${cxx_flag})
- check_cxx_compiler_flag("${cxx_flag}" CXX_FLAG_SUPPORTED)
- if (${CXX_FLAG_SUPPORTED})
- string(APPEND CMAKE_CXX_FLAGS " ${cxx_flag}" CACHE STRING "")
- else()
- string(APPEND DRACO_FAILED_CXX_FLAGS " ${cxx_flag}" CACHE
- STRING "" FORCE)
- endif ()
- endif ()
-endmacro ()
-
-# Convenience method for adding a flag to both the C and C++ compiler command
-# lines.
-macro (add_compiler_flag_if_supported flag)
- add_c_flag_if_supported(${flag})
- add_cxx_flag_if_supported(${flag})
-endmacro ()
-
-# Checks C compiler for support of $c_flag and terminates generation when
-# support is not present.
-macro (require_c_flag c_flag update_c_flags)
- unset(C_FLAG_FOUND CACHE)
- string(FIND "${CMAKE_C_FLAGS}" "${c_flag}" C_FLAG_FOUND)
-
- if (${C_FLAG_FOUND} EQUAL -1)
- unset(HAVE_C_FLAG CACHE)
- message("Checking C compiler flag support for: " ${c_flag})
- check_c_compiler_flag("${c_flag}" HAVE_C_FLAG)
- if (NOT ${HAVE_C_FLAG})
- message(FATAL_ERROR
- "${PROJECT_NAME} requires support for C flag: ${c_flag}.")
- endif ()
- if (${update_c_flags})
- set(CMAKE_C_FLAGS "${c_flag} ${CMAKE_C_FLAGS}" CACHE STRING "" FORCE)
- endif ()
- endif ()
-endmacro ()
-
-# Checks CXX compiler for support of $cxx_flag and terminates generation when
-# support is not present.
-macro (require_cxx_flag cxx_flag update_cxx_flags)
- unset(CXX_FLAG_FOUND CACHE)
- string(FIND "${CMAKE_CXX_FLAGS}" "${cxx_flag}" CXX_FLAG_FOUND)
-
- if (${CXX_FLAG_FOUND} EQUAL -1)
- unset(HAVE_CXX_FLAG CACHE)
- message("Checking CXX compiler flag support for: " ${cxx_flag})
- check_cxx_compiler_flag("${cxx_flag}" HAVE_CXX_FLAG)
- if (NOT ${HAVE_CXX_FLAG})
- message(FATAL_ERROR
- "${PROJECT_NAME} requires support for CXX flag: ${cxx_flag}.")
- endif ()
- if (${update_cxx_flags})
- set(CMAKE_CXX_FLAGS "${cxx_flag} ${CMAKE_CXX_FLAGS}" CACHE STRING ""
- FORCE)
- endif ()
- endif ()
-endmacro ()
-
-# Checks for support of $flag by both the C and CXX compilers. Terminates
-# generation when support is not present in both compilers.
-macro (require_compiler_flag flag update_cmake_flags)
- require_c_flag(${flag} ${update_cmake_flags})
- require_cxx_flag(${flag} ${update_cmake_flags})
-endmacro ()
-
-# Checks only non-MSVC targets for support of $c_flag and terminates generation
-# when support is not present.
-macro (require_c_flag_nomsvc c_flag update_c_flags)
- if (NOT MSVC)
- require_c_flag(${c_flag} ${update_c_flags})
- endif ()
-endmacro ()
-
-# Checks only non-MSVC targets for support of $cxx_flag and terminates
-# generation when support is not present.
-macro (require_cxx_flag_nomsvc cxx_flag update_cxx_flags)
- if (NOT MSVC)
- require_cxx_flag(${cxx_flag} ${update_cxx_flags})
- endif ()
-endmacro ()
-
-# Checks only non-MSVC targets for support of $flag by both the C and CXX
-# compilers. Terminates generation when support is not present in both
-# compilers.
-macro (require_compiler_flag_nomsvc flag update_cmake_flags)
- require_c_flag_nomsvc(${flag} ${update_cmake_flags})
- require_cxx_flag_nomsvc(${flag} ${update_cmake_flags})
-endmacro ()
-
-# Adds $flag to assembler command line.
-macro (append_as_flag flag)
- unset(AS_FLAG_FOUND CACHE)
- string(FIND "${DRACO_AS_FLAGS}" "${flag}" AS_FLAG_FOUND)
-
- if (${AS_FLAG_FOUND} EQUAL -1)
- string(APPEND DRACO_AS_FLAGS " ${flag}")
- endif ()
-endmacro ()
-
-# Adds $flag to the C compiler command line.
-macro (append_c_flag flag)
- unset(C_FLAG_FOUND CACHE)
- string(FIND "${CMAKE_C_FLAGS}" "${flag}" C_FLAG_FOUND)
-
- if (${C_FLAG_FOUND} EQUAL -1)
- string(APPEND CMAKE_C_FLAGS " ${flag}")
- endif ()
-endmacro ()
-
-# Adds $flag to the CXX compiler command line.
-macro (append_cxx_flag flag)
- unset(CXX_FLAG_FOUND CACHE)
- string(FIND "${CMAKE_CXX_FLAGS}" "${flag}" CXX_FLAG_FOUND)
-
- if (${CXX_FLAG_FOUND} EQUAL -1)
- string(APPEND CMAKE_CXX_FLAGS " ${flag}")
- endif ()
-endmacro ()
-
-# Adds $flag to the C and CXX compiler command lines.
-macro (append_compiler_flag flag)
- append_c_flag(${flag})
- append_cxx_flag(${flag})
-endmacro ()
-
-# Adds $flag to the executable linker command line.
-macro (append_exe_linker_flag flag)
- unset(LINKER_FLAG_FOUND CACHE)
- string(FIND "${CMAKE_EXE_LINKER_FLAGS}" "${flag}" LINKER_FLAG_FOUND)
-
- if (${LINKER_FLAG_FOUND} EQUAL -1)
- string(APPEND CMAKE_EXE_LINKER_FLAGS " ${flag}")
- endif ()
-endmacro ()
-
-# Adds $flag to the link flags for $target.
-function (append_link_flag_to_target target flags)
- unset(target_link_flags)
- get_target_property(target_link_flags ${target} LINK_FLAGS)
-
- if (target_link_flags)
- unset(link_flag_found)
- string(FIND "${target_link_flags}" "${flags}" link_flag_found)
-
- if (NOT ${link_flag_found} EQUAL -1)
- return()
- endif ()
-
- string(APPEND target_link_flags " ${flags}")
- else ()
- set(target_link_flags "${flags}")
- endif ()
-
- set_target_properties(${target} PROPERTIES LINK_FLAGS ${target_link_flags})
-endfunction ()
-
-# Adds $flag to executable linker flags, and makes sure C/CXX builds still work.
-macro (require_linker_flag flag)
- append_exe_linker_flag(${flag})
-
- unset(c_passed)
- draco_check_c_compiles("LINKER_FLAG_C_TEST(${flag})" "" c_passed)
- unset(cxx_passed)
- draco_check_cxx_compiles("LINKER_FLAG_CXX_TEST(${flag})" "" cxx_passed)
-
- if (NOT c_passed OR NOT cxx_passed)
- message(FATAL_ERROR "Linker flag test for ${flag} failed.")
- endif ()
-endmacro ()
-
-endif () # DRACO_CMAKE_COMPILER_FLAGS_CMAKE_
diff --git a/extern/draco/dracoenc/cmake/compiler_tests.cmake b/extern/draco/dracoenc/cmake/compiler_tests.cmake
deleted file mode 100644
index 7cc3fbfc67d..00000000000
--- a/extern/draco/dracoenc/cmake/compiler_tests.cmake
+++ /dev/null
@@ -1,124 +0,0 @@
-if (NOT DRACO_CMAKE_COMPILER_TESTS_CMAKE_)
-set(DRACO_CMAKE_COMPILER_TESTS_CMAKE_ 1)
-
-include(CheckCSourceCompiles)
-include(CheckCXXSourceCompiles)
-
-# The basic main() macro used in all compile tests.
-set(DRACO_C_MAIN "\nint main(void) { return 0; }")
-set(DRACO_CXX_MAIN "\nint main() { return 0; }")
-
-# Strings containing the names of passed and failed tests.
-set(DRACO_C_PASSED_TESTS)
-set(DRACO_C_FAILED_TESTS)
-set(DRACO_CXX_PASSED_TESTS)
-set(DRACO_CXX_FAILED_TESTS)
-
-macro(draco_push_var var new_value)
- set(SAVED_${var} ${var})
- set(${var} ${new_value})
-endmacro ()
-
-macro(draco_pop_var var)
- set(var ${SAVED_${var}})
- unset(SAVED_${var})
-endmacro ()
-
-# Confirms $test_source compiles and stores $test_name in one of
-# $DRACO_C_PASSED_TESTS or $DRACO_C_FAILED_TESTS depending on out come. When the
-# test passes $result_var is set to 1. When it fails $result_var is unset.
-# The test is not run if the test name is found in either of the passed or
-# failed test variables.
-macro(draco_check_c_compiles test_name test_source result_var)
- unset(C_TEST_PASSED CACHE)
- unset(C_TEST_FAILED CACHE)
- string(FIND "${DRACO_C_PASSED_TESTS}" "${test_name}" C_TEST_PASSED)
- string(FIND "${DRACO_C_FAILED_TESTS}" "${test_name}" C_TEST_FAILED)
- if (${C_TEST_PASSED} EQUAL -1 AND ${C_TEST_FAILED} EQUAL -1)
- unset(C_TEST_COMPILED CACHE)
- message("Running C compiler test: ${test_name}")
- check_c_source_compiles("${test_source} ${DRACO_C_MAIN}" C_TEST_COMPILED)
- set(${result_var} ${C_TEST_COMPILED})
-
- if (${C_TEST_COMPILED})
- string(APPEND DRACO_C_PASSED_TESTS " ${test_name}")
- else ()
- string(APPEND DRACO_C_FAILED_TESTS " ${test_name}")
- message("C Compiler test ${test_name} failed.")
- endif ()
- elseif (NOT ${C_TEST_PASSED} EQUAL -1)
- set(${result_var} 1)
- else () # ${C_TEST_FAILED} NOT EQUAL -1
- unset(${result_var})
- endif ()
-endmacro ()
-
-# Confirms $test_source compiles and stores $test_name in one of
-# $DRACO_CXX_PASSED_TESTS or $DRACO_CXX_FAILED_TESTS depending on out come. When
-# the test passes $result_var is set to 1. When it fails $result_var is unset.
-# The test is not run if the test name is found in either of the passed or
-# failed test variables.
-macro(draco_check_cxx_compiles test_name test_source result_var)
- unset(CXX_TEST_PASSED CACHE)
- unset(CXX_TEST_FAILED CACHE)
- string(FIND "${DRACO_CXX_PASSED_TESTS}" "${test_name}" CXX_TEST_PASSED)
- string(FIND "${DRACO_CXX_FAILED_TESTS}" "${test_name}" CXX_TEST_FAILED)
- if (${CXX_TEST_PASSED} EQUAL -1 AND ${CXX_TEST_FAILED} EQUAL -1)
- unset(CXX_TEST_COMPILED CACHE)
- message("Running CXX compiler test: ${test_name}")
- check_cxx_source_compiles("${test_source} ${DRACO_CXX_MAIN}"
- CXX_TEST_COMPILED)
- set(${result_var} ${CXX_TEST_COMPILED})
-
- if (${CXX_TEST_COMPILED})
- string(APPEND DRACO_CXX_PASSED_TESTS " ${test_name}")
- else ()
- string(APPEND DRACO_CXX_FAILED_TESTS " ${test_name}")
- message("CXX Compiler test ${test_name} failed.")
- endif ()
- elseif (NOT ${CXX_TEST_PASSED} EQUAL -1)
- set(${result_var} 1)
- else () # ${CXX_TEST_FAILED} NOT EQUAL -1
- unset(${result_var})
- endif ()
-endmacro ()
-
-# Convenience macro that confirms $test_source compiles as C and C++.
-# $result_var is set to 1 when both tests are successful, and 0 when one or both
-# tests fail.
-# Note: This macro is intended to be used to write to result variables that
-# are expanded via configure_file(). $result_var is set to 1 or 0 to allow
-# direct usage of the value in generated source files.
-macro(draco_check_source_compiles test_name test_source result_var)
- unset(C_PASSED)
- unset(CXX_PASSED)
- draco_check_c_compiles(${test_name} ${test_source} C_PASSED)
- draco_check_cxx_compiles(${test_name} ${test_source} CXX_PASSED)
- if (${C_PASSED} AND ${CXX_PASSED})
- set(${result_var} 1)
- else ()
- set(${result_var} 0)
- endif ()
-endmacro ()
-
-# When inline support is detected for the current compiler the supported
-# inlining keyword is written to $result in caller scope.
-macro (draco_get_inline result)
- draco_check_source_compiles("inline_check_1"
- "static inline void macro(void) {}"
- HAVE_INLINE_1)
- if (HAVE_INLINE_1 EQUAL 1)
- set(${result} "inline")
- return()
- endif ()
-
- # Check __inline.
- draco_check_source_compiles("inline_check_2"
- "static __inline void macro(void) {}"
- HAVE_INLINE_2)
- if (HAVE_INLINE_2 EQUAL 1)
- set(${result} "__inline")
- endif ()
-endmacro ()
-
-endif () # DRACO_CMAKE_COMPILER_TESTS_CMAKE_
diff --git a/extern/draco/dracoenc/cmake/draco_features.cmake b/extern/draco/dracoenc/cmake/draco_features.cmake
deleted file mode 100644
index 057b0b07ecd..00000000000
--- a/extern/draco/dracoenc/cmake/draco_features.cmake
+++ /dev/null
@@ -1,57 +0,0 @@
-if (NOT DRACO_CMAKE_DRACO_FEATURES_CMAKE_)
-set(DRACO_CMAKE_DRACO_FEATURES_CMAKE_ 1)
-
-set(draco_features_file_name "${draco_build_dir}/draco/draco_features.h")
-set(draco_features_list)
-
-# Macro that handles tracking of Draco preprocessor symbols for the purpose of
-# producing draco_features.h.
-#
-# draco_enable_feature(FEATURE <feature_name> [TARGETS <target_name>])
-# FEATURE is required. It should be a Draco preprocessor symbol.
-# TARGETS is optional. It can be one or more draco targets.
-#
-# When the TARGETS argument is not present the preproc symbol is added to
-# draco_features.h. When it is draco_features.h is unchanged, and
-# target_compile_options() is called for each target specified.
-macro (draco_enable_feature)
- set(def_flags)
- set(def_single_arg_opts FEATURE)
- set(def_multi_arg_opts TARGETS)
- cmake_parse_arguments(DEF "${def_flags}" "${def_single_arg_opts}"
- "${def_multi_arg_opts}" ${ARGN})
- if ("${DEF_FEATURE}" STREQUAL "")
- message(FATAL_ERROR "Empty FEATURE passed to draco_enable_feature().")
- endif ()
-
- # Do nothing/return early if $DEF_FEATURE is already in the list.
- list(FIND draco_features_list ${DEF_FEATURE} df_index)
- if (NOT df_index EQUAL -1)
- return ()
- endif ()
-
- list(LENGTH DEF_TARGETS df_targets_list_length)
- if (${df_targets_list_length} EQUAL 0)
- list(APPEND draco_features_list ${DEF_FEATURE})
- else ()
- foreach (target ${DEF_TARGETS})
- target_compile_definitions(${target} PRIVATE ${DEF_FEATURE})
- endforeach ()
- endif ()
-endmacro ()
-
-# Function for generating draco_features.h.
-function (draco_generate_features_h)
- file(WRITE "${draco_features_file_name}"
- "// GENERATED FILE -- DO NOT EDIT\n\n"
- "#ifndef DRACO_FEATURES_H_\n"
- "#define DRACO_FEATURES_H_\n\n")
-
- foreach (feature ${draco_features_list})
- file(APPEND "${draco_features_file_name}" "#define ${feature}\n")
- endforeach ()
-
- file(APPEND "${draco_features_file_name}" "\n#endif // DRACO_FEATURES_H_")
-endfunction ()
-
-endif () # DRACO_CMAKE_DRACO_FEATURES_CMAKE_
diff --git a/extern/draco/dracoenc/cmake/draco_test_config.h.cmake b/extern/draco/dracoenc/cmake/draco_test_config.h.cmake
deleted file mode 100644
index 77a574123fd..00000000000
--- a/extern/draco/dracoenc/cmake/draco_test_config.h.cmake
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef DRACO_TESTING_DRACO_TEST_CONFIG_H_
-#define DRACO_TESTING_DRACO_TEST_CONFIG_H_
-
-// If this file is named draco_test_config.h.cmake:
-// This file is used as input at cmake generation time.
-
-// If this file is named draco_test_config.h:
-// GENERATED FILE, DO NOT EDIT. SEE ABOVE.
-
-#define DRACO_TEST_DATA_DIR "${DRACO_TEST_DATA_DIR}"
-#define DRACO_TEST_TEMP_DIR "${DRACO_TEST_TEMP_DIR}"
-
-#endif // DRACO_TESTING_DRACO_TEST_CONFIG_H_
diff --git a/extern/draco/dracoenc/cmake/draco_version.cc.cmake b/extern/draco/dracoenc/cmake/draco_version.cc.cmake
deleted file mode 100644
index 921df7de77d..00000000000
--- a/extern/draco/dracoenc/cmake/draco_version.cc.cmake
+++ /dev/null
@@ -1,21 +0,0 @@
-// If this file is named draco_version.cc.cmake:
-// This file is used as input at cmake generation time.
-
-// If this file is named draco_version.cc:
-// GENERATED FILE, DO NOT EDIT. SEE ABOVE.
-#include "draco_version.h"
-
-static const char kDracoGitHash[] = "${draco_git_hash}";
-static const char kDracoGitDesc[] = "${draco_git_desc}";
-
-const char *draco_git_hash() {
- return kDracoGitHash;
-}
-
-const char *draco_git_version() {
- return kDracoGitDesc;
-}
-
-const char* draco_version() {
- return draco::Version();
-}
diff --git a/extern/draco/dracoenc/cmake/draco_version.h.cmake b/extern/draco/dracoenc/cmake/draco_version.h.cmake
deleted file mode 100644
index 506423ed34c..00000000000
--- a/extern/draco/dracoenc/cmake/draco_version.h.cmake
+++ /dev/null
@@ -1,21 +0,0 @@
-// If this file is named draco_version.h.cmake:
-// This file is used as input at cmake generation time.
-
-// If this file is named draco_version.h:
-// GENERATED FILE, DO NOT EDIT. SEE ABOVE.
-#ifndef DRACO_DRACO_VERSION_H_
-#define DRACO_DRACO_VERSION_H_
-
-#include "draco/core/draco_version.h"
-
-// Returns git hash of Draco git repository.
-const char *draco_git_hash();
-
-// Returns the output of the git describe command when run from the Draco git
-// repository.
-const char *draco_git_version();
-
-// Returns the version string from core/draco_version.h.
-const char* draco_version();
-
-#endif // DRACO_DRACO_VERSION_H_
diff --git a/extern/draco/dracoenc/cmake/msvc_runtime.cmake b/extern/draco/dracoenc/cmake/msvc_runtime.cmake
deleted file mode 100644
index ca8de08f9a2..00000000000
--- a/extern/draco/dracoenc/cmake/msvc_runtime.cmake
+++ /dev/null
@@ -1,14 +0,0 @@
-cmake_minimum_required(VERSION 3.2)
-
-if (MSVC)
- # Use statically linked versions of the MS standard libraries.
- if (NOT "${MSVC_RUNTIME}" STREQUAL "dll")
- foreach (flag_var
- CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
- CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
- if (${flag_var} MATCHES "/MD")
- string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
- endif ()
- endforeach ()
- endif ()
-endif ()
diff --git a/extern/draco/dracoenc/cmake/sanitizers.cmake b/extern/draco/dracoenc/cmake/sanitizers.cmake
deleted file mode 100644
index e966cd85d52..00000000000
--- a/extern/draco/dracoenc/cmake/sanitizers.cmake
+++ /dev/null
@@ -1,19 +0,0 @@
-if (NOT DRACO_CMAKE_SANITIZERS_CMAKE_)
-set(DRACO_CMAKE_SANITIZERS_CMAKE_ 1)
-
-if (MSVC OR NOT SANITIZE)
- return ()
-endif ()
-
-include("${draco_root}/cmake/compiler_flags.cmake")
-
-string(TOLOWER ${SANITIZE} SANITIZE)
-
-# Require the sanitizer requested.
-require_linker_flag("-fsanitize=${SANITIZE}")
-require_compiler_flag("-fsanitize=${SANITIZE}" YES)
-
-# Make callstacks accurate.
-require_compiler_flag("-fno-omit-frame-pointer -fno-optimize-sibling-calls" YES)
-
-endif() # DRACO_CMAKE_SANITIZERS_CMAKE_
diff --git a/extern/draco/dracoenc/cmake/toolchains/arm-ios-common.cmake b/extern/draco/dracoenc/cmake/toolchains/arm-ios-common.cmake
deleted file mode 100644
index 48f5ce5e68c..00000000000
--- a/extern/draco/dracoenc/cmake/toolchains/arm-ios-common.cmake
+++ /dev/null
@@ -1,13 +0,0 @@
-if (NOT DRACO_CMAKE_TOOLCHAINS_ARM_IOS_COMMON_CMAKE_)
-set(DRACO_CMAKE_ARM_IOS_COMMON_CMAKE_ 1)
-
-set(CMAKE_SYSTEM_NAME "Darwin")
-set(CMAKE_OSX_SYSROOT iphoneos)
-set(CMAKE_C_COMPILER clang)
-set(CMAKE_C_COMPILER_ARG1 "-arch ${CMAKE_SYSTEM_PROCESSOR}")
-set(CMAKE_CXX_COMPILER clang++)
-set(CMAKE_CXX_COMPILER_ARG1 "-arch ${CMAKE_SYSTEM_PROCESSOR}")
-
-# TODO(tomfinegan): Handle bit code embedding.
-
-endif () # DRACO_CMAKE_TOOLCHAINS_ARM_IOS_COMMON_CMAKE_
diff --git a/extern/draco/dracoenc/cmake/toolchains/arm64-android-ndk-libcpp.cmake b/extern/draco/dracoenc/cmake/toolchains/arm64-android-ndk-libcpp.cmake
deleted file mode 100644
index bd044199063..00000000000
--- a/extern/draco/dracoenc/cmake/toolchains/arm64-android-ndk-libcpp.cmake
+++ /dev/null
@@ -1,12 +0,0 @@
-if (NOT DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_NDK_LIBCPP_CMAKE_)
-set(DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_NDK_LIBCPP_CMAKE_ 1)
-
-include("${CMAKE_CURRENT_LIST_DIR}/../util.cmake")
-
-set(CMAKE_SYSTEM_NAME Android)
-set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
-require_variable(CMAKE_ANDROID_NDK)
-set_variable_if_unset(CMAKE_SYSTEM_VERSION 21)
-set_variable_if_unset(CMAKE_ANDROID_STL_TYPE c++_static)
-
-endif () # DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_NDK_LIBCPP_CMAKE_
diff --git a/extern/draco/dracoenc/cmake/toolchains/arm64-ios.cmake b/extern/draco/dracoenc/cmake/toolchains/arm64-ios.cmake
deleted file mode 100644
index 0d4909e1be3..00000000000
--- a/extern/draco/dracoenc/cmake/toolchains/arm64-ios.cmake
+++ /dev/null
@@ -1,14 +0,0 @@
-if (NOT DRACO_CMAKE_TOOLCHAINS_ARM64_IOS_CMAKE_)
-set(DRACO_CMAKE_TOOLCHAINS_ARM64_IOS_CMAKE_ 1)
-
-if (XCODE)
- # TODO(tomfinegan): Handle arm builds in Xcode.
- message(FATAL_ERROR "This toolchain does not support Xcode.")
-endif ()
-
-set(CMAKE_SYSTEM_PROCESSOR "arm64")
-set(CMAKE_OSX_ARCHITECTURES "arm64")
-
-include("${CMAKE_CURRENT_LIST_DIR}/arm-ios-common.cmake")
-
-endif () # DRACO_CMAKE_TOOLCHAINS_ARM64_IOS_CMAKE_
diff --git a/extern/draco/dracoenc/cmake/toolchains/arm64-linux-gcc.cmake b/extern/draco/dracoenc/cmake/toolchains/arm64-linux-gcc.cmake
deleted file mode 100644
index 3bab482855c..00000000000
--- a/extern/draco/dracoenc/cmake/toolchains/arm64-linux-gcc.cmake
+++ /dev/null
@@ -1,18 +0,0 @@
-if (NOT DRACO_CMAKE_TOOLCHAINS_ARM64_LINUX_GCC_CMAKE_)
-set(DRACO_CMAKE_TOOLCHAINS_ARM64_LINUX_GCC_CMAKE_ 1)
-
-set(CMAKE_SYSTEM_NAME "Linux")
-
-if ("${CROSS}" STREQUAL "")
- # Default the cross compiler prefix to something known to work.
- set(CROSS aarch64-linux-gnu-)
-endif ()
-
-set(CMAKE_C_COMPILER ${CROSS}gcc)
-set(CMAKE_CXX_COMPILER ${CROSS}g++)
-set(AS_EXECUTABLE ${CROSS}as)
-set(CMAKE_C_COMPILER_ARG1 "-march=armv8-a")
-set(CMAKE_CXX_COMPILER_ARG1 "-march=armv8-a")
-set(CMAKE_SYSTEM_PROCESSOR "arm64")
-
-endif () # DRACO_CMAKE_TOOLCHAINS_ARM64_LINUX_GCC_CMAKE_
diff --git a/extern/draco/dracoenc/cmake/toolchains/armv7-android-ndk-libcpp.cmake b/extern/draco/dracoenc/cmake/toolchains/armv7-android-ndk-libcpp.cmake
deleted file mode 100644
index fd50defd82e..00000000000
--- a/extern/draco/dracoenc/cmake/toolchains/armv7-android-ndk-libcpp.cmake
+++ /dev/null
@@ -1,12 +0,0 @@
-if (NOT DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_NDK_LIBCPP_CMAKE_)
-set(DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_NDK_LIBCPP_CMAKE_ 1)
-
-include("${CMAKE_CURRENT_LIST_DIR}/../util.cmake")
-
-set(CMAKE_SYSTEM_NAME Android)
-set(CMAKE_ANDROID_ARCH_ABI armeabi-v7a)
-require_variable(CMAKE_ANDROID_NDK)
-set_variable_if_unset(CMAKE_SYSTEM_VERSION 18)
-set_variable_if_unset(CMAKE_ANDROID_STL_TYPE c++_static)
-
-endif () # DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_NDK_LIBCPP_CMAKE_
diff --git a/extern/draco/dracoenc/cmake/toolchains/armv7-ios.cmake b/extern/draco/dracoenc/cmake/toolchains/armv7-ios.cmake
deleted file mode 100644
index 61d67872917..00000000000
--- a/extern/draco/dracoenc/cmake/toolchains/armv7-ios.cmake
+++ /dev/null
@@ -1,14 +0,0 @@
-if (NOT DRACO_CMAKE_TOOLCHAINS_ARMV7_IOS_CMAKE_)
-set(DRACO_CMAKE_TOOLCHAINS_ARMV7_IOS_CMAKE_ 1)
-
-if (XCODE)
- # TODO(tomfinegan): Handle arm builds in Xcode.
- message(FATAL_ERROR "This toolchain does not support Xcode.")
-endif ()
-
-set(CMAKE_SYSTEM_PROCESSOR "armv7")
-set(CMAKE_OSX_ARCHITECTURES "armv7")
-
-include("${CMAKE_CURRENT_LIST_DIR}/arm-ios-common.cmake")
-
-endif () # DRACO_CMAKE_TOOLCHAINS_ARMV7_IOS_CMAKE_
diff --git a/extern/draco/dracoenc/cmake/toolchains/armv7-linux-gcc.cmake b/extern/draco/dracoenc/cmake/toolchains/armv7-linux-gcc.cmake
deleted file mode 100644
index e0f850f4270..00000000000
--- a/extern/draco/dracoenc/cmake/toolchains/armv7-linux-gcc.cmake
+++ /dev/null
@@ -1,24 +0,0 @@
-if (NOT DRACO_CMAKE_TOOLCHAINS_ARMV7_LINUX_GCC_CMAKE_)
-set(DRACO_CMAKE_TOOLCHAINS_ARMV7_LINUX_GCC_CMAKE_ 1)
-
-set(CMAKE_SYSTEM_NAME "Linux")
-
-if ("${CROSS}" STREQUAL "")
- # Default the cross compiler prefix to something known to work.
- set(CROSS arm-linux-gnueabihf-)
-endif ()
-
-if (NOT ${CROSS} MATCHES hf-$)
- set(DRACO_EXTRA_TOOLCHAIN_FLAGS "-mfloat-abi=softfp")
-endif ()
-
-set(CMAKE_C_COMPILER ${CROSS}gcc)
-set(CMAKE_CXX_COMPILER ${CROSS}g++)
-set(AS_EXECUTABLE ${CROSS}as)
-set(CMAKE_C_COMPILER_ARG1
- "-march=armv7-a -mfpu=neon ${DRACO_EXTRA_TOOLCHAIN_FLAGS}")
-set(CMAKE_CXX_COMPILER_ARG1
- "-march=armv7-a -mfpu=neon ${DRACO_EXTRA_TOOLCHAIN_FLAGS}")
-set(CMAKE_SYSTEM_PROCESSOR "armv7")
-
-endif () # DRACO_CMAKE_TOOLCHAINS_ARMV7_LINUX_GCC_CMAKE_
diff --git a/extern/draco/dracoenc/cmake/toolchains/armv7s-ios.cmake b/extern/draco/dracoenc/cmake/toolchains/armv7s-ios.cmake
deleted file mode 100644
index 45097936bcb..00000000000
--- a/extern/draco/dracoenc/cmake/toolchains/armv7s-ios.cmake
+++ /dev/null
@@ -1,14 +0,0 @@
-if (NOT DRACO_CMAKE_TOOLCHAINS_ARMV7S_IOS_CMAKE_)
-set(DRACO_CMAKE_TOOLCHAINS_ARMV7S_IOS_CMAKE_ 1)
-
-if (XCODE)
- # TODO(tomfinegan): Handle arm builds in Xcode.
- message(FATAL_ERROR "This toolchain does not support Xcode.")
-endif ()
-
-set(CMAKE_SYSTEM_PROCESSOR "armv7s")
-set(CMAKE_OSX_ARCHITECTURES "armv7s")
-
-include("${CMAKE_CURRENT_LIST_DIR}/arm-ios-common.cmake")
-
-endif () # DRACO_CMAKE_TOOLCHAINS_ARMV7S_IOS_CMAKE_
diff --git a/extern/draco/dracoenc/cmake/toolchains/x86-android-ndk-libcpp.cmake b/extern/draco/dracoenc/cmake/toolchains/x86-android-ndk-libcpp.cmake
deleted file mode 100644
index 7bb3717971f..00000000000
--- a/extern/draco/dracoenc/cmake/toolchains/x86-android-ndk-libcpp.cmake
+++ /dev/null
@@ -1,12 +0,0 @@
-if (NOT DRACO_CMAKE_TOOLCHAINS_X86_ANDROID_NDK_LIBCPP_CMAKE_)
-set(DRACO_CMAKE_TOOLCHAINS_X86_ANDROID_NDK_LIBCPP_CMAKE_ 1)
-
-include("${CMAKE_CURRENT_LIST_DIR}/../util.cmake")
-
-set(CMAKE_SYSTEM_NAME Android)
-set(CMAKE_ANDROID_ARCH_ABI x86)
-require_variable(CMAKE_ANDROID_NDK)
-set_variable_if_unset(CMAKE_SYSTEM_VERSION 18)
-set_variable_if_unset(CMAKE_ANDROID_STL_TYPE c++_static)
-
-endif () # DRACO_CMAKE_TOOLCHAINS_X86_ANDROID_NDK_LIBCPP_CMAKE_
diff --git a/extern/draco/dracoenc/cmake/toolchains/x86_64-android-ndk-libcpp.cmake b/extern/draco/dracoenc/cmake/toolchains/x86_64-android-ndk-libcpp.cmake
deleted file mode 100644
index 3b86b9d6682..00000000000
--- a/extern/draco/dracoenc/cmake/toolchains/x86_64-android-ndk-libcpp.cmake
+++ /dev/null
@@ -1,12 +0,0 @@
-if (NOT DRACO_CMAKE_TOOLCHAINS_X86_64_ANDROID_NDK_LIBCPP_CMAKE_)
-set(DRACO_CMAKE_TOOLCHAINS_X86_64_ANDROID_NDK_LIBCPP_CMAKE_ 1)
-
-include("${CMAKE_CURRENT_LIST_DIR}/../util.cmake")
-
-set(CMAKE_SYSTEM_NAME Android)
-set(CMAKE_ANDROID_ARCH_ABI x86_64)
-require_variable(CMAKE_ANDROID_NDK)
-set_variable_if_unset(CMAKE_SYSTEM_VERSION 21)
-set_variable_if_unset(CMAKE_ANDROID_STL_TYPE c++_static)
-
-endif () # DRACO_CMAKE_TOOLCHAINS_X86_64_ANDROID_NDK_LIBCPP_CMAKE_
diff --git a/extern/draco/dracoenc/cmake/util.cmake b/extern/draco/dracoenc/cmake/util.cmake
deleted file mode 100644
index d9254c03c03..00000000000
--- a/extern/draco/dracoenc/cmake/util.cmake
+++ /dev/null
@@ -1,73 +0,0 @@
-if (NOT DRACO_CMAKE_UTIL_CMAKE_)
-set(DRACO_CMAKE_UTIL_CMAKE_ 1)
-
-# Creates dummy source file in $draco_build_dir named $basename.$extension and
-# returns the full path to the dummy source file via the $out_file_path
-# parameter.
-function (create_dummy_source_file basename extension out_file_path)
- set(dummy_source_file "${draco_build_dir}/${basename}.${extension}")
- file(WRITE "${dummy_source_file}"
- "// Generated file. DO NOT EDIT!\n"
- "// ${target_name} needs a ${extension} file to force link language, \n"
- "// or to silence a harmless CMake warning: Ignore me.\n"
- "void ${target_name}_dummy_function(void) {}\n")
- set(${out_file_path} ${dummy_source_file} PARENT_SCOPE)
-endfunction ()
-
-# Convenience function for adding a dummy source file to $target_name using
-# $extension as the file extension. Wraps create_dummy_source_file().
-function (add_dummy_source_file_to_target target_name extension)
- create_dummy_source_file("${target_name}" "${extension}" "dummy_source_file")
- target_sources(${target_name} PRIVATE ${dummy_source_file})
-endfunction ()
-
-# Extracts the version number from $version_file and returns it to the user via
-# $version_string_out_var. This is achieved by finding the first instance of
-# the kDracoVersion variable and then removing everything but the string literal
-# assigned to the variable. Quotes and semicolon are stripped from the returned
-# string.
-function (extract_version_string version_file version_string_out_var)
- file(STRINGS "${version_file}" draco_version REGEX "kDracoVersion")
- list(GET draco_version 0 draco_version)
- string(REPLACE "static const char kDracoVersion[] = " "" draco_version
- "${draco_version}")
- string(REPLACE ";" "" draco_version "${draco_version}")
- string(REPLACE "\"" "" draco_version "${draco_version}")
- set("${version_string_out_var}" "${draco_version}" PARENT_SCOPE)
-endfunction ()
-
-# Sets CMake compiler launcher to $launcher_name when $launcher_name is found in
-# $PATH. Warns user about ignoring build flag $launcher_flag when $launcher_name
-# is not found in $PATH.
-function (set_compiler_launcher launcher_flag launcher_name)
- find_program(launcher_path "${launcher_name}")
- if (launcher_path)
- set(CMAKE_C_COMPILER_LAUNCHER "${launcher_path}" PARENT_SCOPE)
- set(CMAKE_CXX_COMPILER_LAUNCHER "${launcher_path}" PARENT_SCOPE)
- message("--- Using ${launcher_name} as compiler launcher.")
- else ()
- message(WARNING
- "--- Cannot find ${launcher_name}, ${launcher_flag} ignored.")
- endif ()
-endfunction ()
-
-# Terminates CMake execution when $var_name is unset in the environment. Sets
-# CMake variable to the value of the environment variable when the variable is
-# present in the environment.
-macro(require_variable var_name)
- if ("$ENV{${var_name}}" STREQUAL "")
- message(FATAL_ERROR "${var_name} must be set in environment.")
- endif ()
- set_variable_if_unset(${var_name} "")
-endmacro ()
-
-# Sets $var_name to $default_value if not already set in the environment.
-macro (set_variable_if_unset var_name default_value)
- if (NOT "$ENV{${var_name}}" STREQUAL "")
- set(${var_name} $ENV{${var_name}})
- else ()
- set(${var_name} ${default_value})
- endif ()
-endmacro ()
-
-endif() # DRACO_CMAKE_UTIL_CMAKE_
diff --git a/extern/draco/dracoenc/src/draco/animation/keyframe_animation_encoding_test.cc b/extern/draco/dracoenc/src/draco/animation/keyframe_animation_encoding_test.cc
deleted file mode 100644
index 4a6491f9d0d..00000000000
--- a/extern/draco/dracoenc/src/draco/animation/keyframe_animation_encoding_test.cc
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2017 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/animation/keyframe_animation.h"
-#include "draco/animation/keyframe_animation_decoder.h"
-#include "draco/animation/keyframe_animation_encoder.h"
-#include "draco/core/draco_test_base.h"
-#include "draco/core/draco_test_utils.h"
-
-namespace draco {
-
-class KeyframeAnimationEncodingTest : public ::testing::Test {
- protected:
- KeyframeAnimationEncodingTest() {}
-
- bool CreateAndAddTimestamps(int32_t num_frames) {
- timestamps_.resize(num_frames);
- for (int i = 0; i < timestamps_.size(); ++i)
- timestamps_[i] = static_cast<draco::KeyframeAnimation::TimestampType>(i);
- return keyframe_animation_.SetTimestamps(timestamps_);
- }
-
- int32_t CreateAndAddAnimationData(int32_t num_frames,
- uint32_t num_components) {
- // Create and add animation data with.
- animation_data_.resize(num_frames * num_components);
- for (int i = 0; i < animation_data_.size(); ++i)
- animation_data_[i] = static_cast<float>(i);
- return keyframe_animation_.AddKeyframes(draco::DT_FLOAT32, num_components,
- animation_data_);
- }
-
- template <int num_components_t>
- void CompareAnimationData(const KeyframeAnimation &animation0,
- const KeyframeAnimation &animation1,
- bool quantized) {
- ASSERT_EQ(animation0.num_frames(), animation1.num_frames());
- ASSERT_EQ(animation0.num_animations(), animation1.num_animations());
-
- if (quantized) {
- // TODO(hemmer) : Add test for stable quantization.
- // Quantization will result in slightly different values.
- // Skip comparing values.
- return;
- }
-
- // Compare time stamp.
- const auto timestamp_att0 = animation0.timestamps();
- const auto timestamp_att1 = animation0.timestamps();
- for (int i = 0; i < animation0.num_frames(); ++i) {
- std::array<float, 1> att_value0;
- std::array<float, 1> att_value1;
- ASSERT_TRUE((timestamp_att0->GetValue<float, 1>(
- draco::AttributeValueIndex(i), &att_value0)));
- ASSERT_TRUE((timestamp_att1->GetValue<float, 1>(
- draco::AttributeValueIndex(i), &att_value1)));
- ASSERT_FLOAT_EQ(att_value0[0], att_value1[0]);
- }
-
- for (int animation_id = 1; animation_id < animation0.num_animations();
- ++animation_id) {
- // Compare keyframe data.
- const auto keyframe_att0 = animation0.keyframes(animation_id);
- const auto keyframe_att1 = animation1.keyframes(animation_id);
- ASSERT_EQ(keyframe_att0->num_components(),
- keyframe_att1->num_components());
- for (int i = 0; i < animation0.num_frames(); ++i) {
- std::array<float, num_components_t> att_value0;
- std::array<float, num_components_t> att_value1;
- ASSERT_TRUE((keyframe_att0->GetValue<float, num_components_t>(
- draco::AttributeValueIndex(i), &att_value0)));
- ASSERT_TRUE((keyframe_att1->GetValue<float, num_components_t>(
- draco::AttributeValueIndex(i), &att_value1)));
- for (int j = 0; j < att_value0.size(); ++j) {
- ASSERT_FLOAT_EQ(att_value0[j], att_value1[j]);
- }
- }
- }
- }
-
- template <int num_components_t>
- void TestKeyframeAnimationEncoding() {
- TestKeyframeAnimationEncoding<num_components_t>(false);
- }
-
- template <int num_components_t>
- void TestKeyframeAnimationEncoding(bool quantized) {
- // Encode animation class.
- draco::EncoderBuffer buffer;
- draco::KeyframeAnimationEncoder encoder;
- EncoderOptions options = EncoderOptions::CreateDefaultOptions();
- if (quantized) {
- // Set quantization for timestamps.
- options.SetAttributeInt(0, "quantization_bits", 20);
- // Set quantization for keyframes.
- for (int i = 1; i <= keyframe_animation_.num_animations(); ++i) {
- options.SetAttributeInt(i, "quantization_bits", 20);
- }
- }
-
- ASSERT_TRUE(
- encoder.EncodeKeyframeAnimation(keyframe_animation_, options, &buffer)
- .ok());
-
- draco::DecoderBuffer dec_decoder;
- draco::KeyframeAnimationDecoder decoder;
- DecoderBuffer dec_buffer;
- dec_buffer.Init(buffer.data(), buffer.size());
-
- // Decode animation class.
- std::unique_ptr<KeyframeAnimation> decoded_animation(
- new KeyframeAnimation());
- DecoderOptions dec_options;
- ASSERT_TRUE(
- decoder.Decode(dec_options, &dec_buffer, decoded_animation.get()).ok());
-
- // Verify if animation before and after compression is identical.
- CompareAnimationData<num_components_t>(keyframe_animation_,
- *decoded_animation, quantized);
- }
-
- draco::KeyframeAnimation keyframe_animation_;
- std::vector<draco::KeyframeAnimation::TimestampType> timestamps_;
- std::vector<float> animation_data_;
-};
-
-TEST_F(KeyframeAnimationEncodingTest, OneComponent) {
- const int num_frames = 1;
- ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
- ASSERT_EQ(CreateAndAddAnimationData(num_frames, 1), 1);
- TestKeyframeAnimationEncoding<1>();
-}
-
-TEST_F(KeyframeAnimationEncodingTest, ManyComponents) {
- const int num_frames = 100;
- ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
- ASSERT_EQ(CreateAndAddAnimationData(num_frames, 100), 1);
- TestKeyframeAnimationEncoding<100>();
-}
-
-TEST_F(KeyframeAnimationEncodingTest, ManyComponentsWithQuantization) {
- const int num_frames = 100;
- ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
- ASSERT_EQ(CreateAndAddAnimationData(num_frames, 4), 1);
- // Test compression with quantization.
- TestKeyframeAnimationEncoding<4>(true);
-}
-
-TEST_F(KeyframeAnimationEncodingTest, MultipleAnimations) {
- const int num_frames = 5;
- ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
- ASSERT_EQ(CreateAndAddAnimationData(num_frames, 3), 1);
- ASSERT_EQ(CreateAndAddAnimationData(num_frames, 3), 2);
- TestKeyframeAnimationEncoding<3>();
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/animation/keyframe_animation_test.cc b/extern/draco/dracoenc/src/draco/animation/keyframe_animation_test.cc
deleted file mode 100644
index bc92b25ffc4..00000000000
--- a/extern/draco/dracoenc/src/draco/animation/keyframe_animation_test.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2017 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/animation/keyframe_animation.h"
-
-#include "draco/core/draco_test_base.h"
-
-namespace {
-
-class KeyframeAnimationTest : public ::testing::Test {
- protected:
- KeyframeAnimationTest() {}
-
- bool CreateAndAddTimestamps(int32_t num_frames) {
- timestamps_.resize(num_frames);
- for (int i = 0; i < timestamps_.size(); ++i)
- timestamps_[i] = static_cast<draco::KeyframeAnimation::TimestampType>(i);
- return keyframe_animation_.SetTimestamps(timestamps_);
- }
-
- int32_t CreateAndAddAnimationData(int32_t num_frames,
- uint32_t num_components) {
- // Create and add animation data with.
- animation_data_.resize(num_frames * num_components);
- for (int i = 0; i < animation_data_.size(); ++i)
- animation_data_[i] = static_cast<float>(i);
- return keyframe_animation_.AddKeyframes(draco::DT_FLOAT32, num_components,
- animation_data_);
- }
-
- template <int num_components_t>
- void CompareAnimationData() {
- // Compare time stamp.
- const auto timestamp_att = keyframe_animation_.timestamps();
- for (int i = 0; i < timestamps_.size(); ++i) {
- std::array<float, 1> att_value;
- ASSERT_TRUE((timestamp_att->GetValue<float, 1>(
- draco::AttributeValueIndex(i), &att_value)));
- ASSERT_FLOAT_EQ(att_value[0], i);
- }
-
- // Compare keyframe data.
- const auto keyframe_att = keyframe_animation_.keyframes(1);
- for (int i = 0; i < animation_data_.size() / num_components_t; ++i) {
- std::array<float, num_components_t> att_value;
- ASSERT_TRUE((keyframe_att->GetValue<float, num_components_t>(
- draco::AttributeValueIndex(i), &att_value)));
- for (int j = 0; j < num_components_t; ++j) {
- ASSERT_FLOAT_EQ(att_value[j], i * num_components_t + j);
- }
- }
- }
-
- template <int num_components_t>
- void TestKeyframeAnimation(int32_t num_frames) {
- ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
- ASSERT_EQ(CreateAndAddAnimationData(num_frames, num_components_t), 1);
- CompareAnimationData<num_components_t>();
- }
-
- draco::KeyframeAnimation keyframe_animation_;
- std::vector<draco::KeyframeAnimation::TimestampType> timestamps_;
- std::vector<float> animation_data_;
-};
-
-// Test animation with 1 component and 10 frames.
-TEST_F(KeyframeAnimationTest, OneComponent) { TestKeyframeAnimation<1>(10); }
-
-// Test animation with 4 component and 10 frames.
-TEST_F(KeyframeAnimationTest, FourComponent) { TestKeyframeAnimation<4>(10); }
-
-// Test adding animation data before timestamp.
-TEST_F(KeyframeAnimationTest, AddingAnimationFirst) {
- ASSERT_EQ(CreateAndAddAnimationData(5, 1), 1);
- ASSERT_TRUE(CreateAndAddTimestamps(5));
-}
-
-// Test adding timestamp more than once.
-TEST_F(KeyframeAnimationTest, ErrorAddingTimestampsTwice) {
- ASSERT_TRUE(CreateAndAddTimestamps(5));
- ASSERT_FALSE(CreateAndAddTimestamps(5));
-}
-// Test animation with multiple animation data.
-TEST_F(KeyframeAnimationTest, MultipleAnimationData) {
- const int num_frames = 5;
- ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
- ASSERT_EQ(CreateAndAddAnimationData(num_frames, 1), 1);
- ASSERT_EQ(CreateAndAddAnimationData(num_frames, 2), 2);
-}
-
-} // namespace
diff --git a/extern/draco/dracoenc/src/draco/attributes/point_attribute_test.cc b/extern/draco/dracoenc/src/draco/attributes/point_attribute_test.cc
deleted file mode 100644
index 183003abea4..00000000000
--- a/extern/draco/dracoenc/src/draco/attributes/point_attribute_test.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2017 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/attributes/point_attribute.h"
-
-#include "draco/core/draco_test_base.h"
-
-namespace {
-
-class PointAttributeTest : public ::testing::Test {
- protected:
- PointAttributeTest() {}
-};
-
-TEST_F(PointAttributeTest, TestCopy) {
- // This test verifies that PointAttribute can copy data from another point
- // attribute.
- draco::GeometryAttribute pos_att;
- pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 1, draco::DT_INT32,
- false, 4, 0);
- draco::PointAttribute pa(pos_att);
- pa.SetIdentityMapping();
- pa.Reset(10);
- for (int32_t i = 0; i < 10; ++i) {
- pa.SetAttributeValue(draco::AttributeValueIndex(i), &i);
- }
-
- draco::PointAttribute other_pa;
- other_pa.CopyFrom(pa);
-
- draco::PointAttributeHasher hasher;
- ASSERT_EQ(hasher(pa), hasher(other_pa));
-
- // The hash function does not actually compute the hash from attribute values,
- // so ensure the data got copied correctly as well.
- for (int32_t i = 0; i < 10; ++i) {
- int32_t data;
- other_pa.GetValue(draco::AttributeValueIndex(i), &data);
- ASSERT_EQ(data, i);
- }
-}
-
-TEST_F(PointAttributeTest, TestGetValueFloat) {
- draco::GeometryAttribute pos_att;
- pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 3,
- draco::DT_FLOAT32, false, 4, 0);
- draco::PointAttribute pa(pos_att);
- pa.SetIdentityMapping();
- pa.Reset(5);
- float points[3];
- for (int32_t i = 0; i < 5; ++i) {
- points[0] = i * 3.0;
- points[1] = (i * 3.0) + 1.0;
- points[2] = (i * 3.0) + 2.0;
- pa.SetAttributeValue(draco::AttributeValueIndex(i), &points);
- }
-
- for (int32_t i = 0; i < 5; ++i) {
- pa.GetValue(draco::AttributeValueIndex(i), &points);
- ASSERT_FLOAT_EQ(points[0], i * 3.0);
- ASSERT_FLOAT_EQ(points[1], (i * 3.0) + 1.0);
- ASSERT_FLOAT_EQ(points[2], (i * 3.0) + 2.0);
- }
-}
-
-TEST_F(PointAttributeTest, TestGetArray) {
- draco::GeometryAttribute pos_att;
- pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 3,
- draco::DT_FLOAT32, false, 4, 0);
- draco::PointAttribute pa(pos_att);
- pa.SetIdentityMapping();
- pa.Reset(5);
- float points[3];
- for (int32_t i = 0; i < 5; ++i) {
- points[0] = i * 3.0;
- points[1] = (i * 3.0) + 1.0;
- points[2] = (i * 3.0) + 2.0;
- pa.SetAttributeValue(draco::AttributeValueIndex(i), &points);
- }
-
- for (int32_t i = 0; i < 5; ++i) {
- std::array<float, 3> att_value;
- att_value = pa.GetValue<float, 3>(draco::AttributeValueIndex(i));
- ASSERT_FLOAT_EQ(att_value[0], i * 3.0);
- ASSERT_FLOAT_EQ(att_value[1], (i * 3.0) + 1.0);
- ASSERT_FLOAT_EQ(att_value[2], (i * 3.0) + 2.0);
- }
- for (int32_t i = 0; i < 5; ++i) {
- std::array<float, 3> att_value;
- EXPECT_TRUE(
- (pa.GetValue<float, 3>(draco::AttributeValueIndex(i), &att_value)));
- ASSERT_FLOAT_EQ(att_value[0], i * 3.0);
- ASSERT_FLOAT_EQ(att_value[1], (i * 3.0) + 1.0);
- ASSERT_FLOAT_EQ(att_value[2], (i * 3.0) + 2.0);
- }
-}
-
-TEST_F(PointAttributeTest, TestArrayReadError) {
- draco::GeometryAttribute pos_att;
- pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 3,
- draco::DT_FLOAT32, false, 4, 0);
- draco::PointAttribute pa(pos_att);
- pa.SetIdentityMapping();
- pa.Reset(5);
- float points[3];
- for (int32_t i = 0; i < 5; ++i) {
- points[0] = i * 3.0;
- points[1] = (i * 3.0) + 1.0;
- points[2] = (i * 3.0) + 2.0;
- pa.SetAttributeValue(draco::AttributeValueIndex(i), &points);
- }
-
- std::array<float, 3> att_value;
- EXPECT_FALSE(
- (pa.GetValue<float, 3>(draco::AttributeValueIndex(5), &att_value)));
-}
-
-} // namespace
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/point_d_vector_test.cc b/extern/draco/dracoenc/src/draco/compression/attributes/point_d_vector_test.cc
deleted file mode 100644
index bff10392c3d..00000000000
--- a/extern/draco/dracoenc/src/draco/compression/attributes/point_d_vector_test.cc
+++ /dev/null
@@ -1,359 +0,0 @@
-// Copyright 2018 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/compression/attributes/point_d_vector.h"
-#include "draco/compression/point_cloud/algorithms/point_cloud_types.h"
-#include "draco/core/draco_test_base.h"
-
-namespace draco {
-
-class PointDVectorTest : public ::testing::Test {
- protected:
- template <typename PT>
- void TestIntegrity() {}
- template <typename PT>
- void TestSize() {
- for (uint32_t n_items = 0; n_items <= 10; ++n_items) {
- for (uint32_t dimensionality = 1; dimensionality <= 10;
- ++dimensionality) {
- draco::PointDVector<PT> var(n_items, dimensionality);
- ASSERT_EQ(n_items, var.size());
- ASSERT_EQ(n_items * dimensionality, var.GetBufferSize());
- }
- }
- }
- template <typename PT>
- void TestContentsContiguous() {
- for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) {
- for (uint32_t dimensionality = 1; dimensionality < 10;
- dimensionality += 2) {
- for (uint32_t att_dimensionality = 1;
- att_dimensionality <= dimensionality; att_dimensionality += 2) {
- for (uint32_t offset_dimensionality = 0;
- offset_dimensionality < dimensionality - att_dimensionality;
- ++offset_dimensionality) {
- PointDVector<PT> var(n_items, dimensionality);
-
- std::vector<PT> att(n_items * att_dimensionality);
- for (PT val = 0; val < n_items; val += 1) {
- for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
- att[val * att_dimensionality + att_dim] = val;
- }
- }
- const PT *const attribute_data = att.data();
-
- var.CopyAttribute(att_dimensionality, offset_dimensionality,
- attribute_data);
-
- for (PT val = 0; val < n_items; val += 1) {
- for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
- ASSERT_EQ(var[val][offset_dimensionality + att_dim], val);
- }
- }
- }
- }
- }
- }
- }
- template <typename PT>
- void TestContentsDiscrete() {
- for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) {
- for (uint32_t dimensionality = 1; dimensionality < 10;
- dimensionality += 2) {
- for (uint32_t att_dimensionality = 1;
- att_dimensionality <= dimensionality; att_dimensionality += 2) {
- for (uint32_t offset_dimensionality = 0;
- offset_dimensionality < dimensionality - att_dimensionality;
- ++offset_dimensionality) {
- PointDVector<PT> var(n_items, dimensionality);
-
- std::vector<PT> att(n_items * att_dimensionality);
- for (PT val = 0; val < n_items; val += 1) {
- for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
- att[val * att_dimensionality + att_dim] = val;
- }
- }
- const PT *const attribute_data = att.data();
-
- for (PT item = 0; item < n_items; item += 1) {
- var.CopyAttribute(att_dimensionality, offset_dimensionality, item,
- attribute_data + item * att_dimensionality);
- }
-
- for (PT val = 0; val < n_items; val += 1) {
- for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
- ASSERT_EQ(var[val][offset_dimensionality + att_dim], val);
- }
- }
- }
- }
- }
- }
- }
-
- template <typename PT>
- void TestContentsCopy() {
- for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) {
- for (uint32_t dimensionality = 1; dimensionality < 10;
- dimensionality += 2) {
- for (uint32_t att_dimensionality = 1;
- att_dimensionality <= dimensionality; att_dimensionality += 2) {
- for (uint32_t offset_dimensionality = 0;
- offset_dimensionality < dimensionality - att_dimensionality;
- ++offset_dimensionality) {
- PointDVector<PT> var(n_items, dimensionality);
- PointDVector<PT> dest(n_items, dimensionality);
-
- std::vector<PT> att(n_items * att_dimensionality);
- for (PT val = 0; val < n_items; val += 1) {
- for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
- att[val * att_dimensionality + att_dim] = val;
- }
- }
- const PT *const attribute_data = att.data();
-
- var.CopyAttribute(att_dimensionality, offset_dimensionality,
- attribute_data);
-
- for (PT item = 0; item < n_items; item += 1) {
- dest.CopyItem(var, item, item);
- }
-
- for (PT val = 0; val < n_items; val += 1) {
- for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
- ASSERT_EQ(var[val][offset_dimensionality + att_dim], val);
- ASSERT_EQ(dest[val][offset_dimensionality + att_dim], val);
- }
- }
- }
- }
- }
- }
- }
- template <typename PT>
- void TestIterator() {
- for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) {
- for (uint32_t dimensionality = 1; dimensionality < 10;
- dimensionality += 2) {
- for (uint32_t att_dimensionality = 1;
- att_dimensionality <= dimensionality; att_dimensionality += 2) {
- for (uint32_t offset_dimensionality = 0;
- offset_dimensionality < dimensionality - att_dimensionality;
- ++offset_dimensionality) {
- PointDVector<PT> var(n_items, dimensionality);
- PointDVector<PT> dest(n_items, dimensionality);
-
- std::vector<PT> att(n_items * att_dimensionality);
- for (PT val = 0; val < n_items; val += 1) {
- for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
- att[val * att_dimensionality + att_dim] = val;
- }
- }
- const PT *const attribute_data = att.data();
-
- var.CopyAttribute(att_dimensionality, offset_dimensionality,
- attribute_data);
-
- for (PT item = 0; item < n_items; item += 1) {
- dest.CopyItem(var, item, item);
- }
-
- auto V0 = var.begin();
- auto VE = var.end();
- auto D0 = dest.begin();
- auto DE = dest.end();
-
- while (V0 != VE && D0 != DE) {
- ASSERT_EQ(*D0, *V0); // compare PseudoPointD
- // verify elemental values
- for (auto index = 0; index < dimensionality; index += 1) {
- ASSERT_EQ((*D0)[index], (*V0)[index]);
- }
- ++V0;
- ++D0;
- }
-
- for (PT val = 0; val < n_items; val += 1) {
- for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
- ASSERT_EQ(var[val][offset_dimensionality + att_dim], val);
- ASSERT_EQ(dest[val][offset_dimensionality + att_dim], val);
- }
- }
- }
- }
- }
- }
- }
- template <typename PT>
- void TestPoint3Iterator() {
- for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) {
- const uint32_t dimensionality = 3;
- // for (uint32_t dimensionality = 1; dimensionality < 10;
- // dimensionality += 2) {
- const uint32_t att_dimensionality = 3;
- // for (uint32_t att_dimensionality = 1;
- // att_dimensionality <= dimensionality; att_dimensionality += 2) {
- for (uint32_t offset_dimensionality = 0;
- offset_dimensionality < dimensionality - att_dimensionality;
- ++offset_dimensionality) {
- PointDVector<PT> var(n_items, dimensionality);
- PointDVector<PT> dest(n_items, dimensionality);
-
- std::vector<PT> att(n_items * att_dimensionality);
- std::vector<draco::Point3ui> att3(n_items);
- for (PT val = 0; val < n_items; val += 1) {
- att3[val][0] = val;
- att3[val][1] = val;
- att3[val][2] = val;
- for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
- att[val * att_dimensionality + att_dim] = val;
- }
- }
- const PT *const attribute_data = att.data();
-
- var.CopyAttribute(att_dimensionality, offset_dimensionality,
- attribute_data);
-
- for (PT item = 0; item < n_items; item += 1) {
- dest.CopyItem(var, item, item);
- }
-
- auto aV0 = att3.begin();
- auto aVE = att3.end();
- auto V0 = var.begin();
- auto VE = var.end();
- auto D0 = dest.begin();
- auto DE = dest.end();
-
- while (aV0 != aVE && V0 != VE && D0 != DE) {
- ASSERT_EQ(*D0, *V0); // compare PseudoPointD
- // verify elemental values
- for (auto index = 0; index < dimensionality; index += 1) {
- ASSERT_EQ((*D0)[index], (*V0)[index]);
- ASSERT_EQ((*D0)[index], (*aV0)[index]);
- ASSERT_EQ((*aV0)[index], (*V0)[index]);
- }
- ++aV0;
- ++V0;
- ++D0;
- }
-
- for (PT val = 0; val < n_items; val += 1) {
- for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
- ASSERT_EQ(var[val][offset_dimensionality + att_dim], val);
- ASSERT_EQ(dest[val][offset_dimensionality + att_dim], val);
- }
- }
- }
- }
- }
-
- void TestPseudoPointDSwap() {
- draco::Point3ui val = {0, 1, 2};
- draco::Point3ui dest = {10, 11, 12};
- draco::PseudoPointD<uint32_t> val_src1(&val[0], 3);
- draco::PseudoPointD<uint32_t> dest_src1(&dest[0], 3);
-
- ASSERT_EQ(val_src1[0], 0);
- ASSERT_EQ(val_src1[1], 1);
- ASSERT_EQ(val_src1[2], 2);
- ASSERT_EQ(dest_src1[0], 10);
- ASSERT_EQ(dest_src1[1], 11);
- ASSERT_EQ(dest_src1[2], 12);
-
- ASSERT_NE(val_src1, dest_src1);
-
- swap(val_src1, dest_src1);
-
- ASSERT_EQ(dest_src1[0], 0);
- ASSERT_EQ(dest_src1[1], 1);
- ASSERT_EQ(dest_src1[2], 2);
- ASSERT_EQ(val_src1[0], 10);
- ASSERT_EQ(val_src1[1], 11);
- ASSERT_EQ(val_src1[2], 12);
-
- ASSERT_NE(val_src1, dest_src1);
- }
- void TestPseudoPointDEquality() {
- draco::Point3ui val = {0, 1, 2};
- draco::Point3ui dest = {0, 1, 2};
- draco::PseudoPointD<uint32_t> val_src1(&val[0], 3);
- draco::PseudoPointD<uint32_t> val_src2(&val[0], 3);
- draco::PseudoPointD<uint32_t> dest_src1(&dest[0], 3);
- draco::PseudoPointD<uint32_t> dest_src2(&dest[0], 3);
-
- ASSERT_EQ(val_src1, val_src1);
- ASSERT_EQ(val_src1, val_src2);
- ASSERT_EQ(dest_src1, val_src1);
- ASSERT_EQ(dest_src1, val_src2);
- ASSERT_EQ(val_src2, val_src1);
- ASSERT_EQ(val_src2, val_src2);
- ASSERT_EQ(dest_src2, val_src1);
- ASSERT_EQ(dest_src2, val_src2);
-
- for (auto i = 0; i < 3; i++) {
- ASSERT_EQ(val_src1[i], val_src1[i]);
- ASSERT_EQ(val_src1[i], val_src2[i]);
- ASSERT_EQ(dest_src1[i], val_src1[i]);
- ASSERT_EQ(dest_src1[i], val_src2[i]);
- ASSERT_EQ(val_src2[i], val_src1[i]);
- ASSERT_EQ(val_src2[i], val_src2[i]);
- ASSERT_EQ(dest_src2[i], val_src1[i]);
- ASSERT_EQ(dest_src2[i], val_src2[i]);
- }
- }
- void TestPseudoPointDInequality() {
- draco::Point3ui val = {0, 1, 2};
- draco::Point3ui dest = {1, 2, 3};
- draco::PseudoPointD<uint32_t> val_src1(&val[0], 3);
- draco::PseudoPointD<uint32_t> val_src2(&val[0], 3);
- draco::PseudoPointD<uint32_t> dest_src1(&dest[0], 3);
- draco::PseudoPointD<uint32_t> dest_src2(&dest[0], 3);
-
- ASSERT_EQ(val_src1, val_src1);
- ASSERT_EQ(val_src1, val_src2);
- ASSERT_NE(dest_src1, val_src1);
- ASSERT_NE(dest_src1, val_src2);
- ASSERT_EQ(val_src2, val_src1);
- ASSERT_EQ(val_src2, val_src2);
- ASSERT_NE(dest_src2, val_src1);
- ASSERT_NE(dest_src2, val_src2);
-
- for (auto i = 0; i < 3; i++) {
- ASSERT_EQ(val_src1[i], val_src1[i]);
- ASSERT_EQ(val_src1[i], val_src2[i]);
- ASSERT_NE(dest_src1[i], val_src1[i]);
- ASSERT_NE(dest_src1[i], val_src2[i]);
- ASSERT_EQ(val_src2[i], val_src1[i]);
- ASSERT_EQ(val_src2[i], val_src2[i]);
- ASSERT_NE(dest_src2[i], val_src1[i]);
- ASSERT_NE(dest_src2[i], val_src2[i]);
- }
- }
-};
-
-TEST_F(PointDVectorTest, VectorTest) {
- TestSize<uint32_t>();
- TestContentsDiscrete<uint32_t>();
- TestContentsContiguous<uint32_t>();
- TestContentsCopy<uint32_t>();
- TestIterator<uint32_t>();
- TestPoint3Iterator<uint32_t>();
-}
-TEST_F(PointDVectorTest, PseudoPointDTest) {
- TestPseudoPointDSwap();
- TestPseudoPointDEquality();
- TestPseudoPointDInequality();
-}
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_test.cc b/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_test.cc
deleted file mode 100644
index 8c8932f77c3..00000000000
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_test.cc
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h"
-#include "draco/core/draco_test_base.h"
-
-namespace {
-
-class PredictionSchemeNormalOctahedronCanonicalizedTransformTest
- : public ::testing::Test {
- protected:
- typedef draco::PredictionSchemeNormalOctahedronCanonicalizedEncodingTransform<
- int32_t>
- Transform;
- typedef Transform::Point2 Point2;
-
- void TestComputeCorrection(const Transform &transform, const int32_t &ox,
- const int32_t &oy, const int32_t &px,
- const int32_t &py, const int32_t &cx,
- const int32_t &cy) {
- const int32_t o[2] = {ox + 7, oy + 7};
- const int32_t p[2] = {px + 7, py + 7};
- int32_t corr[2] = {500, 500};
- transform.ComputeCorrection(o, p, corr);
- ASSERT_EQ(corr[0], (cx + 15) % 15);
- ASSERT_EQ(corr[1], (cy + 15) % 15);
- }
-
- void TestGetRotationCount(const Transform &transform, const Point2 &pred,
- const int32_t &rot_dir) {
- const int32_t rotation_count = transform.GetRotationCount(pred);
- ASSERT_EQ(rot_dir, rotation_count);
- }
-
- void TestRotateRepresentation(const Transform &transform, const Point2 &org,
- const Point2 &pred, const Point2 &rot_org,
- const Point2 &rot_pred) {
- const int32_t rotation_count = transform.GetRotationCount(pred);
- const Point2 res_org = transform.RotatePoint(org, rotation_count);
- const Point2 res_pred = transform.RotatePoint(pred, rotation_count);
- ASSERT_EQ(rot_org[0], res_org[0]);
- ASSERT_EQ(rot_org[1], res_org[1]);
- ASSERT_EQ(rot_pred[0], res_pred[0]);
- ASSERT_EQ(rot_pred[1], res_pred[1]);
- }
-};
-
-TEST_F(PredictionSchemeNormalOctahedronCanonicalizedTransformTest, Init) {
- const Transform transform(15);
- ASSERT_TRUE(transform.AreCorrectionsPositive());
-}
-
-TEST_F(PredictionSchemeNormalOctahedronCanonicalizedTransformTest,
- IsInBottomLeft) {
- const Transform transform(15);
- ASSERT_TRUE(transform.IsInBottomLeft(Point2(0, 0)));
- ASSERT_TRUE(transform.IsInBottomLeft(Point2(-1, -1)));
- ASSERT_TRUE(transform.IsInBottomLeft(Point2(-7, -7)));
-
- ASSERT_FALSE(transform.IsInBottomLeft(Point2(1, 1)));
- ASSERT_FALSE(transform.IsInBottomLeft(Point2(7, 7)));
- ASSERT_FALSE(transform.IsInBottomLeft(Point2(-1, 1)));
- ASSERT_FALSE(transform.IsInBottomLeft(Point2(-7, 7)));
- ASSERT_FALSE(transform.IsInBottomLeft(Point2(1, -1)));
- ASSERT_FALSE(transform.IsInBottomLeft(Point2(7, -7)));
-}
-
-TEST_F(PredictionSchemeNormalOctahedronCanonicalizedTransformTest,
- GetRotationCount) {
- const Transform transform(15);
- TestGetRotationCount(transform, Point2(1, 2), 2); // top right
- TestGetRotationCount(transform, Point2(-1, 2), 3); // top left
- TestGetRotationCount(transform, Point2(1, -2), 1); // bottom right
- TestGetRotationCount(transform, Point2(-1, -2), 0); // bottom left
- TestGetRotationCount(transform, Point2(0, 2), 3); // top left
- TestGetRotationCount(transform, Point2(0, -2), 1); // bottom right
- TestGetRotationCount(transform, Point2(2, 0), 2); // top right
- TestGetRotationCount(transform, Point2(-2, 0), 0); // bottom left
- TestGetRotationCount(transform, Point2(0, 0), 0); // bottom left
-}
-
-TEST_F(PredictionSchemeNormalOctahedronCanonicalizedTransformTest,
- RotateRepresentation) {
- const Transform transform(15);
- // p top left; shift clockwise by 3
- TestRotateRepresentation(transform, Point2(1, 2), Point2(-3, 1),
- Point2(-2, 1), Point2(-1, -3)); // q top right
- TestRotateRepresentation(transform, Point2(-1, -2), Point2(-3, 1),
- Point2(2, -1), Point2(-1, -3)); // q bottom left
- TestRotateRepresentation(transform, Point2(1, -2), Point2(-3, 1),
- Point2(2, 1), Point2(-1, -3)); // q bottom right
- TestRotateRepresentation(transform, Point2(-1, 2), Point2(-3, 1),
- Point2(-2, -1), Point2(-1, -3)); // q top left
- // p top right; shift clockwise by 2 (flip)
- TestRotateRepresentation(transform, Point2(1, 1), Point2(1, 3),
- Point2(-1, -1), Point2(-1, -3)); // q top right
- TestRotateRepresentation(transform, Point2(-1, -2), Point2(1, 3),
- Point2(1, 2), Point2(-1, -3)); // q bottom left
- TestRotateRepresentation(transform, Point2(-1, 2), Point2(1, 3),
- Point2(1, -2), Point2(-1, -3)); // q top left
- TestRotateRepresentation(transform, Point2(1, -2), Point2(1, 3),
- Point2(-1, 2), Point2(-1, -3)); // q bottom right
- // p bottom right; shift clockwise by 1
- TestRotateRepresentation(transform, Point2(1, 2), Point2(3, -1),
- Point2(2, -1), Point2(-1, -3)); // q top right
- TestRotateRepresentation(transform, Point2(1, -2), Point2(3, -1),
- Point2(-2, -1), Point2(-1, -3)); // q bottom right
- TestRotateRepresentation(transform, Point2(-1, -2), Point2(3, -1),
- Point2(-2, 1), Point2(-1, -3)); // q bottom left
- TestRotateRepresentation(transform, Point2(-1, 2), Point2(3, -1),
- Point2(2, 1), Point2(-1, -3)); // q top left
- // p bottom left; no change
- TestRotateRepresentation(transform, Point2(1, 2), Point2(-1, -3),
- Point2(1, 2), Point2(-1, -3)); // q top right
- TestRotateRepresentation(transform, Point2(-1, 2), Point2(-1, -3),
- Point2(-1, 2), Point2(-1, -3)); // q top left
- TestRotateRepresentation(transform, Point2(1, -2), Point2(-1, -3),
- Point2(1, -2), Point2(-1, -3)); // q bottom right
- TestRotateRepresentation(transform, Point2(-1, -2), Point2(-1, -3),
- Point2(-1, -2), Point2(-1, -3)); // q bottom left
-}
-
-TEST_F(PredictionSchemeNormalOctahedronCanonicalizedTransformTest,
- ComputeCorrection) {
- const Transform transform(15);
- TestComputeCorrection(transform, 0, 0, 0, 0, 0, 0);
- TestComputeCorrection(transform, 1, 1, 1, 1, 0, 0);
- // inside diamond; p top right
- TestComputeCorrection(transform, 3, 4, 1, 2, -2, -2); // q top right
- TestComputeCorrection(transform, -3, 4, 1, 2, 4, -2); // q top left
- TestComputeCorrection(transform, 3, -4, 1, 2, -2, 6); // q bottom right
- TestComputeCorrection(transform, -3, -4, 1, 2, 4, 6); // q bottom left
- // inside diamond; p top left
- TestComputeCorrection(transform, 3, 4, -1, 2, -2, 4); // q top right
- TestComputeCorrection(transform, -3, 4, -1, 2, -2, -2); // q top left
- TestComputeCorrection(transform, 3, -4, -1, 2, 6, 4); // q bottom right
- TestComputeCorrection(transform, -3, -4, -1, 2, 6, -2); // q bottom left
- // inside diamond; p bottom right
- TestComputeCorrection(transform, 3, 4, 1, -2, 6, -2); // q top right
- TestComputeCorrection(transform, -3, 4, 1, -2, 6, 4); // q top left
- TestComputeCorrection(transform, 3, -4, 1, -2, -2, -2); // q bottom right
- TestComputeCorrection(transform, -3, -4, 1, -2, -2, 4); // q bottom left
- // inside diamond; p bottom left
- TestComputeCorrection(transform, 3, 4, -1, -2, 4, 6); // q top right
- TestComputeCorrection(transform, -3, 4, -1, -2, -2, 6); // q top left
- TestComputeCorrection(transform, 3, -4, -1, -2, 4, -2); // q bottom right
- TestComputeCorrection(transform, -3, -4, -1, -2, -2, -2); // q bottom left
- // outside diamond; p top right
- TestComputeCorrection(transform, 1, 2, 5, 4, -2, -4); // q top right
- TestComputeCorrection(transform, -1, 2, 5, 4, -7, -4); // q top left
- TestComputeCorrection(transform, 1, -2, 5, 4, -2, -7); // q bottom right
- TestComputeCorrection(transform, -1, -2, 5, 4, -7, -7); // q bottom left
- // outside diamond; p top left
- TestComputeCorrection(transform, 1, 2, -5, 4, -4, -7); // q top right
- TestComputeCorrection(transform, -1, 2, -5, 4, -4, -2); // q top left
- TestComputeCorrection(transform, 1, -2, -5, 4, -7, -7); // q bottom right
- TestComputeCorrection(transform, -1, -2, -5, 4, -7, -2); // q bottom left
- // outside diamond; p bottom right
- TestComputeCorrection(transform, 1, 2, 5, -4, -7, -2); // q top right
- TestComputeCorrection(transform, -1, 2, 5, -4, -7, -7); // q top left
- TestComputeCorrection(transform, 1, -2, 5, -4, -4, -2); // q bottom right
- TestComputeCorrection(transform, -1, -2, 5, -4, -4, -7); // q bottom left
- // outside diamond; p bottom left
- TestComputeCorrection(transform, 1, 2, -5, -4, -7, -7); // q top right
- TestComputeCorrection(transform, -1, 2, -5, -4, -2, -7); // q top left
- TestComputeCorrection(transform, 1, -2, -5, -4, -7, -4); // q bottom right
- TestComputeCorrection(transform, -1, -2, -5, -4, -2, -4); // q bottom left
-
- TestComputeCorrection(transform, -1, -2, 7, 7, -5, -6);
- TestComputeCorrection(transform, 0, 0, 7, 7, 7, 7);
- TestComputeCorrection(transform, -1, -2, 0, -2, 0, 1);
-}
-
-TEST_F(PredictionSchemeNormalOctahedronCanonicalizedTransformTest, Interface) {
- const Transform transform(15);
- ASSERT_EQ(transform.max_quantized_value(), 15);
- ASSERT_EQ(transform.center_value(), 7);
- ASSERT_EQ(transform.quantization_bits(), 4);
-}
-
-} // namespace
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_test.cc b/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_test.cc
deleted file mode 100644
index 1001b19fa50..00000000000
--- a/extern/draco/dracoenc/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_test.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h"
-#include "draco/core/draco_test_base.h"
-
-namespace {
-
-class PredictionSchemeNormalOctahedronTransformTest : public ::testing::Test {
- protected:
- typedef draco::PredictionSchemeNormalOctahedronEncodingTransform<int32_t>
- Transform;
- typedef Transform::Point2 Point2;
-
- void TestComputeCorrection(const Transform &transform, const int32_t &ox,
- const int32_t &oy, const int32_t &px,
- const int32_t &py, const int32_t &cx,
- const int32_t &cy) {
- const int32_t o[2] = {ox + 7, oy + 7};
- const int32_t p[2] = {px + 7, py + 7};
- int32_t corr[2] = {500, 500};
- transform.ComputeCorrection(o, p, corr);
- ASSERT_EQ(corr[0], (cx + 15) % 15);
- ASSERT_EQ(corr[1], (cy + 15) % 15);
- }
-};
-
-TEST_F(PredictionSchemeNormalOctahedronTransformTest, Init) {
- const Transform transform(15);
- ASSERT_TRUE(transform.AreCorrectionsPositive());
-}
-
-TEST_F(PredictionSchemeNormalOctahedronTransformTest, ComputeCorrections) {
- const Transform transform(15);
- // checks inside diamond
- TestComputeCorrection(transform, 0, 0, 0, 0, 0, 0);
- TestComputeCorrection(transform, 1, 1, 1, 1, 0, 0);
- TestComputeCorrection(transform, 3, 4, 1, 1, 2, 3);
- TestComputeCorrection(transform, -1, -1, -1, -1, 0, 0);
- TestComputeCorrection(transform, -3, -4, -1, -1, -2, -3);
- // checks outside diamond
- TestComputeCorrection(transform, 4, 4, 4, 4, 0, 0);
- TestComputeCorrection(transform, 5, 6, 4, 4, -2, -1);
- TestComputeCorrection(transform, 3, 2, 4, 4, 2, 1);
- // checks on outer edges
- TestComputeCorrection(transform, 7, 7, 4, 4, -3, -3);
- TestComputeCorrection(transform, 6, 7, 4, 4, -3, -2);
- TestComputeCorrection(transform, -6, 7, 4, 4, -3, -2);
- TestComputeCorrection(transform, 7, 6, 4, 4, -2, -3);
- TestComputeCorrection(transform, 7, -6, 4, 4, -2, -3);
-}
-
-TEST_F(PredictionSchemeNormalOctahedronTransformTest, Interface) {
- const Transform transform(15);
- ASSERT_EQ(transform.max_quantized_value(), 15);
- ASSERT_EQ(transform.center_value(), 7);
- ASSERT_EQ(transform.quantization_bits(), 4);
-}
-
-} // namespace
diff --git a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_integer_attribute_encoding_test.cc b/extern/draco/dracoenc/src/draco/compression/attributes/sequential_integer_attribute_encoding_test.cc
deleted file mode 100644
index d7b0cd25df6..00000000000
--- a/extern/draco/dracoenc/src/draco/compression/attributes/sequential_integer_attribute_encoding_test.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include <numeric>
-
-#include "draco/compression/attributes/sequential_integer_attribute_decoder.h"
-#include "draco/compression/attributes/sequential_integer_attribute_encoder.h"
-#include "draco/compression/config/compression_shared.h"
-#include "draco/core/draco_test_base.h"
-
-namespace draco {
-
-class SequentialIntegerAttributeEncodingTest : public ::testing::Test {
- protected:
-};
-
-TEST_F(SequentialIntegerAttributeEncodingTest, DoesCompress) {
- // This test verifies that IntegerEncoding encodes and decodes the given data.
- const std::vector<int32_t> values{1, 8, 7, 5, 5, 5, 9,
- 155, -6, -9, 9, 125, 1, 0};
- GeometryAttribute ga;
- PointAttribute pa;
- pa.Init(GeometryAttribute::GENERIC, nullptr, 1, DT_INT32, false, 4, 0);
- pa.Reset(values.size());
- pa.SetIdentityMapping();
- for (uint32_t i = 0; i < values.size(); ++i) {
- pa.SetAttributeValue(AttributeValueIndex(i), &values[i]);
- }
- // List of point ids from 0 to point_ids.size() - 1.
- std::vector<PointIndex> point_ids(values.size());
- std::iota(point_ids.begin(), point_ids.end(), 0);
-
- EncoderBuffer out_buf;
- SequentialIntegerAttributeEncoder ie;
- ASSERT_TRUE(ie.InitializeStandalone(&pa));
- ASSERT_TRUE(ie.TransformAttributeToPortableFormat(point_ids));
- ASSERT_TRUE(ie.EncodePortableAttribute(point_ids, &out_buf));
- ASSERT_TRUE(ie.EncodeDataNeededByPortableTransform(&out_buf));
-
- DecoderBuffer in_buf;
- in_buf.Init(out_buf.data(), out_buf.size());
- in_buf.set_bitstream_version(kDracoMeshBitstreamVersion);
- SequentialIntegerAttributeDecoder id;
- ASSERT_TRUE(id.InitializeStandalone(&pa));
- ASSERT_TRUE(id.DecodePortableAttribute(point_ids, &in_buf));
- ASSERT_TRUE(id.DecodeDataNeededByPortableTransform(point_ids, &in_buf));
- ASSERT_TRUE(id.TransformAttributeToOriginalFormat(point_ids));
-
- for (uint32_t i = 0; i < values.size(); ++i) {
- int32_t entry_val;
- pa.GetValue(AttributeValueIndex(i), &entry_val);
- ASSERT_EQ(entry_val, values[i]);
- }
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/compression/bit_coders/rans_coding_test.cc b/extern/draco/dracoenc/src/draco/compression/bit_coders/rans_coding_test.cc
deleted file mode 100644
index 9509ad9f354..00000000000
--- a/extern/draco/dracoenc/src/draco/compression/bit_coders/rans_coding_test.cc
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "draco/compression/bit_coders/adaptive_rans_bit_decoder.h"
-#include "draco/compression/bit_coders/adaptive_rans_bit_encoder.h"
-#include "draco/compression/bit_coders/rans_bit_decoder.h"
-#include "draco/compression/bit_coders/rans_bit_encoder.h"
-#include "draco/core/draco_test_base.h"
-
-// Just including rans_coding.h and adaptive_rans_coding.h gets an asan error
-// when compiling (blaze test :rans_coding_test --config=asan)
-TEST(RansCodingTest, LinkerTest) {}
diff --git a/extern/draco/dracoenc/src/draco/compression/config/decoder_options_test.cc b/extern/draco/dracoenc/src/draco/compression/config/decoder_options_test.cc
deleted file mode 100644
index a5cd7f10640..00000000000
--- a/extern/draco/dracoenc/src/draco/compression/config/decoder_options_test.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2017 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/compression/config/decoder_options.h"
-
-#include "draco/core/draco_test_base.h"
-
-namespace {
-
-class DecoderOptionsTest : public ::testing::Test {
- protected:
- DecoderOptionsTest() {}
-};
-
-TEST_F(DecoderOptionsTest, TestOptions) {
- // This test verifies that we can update global and attribute options of the
- // DecoderOptions class instance.
- draco::DecoderOptions options;
- options.SetGlobalInt("test", 3);
- ASSERT_EQ(options.GetGlobalInt("test", -1), 3);
-
- options.SetAttributeInt(draco::GeometryAttribute::POSITION, "test", 1);
- options.SetAttributeInt(draco::GeometryAttribute::GENERIC, "test", 2);
- ASSERT_EQ(
- options.GetAttributeInt(draco::GeometryAttribute::TEX_COORD, "test", -1),
- 3);
- ASSERT_EQ(
- options.GetAttributeInt(draco::GeometryAttribute::POSITION, "test", -1),
- 1);
- ASSERT_EQ(
- options.GetAttributeInt(draco::GeometryAttribute::GENERIC, "test", -1),
- 2);
-}
-
-TEST_F(DecoderOptionsTest, TestAttributeOptionsAccessors) {
- // This test verifies that we can query options stored in DecoderOptions
- // class instance.
- draco::DecoderOptions options;
- options.SetGlobalInt("test", 1);
- options.SetAttributeInt(draco::GeometryAttribute::POSITION, "test", 2);
- options.SetAttributeInt(draco::GeometryAttribute::TEX_COORD, "test", 3);
-
- ASSERT_EQ(
- options.GetAttributeInt(draco::GeometryAttribute::POSITION, "test", -1),
- 2);
- ASSERT_EQ(
- options.GetAttributeInt(draco::GeometryAttribute::POSITION, "test2", -1),
- -1);
- ASSERT_EQ(
- options.GetAttributeInt(draco::GeometryAttribute::TEX_COORD, "test", -1),
- 3);
- ASSERT_EQ(
- options.GetAttributeInt(draco::GeometryAttribute::NORMAL, "test", -1), 1);
-}
-
-} // namespace
diff --git a/extern/draco/dracoenc/src/draco/compression/decode_test.cc b/extern/draco/dracoenc/src/draco/compression/decode_test.cc
deleted file mode 100644
index c57542069dd..00000000000
--- a/extern/draco/dracoenc/src/draco/compression/decode_test.cc
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright 2017 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/compression/decode.h"
-
-#include <cinttypes>
-#include <fstream>
-#include <sstream>
-
-#include "draco/core/draco_test_base.h"
-#include "draco/core/draco_test_utils.h"
-
-namespace {
-
-class DecodeTest : public ::testing::Test {
- protected:
- DecodeTest() {}
-};
-
-#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
-TEST_F(DecodeTest, TestSkipAttributeTransform) {
- const std::string file_name = "test_nm_quant.0.9.0.drc";
- // Tests that decoders can successfully skip attribute transform.
- std::ifstream input_file(draco::GetTestFileFullPath(file_name),
- std::ios::binary);
- ASSERT_TRUE(input_file);
-
- // Read the file stream into a buffer.
- std::streampos file_size = 0;
- input_file.seekg(0, std::ios::end);
- file_size = input_file.tellg() - file_size;
- input_file.seekg(0, std::ios::beg);
- std::vector<char> data(file_size);
- input_file.read(data.data(), file_size);
-
- ASSERT_FALSE(data.empty());
-
- // Create a draco decoding buffer. Note that no data is copied in this step.
- draco::DecoderBuffer buffer;
- buffer.Init(data.data(), data.size());
-
- draco::Decoder decoder;
- // Make sure we skip dequantization for the position attribute.
- decoder.SetSkipAttributeTransform(draco::GeometryAttribute::POSITION);
-
- // Decode the input data into a geometry.
- std::unique_ptr<draco::PointCloud> pc =
- decoder.DecodePointCloudFromBuffer(&buffer).value();
- ASSERT_NE(pc, nullptr);
-
- const draco::PointAttribute *const pos_att =
- pc->GetNamedAttribute(draco::GeometryAttribute::POSITION);
- ASSERT_NE(pos_att, nullptr);
-
- // Ensure the position attribute is of type int32_t and that it has a valid
- // attribute transform.
- ASSERT_EQ(pos_att->data_type(), draco::DT_INT32);
- ASSERT_NE(pos_att->GetAttributeTransformData(), nullptr);
-
- // Normal attribute should be left transformed.
- const draco::PointAttribute *const norm_att =
- pc->GetNamedAttribute(draco::GeometryAttribute::NORMAL);
- ASSERT_EQ(norm_att->data_type(), draco::DT_FLOAT32);
- ASSERT_EQ(norm_att->GetAttributeTransformData(), nullptr);
-}
-#endif
-
-void TestSkipAttributeTransformOnPointCloudWithColor(const std::string &file) {
- std::ifstream input_file(draco::GetTestFileFullPath(file), std::ios::binary);
- ASSERT_TRUE(input_file);
-
- // Read the file stream into a buffer.
- std::streampos file_size = 0;
- input_file.seekg(0, std::ios::end);
- file_size = input_file.tellg() - file_size;
- input_file.seekg(0, std::ios::beg);
- std::vector<char> data(file_size);
- input_file.read(data.data(), file_size);
-
- ASSERT_FALSE(data.empty());
-
- // Create a draco decoding buffer. Note that no data is copied in this step.
- draco::DecoderBuffer buffer;
- buffer.Init(data.data(), data.size());
-
- draco::Decoder decoder;
- // Make sure we skip dequantization for the position attribute.
- decoder.SetSkipAttributeTransform(draco::GeometryAttribute::POSITION);
-
- // Decode the input data into a geometry.
- std::unique_ptr<draco::PointCloud> pc =
- decoder.DecodePointCloudFromBuffer(&buffer).value();
- ASSERT_NE(pc, nullptr);
-
- const draco::PointAttribute *const pos_att =
- pc->GetNamedAttribute(draco::GeometryAttribute::POSITION);
- ASSERT_NE(pos_att, nullptr);
-
- // Ensure the position attribute is of type int32_t or uint32_t and that it
- // has a valid attribute transform.
- ASSERT_TRUE(pos_att->data_type() == draco::DT_INT32 ||
- pos_att->data_type() == draco::DT_UINT32);
- ASSERT_NE(pos_att->GetAttributeTransformData(), nullptr);
-
- const draco::PointAttribute *const clr_att =
- pc->GetNamedAttribute(draco::GeometryAttribute::COLOR);
- ASSERT_EQ(clr_att->data_type(), draco::DT_UINT8);
-
- // Ensure the color attribute was decoded correctly. Perform the decoding
- // again without skipping the position dequantization and compare the
- // attribute values.
-
- draco::DecoderBuffer buffer_2;
- buffer_2.Init(data.data(), data.size());
-
- draco::Decoder decoder_2;
-
- // Decode the input data into a geometry.
- std::unique_ptr<draco::PointCloud> pc_2 =
- decoder_2.DecodePointCloudFromBuffer(&buffer_2).value();
- ASSERT_NE(pc_2, nullptr);
-
- const draco::PointAttribute *const clr_att_2 =
- pc_2->GetNamedAttribute(draco::GeometryAttribute::COLOR);
- ASSERT_NE(clr_att_2, nullptr);
- for (draco::PointIndex pi(0); pi < pc_2->num_points(); ++pi) {
- // Colors should be exactly the same for both cases.
- ASSERT_EQ(std::memcmp(clr_att->GetAddress(clr_att->mapped_index(pi)),
- clr_att_2->GetAddress(clr_att_2->mapped_index(pi)),
- clr_att->byte_stride()),
- 0);
- }
-}
-
-TEST_F(DecodeTest, TestSkipAttributeTransformOnPointCloud) {
- // Tests that decoders can successfully skip attribute transform on a point
- // cloud with multiple attributes encoded with one attributes encoder.
- TestSkipAttributeTransformOnPointCloudWithColor("pc_color.drc");
- TestSkipAttributeTransformOnPointCloudWithColor("pc_kd_color.drc");
-}
-
-TEST_F(DecodeTest, TestSkipAttributeTransformWithNoQuantization) {
- // Tests that decoders can successfully skip attribute transform even though
- // the input model was not quantized (it has no attribute transform).
- const std::string file_name = "point_cloud_no_qp.drc";
- std::ifstream input_file(draco::GetTestFileFullPath(file_name),
- std::ios::binary);
- ASSERT_TRUE(input_file);
-
- // Read the file stream into a buffer.
- std::streampos file_size = 0;
- input_file.seekg(0, std::ios::end);
- file_size = input_file.tellg() - file_size;
- input_file.seekg(0, std::ios::beg);
- std::vector<char> data(file_size);
- input_file.read(data.data(), file_size);
-
- ASSERT_FALSE(data.empty());
-
- // Create a draco decoding buffer. Note that no data is copied in this step.
- draco::DecoderBuffer buffer;
- buffer.Init(data.data(), data.size());
-
- draco::Decoder decoder;
- // Make sure we skip dequantization for the position attribute.
- decoder.SetSkipAttributeTransform(draco::GeometryAttribute::POSITION);
-
- // Decode the input data into a geometry.
- std::unique_ptr<draco::PointCloud> pc =
- decoder.DecodePointCloudFromBuffer(&buffer).value();
- ASSERT_NE(pc, nullptr);
-
- const draco::PointAttribute *const pos_att =
- pc->GetNamedAttribute(draco::GeometryAttribute::POSITION);
- ASSERT_NE(pos_att, nullptr);
-
- // Ensure the position attribute is of type float32 since the attribute was
- // not quantized.
- ASSERT_EQ(pos_att->data_type(), draco::DT_FLOAT32);
-
- // Make sure there is no attribute transform available for the attribute.
- ASSERT_EQ(pos_att->GetAttributeTransformData(), nullptr);
-}
-
-} // namespace
diff --git a/extern/draco/dracoenc/src/draco/compression/encode_test.cc b/extern/draco/dracoenc/src/draco/compression/encode_test.cc
deleted file mode 100644
index 2eadb73b343..00000000000
--- a/extern/draco/dracoenc/src/draco/compression/encode_test.cc
+++ /dev/null
@@ -1,293 +0,0 @@
-// Copyright 2017 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include <cinttypes>
-#include <fstream>
-#include <sstream>
-
-#include "draco/attributes/attribute_quantization_transform.h"
-#include "draco/compression/decode.h"
-#include "draco/compression/encode.h"
-#include "draco/compression/expert_encode.h"
-#include "draco/core/draco_test_base.h"
-#include "draco/core/draco_test_utils.h"
-#include "draco/core/vector_d.h"
-#include "draco/io/obj_decoder.h"
-#include "draco/mesh/triangle_soup_mesh_builder.h"
-#include "draco/point_cloud/point_cloud_builder.h"
-
-namespace {
-
-class EncodeTest : public ::testing::Test {
- protected:
- EncodeTest() {}
- std::unique_ptr<draco::Mesh> CreateTestMesh() const {
- draco::TriangleSoupMeshBuilder mesh_builder;
-
- // Create a simple mesh with one face.
- mesh_builder.Start(1);
-
- // Add one position attribute and two texture coordinate attributes.
- const int32_t pos_att_id = mesh_builder.AddAttribute(
- draco::GeometryAttribute::POSITION, 3, draco::DT_FLOAT32);
- const int32_t tex_att_id_0 = mesh_builder.AddAttribute(
- draco::GeometryAttribute::TEX_COORD, 2, draco::DT_FLOAT32);
- const int32_t tex_att_id_1 = mesh_builder.AddAttribute(
- draco::GeometryAttribute::TEX_COORD, 2, draco::DT_FLOAT32);
-
- // Initialize the attribute values.
- mesh_builder.SetAttributeValuesForFace(
- pos_att_id, draco::FaceIndex(0), draco::Vector3f(0.f, 0.f, 0.f).data(),
- draco::Vector3f(1.f, 0.f, 0.f).data(),
- draco::Vector3f(1.f, 1.f, 0.f).data());
- mesh_builder.SetAttributeValuesForFace(
- tex_att_id_0, draco::FaceIndex(0), draco::Vector2f(0.f, 0.f).data(),
- draco::Vector2f(1.f, 0.f).data(), draco::Vector2f(1.f, 1.f).data());
- mesh_builder.SetAttributeValuesForFace(
- tex_att_id_1, draco::FaceIndex(0), draco::Vector2f(0.f, 0.f).data(),
- draco::Vector2f(1.f, 0.f).data(), draco::Vector2f(1.f, 1.f).data());
-
- return mesh_builder.Finalize();
- }
-
- std::unique_ptr<draco::PointCloud> CreateTestPointCloud() const {
- draco::PointCloudBuilder pc_builder;
-
- constexpr int kNumPoints = 100;
- constexpr int kNumGenAttCoords0 = 4;
- constexpr int kNumGenAttCoords1 = 6;
- pc_builder.Start(kNumPoints);
-
- // Add one position attribute and two generic attributes.
- const int32_t pos_att_id = pc_builder.AddAttribute(
- draco::GeometryAttribute::POSITION, 3, draco::DT_FLOAT32);
- const int32_t gen_att_id_0 = pc_builder.AddAttribute(
- draco::GeometryAttribute::GENERIC, kNumGenAttCoords0, draco::DT_UINT32);
- const int32_t gen_att_id_1 = pc_builder.AddAttribute(
- draco::GeometryAttribute::GENERIC, kNumGenAttCoords1, draco::DT_UINT8);
-
- std::vector<uint32_t> gen_att_data_0(kNumGenAttCoords0);
- std::vector<uint32_t> gen_att_data_1(kNumGenAttCoords1);
-
- // Initialize the attribute values.
- for (draco::PointIndex i(0); i < kNumPoints; ++i) {
- const float pos_coord = static_cast<float>(i.value());
- pc_builder.SetAttributeValueForPoint(
- pos_att_id, i,
- draco::Vector3f(pos_coord, -pos_coord, pos_coord).data());
-
- for (int j = 0; j < kNumGenAttCoords0; ++j) {
- gen_att_data_0[j] = i.value();
- }
- pc_builder.SetAttributeValueForPoint(gen_att_id_0, i,
- gen_att_data_0.data());
-
- for (int j = 0; j < kNumGenAttCoords1; ++j) {
- gen_att_data_1[j] = -i.value();
- }
- pc_builder.SetAttributeValueForPoint(gen_att_id_1, i,
- gen_att_data_1.data());
- }
-
- return pc_builder.Finalize(false);
- }
-
- int GetQuantizationBitsFromAttribute(const draco::PointAttribute *att) const {
- if (att == nullptr)
- return -1;
- draco::AttributeQuantizationTransform transform;
- if (!transform.InitFromAttribute(*att))
- return -1;
- return transform.quantization_bits();
- }
-
- void VerifyNumQuantizationBits(const draco::EncoderBuffer &buffer,
- int pos_quantization,
- int tex_coord_0_quantization,
- int tex_coord_1_quantization) const {
- draco::Decoder decoder;
-
- // Skip the dequantization for the attributes which will allow us to get
- // the number of quantization bits used during encoding.
- decoder.SetSkipAttributeTransform(draco::GeometryAttribute::POSITION);
- decoder.SetSkipAttributeTransform(draco::GeometryAttribute::TEX_COORD);
-
- draco::DecoderBuffer in_buffer;
- in_buffer.Init(buffer.data(), buffer.size());
- auto mesh = decoder.DecodeMeshFromBuffer(&in_buffer).value();
- ASSERT_NE(mesh, nullptr);
- ASSERT_EQ(GetQuantizationBitsFromAttribute(mesh->attribute(0)),
- pos_quantization);
- ASSERT_EQ(GetQuantizationBitsFromAttribute(mesh->attribute(1)),
- tex_coord_0_quantization);
- ASSERT_EQ(GetQuantizationBitsFromAttribute(mesh->attribute(2)),
- tex_coord_1_quantization);
- }
-
- // Tests that the encoder returns the correct number of encoded points and
- // faces for a given mesh or point cloud.
- void TestNumberOfEncodedEntries(const std::string &file_name,
- int32_t encoding_method) {
- std::unique_ptr<draco::PointCloud> geometry;
- draco::Mesh *mesh = nullptr;
-
- if (encoding_method == draco::MESH_EDGEBREAKER_ENCODING ||
- encoding_method == draco::MESH_SEQUENTIAL_ENCODING) {
- std::unique_ptr<draco::Mesh> mesh_tmp =
- draco::ReadMeshFromTestFile(file_name);
- mesh = mesh_tmp.get();
- if (!mesh->DeduplicateAttributeValues())
- return;
- mesh->DeduplicatePointIds();
- geometry = std::move(mesh_tmp);
- } else {
- geometry = draco::ReadPointCloudFromTestFile(file_name);
- }
- ASSERT_NE(mesh, nullptr);
-
- draco::Encoder encoder;
- encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, 14);
- encoder.SetAttributeQuantization(draco::GeometryAttribute::TEX_COORD, 12);
- encoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL, 10);
-
- encoder.SetEncodingMethod(encoding_method);
-
- encoder.SetTrackEncodedProperties(true);
-
- draco::EncoderBuffer buffer;
- if (mesh) {
- encoder.EncodeMeshToBuffer(*mesh, &buffer);
- } else {
- encoder.EncodePointCloudToBuffer(*geometry, &buffer);
- }
-
- // Ensure the logged number of encoded points and faces matches the number
- // we get from the decoder.
-
- draco::DecoderBuffer decoder_buffer;
- decoder_buffer.Init(buffer.data(), buffer.size());
- draco::Decoder decoder;
-
- if (mesh) {
- auto maybe_mesh = decoder.DecodeMeshFromBuffer(&decoder_buffer);
- ASSERT_TRUE(maybe_mesh.ok());
- auto decoded_mesh = std::move(maybe_mesh).value();
- ASSERT_NE(decoded_mesh, nullptr);
- ASSERT_EQ(decoded_mesh->num_points(), encoder.num_encoded_points());
- ASSERT_EQ(decoded_mesh->num_faces(), encoder.num_encoded_faces());
- } else {
- auto maybe_pc = decoder.DecodePointCloudFromBuffer(&decoder_buffer);
- ASSERT_TRUE(maybe_pc.ok());
- auto decoded_pc = std::move(maybe_pc).value();
- ASSERT_EQ(decoded_pc->num_points(), encoder.num_encoded_points());
- }
- }
-};
-
-TEST_F(EncodeTest, TestExpertEncoderQuantization) {
- // This test verifies that the expert encoder can quantize individual
- // attributes even if they have the same type.
- auto mesh = CreateTestMesh();
- ASSERT_NE(mesh, nullptr);
-
- draco::ExpertEncoder encoder(*mesh.get());
- encoder.SetAttributeQuantization(0, 16); // Position quantization.
- encoder.SetAttributeQuantization(1, 15); // Tex-coord 0 quantization.
- encoder.SetAttributeQuantization(2, 14); // Tex-coord 1 quantization.
-
- draco::EncoderBuffer buffer;
- encoder.EncodeToBuffer(&buffer);
- VerifyNumQuantizationBits(buffer, 16, 15, 14);
-}
-
-TEST_F(EncodeTest, TestEncoderQuantization) {
- // This test verifies that Encoder applies the same quantization to all
- // attributes of the same type.
- auto mesh = CreateTestMesh();
- ASSERT_NE(mesh, nullptr);
-
- draco::Encoder encoder;
- encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, 16);
- encoder.SetAttributeQuantization(draco::GeometryAttribute::TEX_COORD, 15);
-
- draco::EncoderBuffer buffer;
- encoder.EncodeMeshToBuffer(*mesh.get(), &buffer);
- VerifyNumQuantizationBits(buffer, 16, 15, 15);
-}
-
-TEST_F(EncodeTest, TestLinesObj) {
- // This test verifies that Encoder can encode file that contains only line
- // segments (that are ignored).
- std::unique_ptr<draco::Mesh> mesh(
- draco::ReadMeshFromTestFile("test_lines.obj"));
- ASSERT_NE(mesh, nullptr);
- ASSERT_EQ(mesh->num_faces(), 0);
- std::unique_ptr<draco::PointCloud> pc(
- draco::ReadPointCloudFromTestFile("test_lines.obj"));
- ASSERT_NE(pc, nullptr);
-
- draco::Encoder encoder;
- encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, 16);
-
- draco::EncoderBuffer buffer;
- ASSERT_TRUE(encoder.EncodePointCloudToBuffer(*pc, &buffer).ok());
-}
-
-TEST_F(EncodeTest, TestKdTreeEncoding) {
- // This test verifies that the API can successfully encode a point cloud
- // defined by several attributes using the kd tree method.
- std::unique_ptr<draco::PointCloud> pc = CreateTestPointCloud();
- ASSERT_NE(pc, nullptr);
-
- draco::EncoderBuffer buffer;
- draco::Encoder encoder;
- encoder.SetEncodingMethod(draco::POINT_CLOUD_KD_TREE_ENCODING);
- // First try it without quantizing positions which should fail.
- ASSERT_FALSE(encoder.EncodePointCloudToBuffer(*pc, &buffer).ok());
-
- // Now set quantization for the position attribute which should make
- // the encoder happy.
- encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, 16);
- ASSERT_TRUE(encoder.EncodePointCloudToBuffer(*pc, &buffer).ok());
-}
-
-TEST_F(EncodeTest, TestTrackingOfNumberOfEncodedEntries) {
- TestNumberOfEncodedEntries("deg_faces.obj", draco::MESH_EDGEBREAKER_ENCODING);
- TestNumberOfEncodedEntries("deg_faces.obj", draco::MESH_SEQUENTIAL_ENCODING);
- TestNumberOfEncodedEntries("cube_att.obj", draco::MESH_EDGEBREAKER_ENCODING);
- TestNumberOfEncodedEntries("test_nm.obj", draco::MESH_EDGEBREAKER_ENCODING);
- TestNumberOfEncodedEntries("test_nm.obj", draco::MESH_SEQUENTIAL_ENCODING);
- TestNumberOfEncodedEntries("cube_subd.obj",
- draco::POINT_CLOUD_KD_TREE_ENCODING);
- TestNumberOfEncodedEntries("cube_subd.obj",
- draco::POINT_CLOUD_SEQUENTIAL_ENCODING);
-}
-
-TEST_F(EncodeTest, TestTrackingOfNumberOfEncodedEntriesNotSet) {
- // Tests that when tracing of encoded properties is disabled, the returned
- // number of encoded faces and points is 0.
- std::unique_ptr<draco::Mesh> mesh(
- draco::ReadMeshFromTestFile("cube_att.obj"));
- ASSERT_NE(mesh, nullptr);
-
- draco::EncoderBuffer buffer;
- draco::Encoder encoder;
-
- ASSERT_TRUE(encoder.EncodeMeshToBuffer(*mesh, &buffer).ok());
- ASSERT_EQ(encoder.num_encoded_points(), 0);
- ASSERT_EQ(encoder.num_encoded_faces(), 0);
-}
-
-} // namespace
diff --git a/extern/draco/dracoenc/src/draco/compression/entropy/shannon_entropy_test.cc b/extern/draco/dracoenc/src/draco/compression/entropy/shannon_entropy_test.cc
deleted file mode 100644
index c2fe64440be..00000000000
--- a/extern/draco/dracoenc/src/draco/compression/entropy/shannon_entropy_test.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-#include "draco/compression/entropy/shannon_entropy.h"
-#include "draco/core/draco_test_base.h"
-
-namespace {
-
-TEST(ShannonEntropyTest, TestBinaryEntropy) {
- // Test verifies that computing binary entropy works as expected.
- ASSERT_EQ(draco::ComputeBinaryShannonEntropy(0, 0), 0);
- ASSERT_EQ(draco::ComputeBinaryShannonEntropy(10, 0), 0);
- ASSERT_EQ(draco::ComputeBinaryShannonEntropy(10, 10), 0);
- ASSERT_NEAR(draco::ComputeBinaryShannonEntropy(10, 5), 1.0, 1e-4);
-}
-
-TEST(ShannonEntropyTest, TestStreamEntropy) {
- // Test verifies that the entropy of streamed data is computed correctly.
- const std::vector<uint32_t> symbols = {1, 5, 1, 100, 2, 1};
-
- draco::ShannonEntropyTracker entropy_tracker;
-
- // Nothing added, 0 entropy.
- ASSERT_EQ(entropy_tracker.GetNumberOfDataBits(), 0);
-
- // Try to push symbols one by one.
- uint32_t max_symbol = 0;
- for (int i = 0; i < symbols.size(); ++i) {
- if (symbols[i] > max_symbol)
- max_symbol = symbols[i];
- const auto entropy_data = entropy_tracker.Push(&symbols[i], 1);
-
- const int64_t stream_entropy_bits = entropy_tracker.GetNumberOfDataBits();
- // Ensure the returned entropy_data is in sync with the stream.
- ASSERT_EQ(draco::ShannonEntropyTracker::GetNumberOfDataBits(entropy_data),
- stream_entropy_bits);
-
- // Make sure the entropy is approximately the same as the one we compute
- // directly from all symbols.
- const int64_t expected_entropy_bits = draco::ComputeShannonEntropy(
- symbols.data(), i + 1, max_symbol, nullptr);
-
- // For now hardcoded tolerance of 2 bits.
- ASSERT_NEAR(expected_entropy_bits, stream_entropy_bits, 2);
- }
-
- // Compare it also to the case when we add all symbols in one call.
- draco::ShannonEntropyTracker entropy_tracker_2;
- entropy_tracker_2.Push(symbols.data(), symbols.size());
- const int64_t stream_2_entropy_bits = entropy_tracker_2.GetNumberOfDataBits();
- ASSERT_EQ(entropy_tracker.GetNumberOfDataBits(), stream_2_entropy_bits);
-
- // Ensure that peeking does not change the entropy.
- entropy_tracker_2.Peek(symbols.data(), 1);
-
- ASSERT_EQ(stream_2_entropy_bits, entropy_tracker_2.GetNumberOfDataBits());
-}
-
-} // namespace
diff --git a/extern/draco/dracoenc/src/draco/compression/entropy/symbol_coding_test.cc b/extern/draco/dracoenc/src/draco/compression/entropy/symbol_coding_test.cc
deleted file mode 100644
index ba7166bbe75..00000000000
--- a/extern/draco/dracoenc/src/draco/compression/entropy/symbol_coding_test.cc
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/compression/config/compression_shared.h"
-#include "draco/compression/entropy/symbol_decoding.h"
-#include "draco/compression/entropy/symbol_encoding.h"
-#include "draco/core/bit_utils.h"
-#include "draco/core/decoder_buffer.h"
-#include "draco/core/draco_test_base.h"
-#include "draco/core/encoder_buffer.h"
-
-namespace draco {
-
-class SymbolCodingTest : public ::testing::Test {
- protected:
- SymbolCodingTest() : bitstream_version_(kDracoMeshBitstreamVersion) {}
-
- template <class SignedIntTypeT>
- void TestConvertToSymbolAndBack(SignedIntTypeT x) {
- typedef typename std::make_unsigned<SignedIntTypeT>::type Symbol;
- Symbol symbol = ConvertSignedIntToSymbol(x);
- SignedIntTypeT y = ConvertSymbolToSignedInt(symbol);
- ASSERT_EQ(x, y);
- }
-
- uint16_t bitstream_version_;
-};
-
-TEST_F(SymbolCodingTest, TestLargeNumbers) {
- // This test verifies that SymbolCoding successfully encodes an array of large
- // numbers.
- const uint32_t in[] = {12345678, 1223333, 111, 5};
- const int num_values = sizeof(in) / sizeof(uint32_t);
- EncoderBuffer eb;
- ASSERT_TRUE(EncodeSymbols(in, num_values, 1, nullptr, &eb));
-
- std::vector<uint32_t> out;
- out.resize(num_values);
- DecoderBuffer db;
- db.Init(eb.data(), eb.size());
- db.set_bitstream_version(bitstream_version_);
- ASSERT_TRUE(DecodeSymbols(num_values, 1, &db, &out[0]));
- for (int i = 0; i < num_values; ++i) {
- EXPECT_EQ(in[i], out[i]);
- }
-}
-
-TEST_F(SymbolCodingTest, TestManyNumbers) {
- // This test verifies that SymbolCoding successfully encodes an array of
- // several numbers that repeat many times.
-
- // Value/frequency pairs.
- const std::pair<uint32_t, uint32_t> in[] = {
- {12, 1500}, {1025, 31000}, {7, 1}, {9, 5}, {0, 6432}};
-
- const int num_pairs = sizeof(in) / sizeof(std::pair<uint32_t, uint32_t>);
-
- std::vector<uint32_t> in_values;
- for (int i = 0; i < num_pairs; ++i) {
- in_values.insert(in_values.end(), in[i].second, in[i].first);
- }
- for (int method = 0; method < NUM_SYMBOL_CODING_METHODS; ++method) {
- // Test the encoding using all available symbol coding methods.
- Options options;
- SetSymbolEncodingMethod(&options, static_cast<SymbolCodingMethod>(method));
-
- EncoderBuffer eb;
- ASSERT_TRUE(
- EncodeSymbols(in_values.data(), in_values.size(), 1, &options, &eb));
- std::vector<uint32_t> out_values;
- out_values.resize(in_values.size());
- DecoderBuffer db;
- db.Init(eb.data(), eb.size());
- db.set_bitstream_version(bitstream_version_);
- ASSERT_TRUE(DecodeSymbols(in_values.size(), 1, &db, &out_values[0]));
- for (uint32_t i = 0; i < in_values.size(); ++i) {
- ASSERT_EQ(in_values[i], out_values[i]);
- }
- }
-}
-
-TEST_F(SymbolCodingTest, TestEmpty) {
- // This test verifies that SymbolCoding successfully encodes an empty array.
- EncoderBuffer eb;
- ASSERT_TRUE(EncodeSymbols(nullptr, 0, 1, nullptr, &eb));
- DecoderBuffer db;
- db.Init(eb.data(), eb.size());
- db.set_bitstream_version(bitstream_version_);
- ASSERT_TRUE(DecodeSymbols(0, 1, &db, nullptr));
-}
-
-TEST_F(SymbolCodingTest, TestOneSymbol) {
- // This test verifies that SymbolCoding successfully encodes an a single
- // symbol.
- EncoderBuffer eb;
- const std::vector<uint32_t> in(1200, 0);
- ASSERT_TRUE(EncodeSymbols(in.data(), in.size(), 1, nullptr, &eb));
-
- std::vector<uint32_t> out(in.size());
- DecoderBuffer db;
- db.Init(eb.data(), eb.size());
- db.set_bitstream_version(bitstream_version_);
- ASSERT_TRUE(DecodeSymbols(in.size(), 1, &db, &out[0]));
- for (uint32_t i = 0; i < in.size(); ++i) {
- ASSERT_EQ(in[i], out[i]);
- }
-}
-
-TEST_F(SymbolCodingTest, TestBitLengths) {
- // This test verifies that SymbolCoding successfully encodes symbols of
- // various bit lengths
- EncoderBuffer eb;
- std::vector<uint32_t> in;
- constexpr int bit_lengths = 18;
- for (int i = 0; i < bit_lengths; ++i) {
- in.push_back(1 << i);
- }
- std::vector<uint32_t> out(in.size());
- for (int i = 0; i < bit_lengths; ++i) {
- eb.Clear();
- ASSERT_TRUE(EncodeSymbols(in.data(), i + 1, 1, nullptr, &eb));
- DecoderBuffer db;
- db.Init(eb.data(), eb.size());
- db.set_bitstream_version(bitstream_version_);
- ASSERT_TRUE(DecodeSymbols(i + 1, 1, &db, &out[0]));
- for (int j = 0; j < i + 1; ++j) {
- ASSERT_EQ(in[j], out[j]);
- }
- }
-}
-
-TEST_F(SymbolCodingTest, TestLargeNumberCondition) {
- // This test verifies that SymbolCoding successfully encodes large symbols
- // that are on the boundary between raw scheme and tagged scheme (18 bits).
- EncoderBuffer eb;
- constexpr int num_symbols = 1000000;
- const std::vector<uint32_t> in(num_symbols, 1 << 18);
- ASSERT_TRUE(EncodeSymbols(in.data(), in.size(), 1, nullptr, &eb));
-
- std::vector<uint32_t> out(in.size());
- DecoderBuffer db;
- db.Init(eb.data(), eb.size());
- db.set_bitstream_version(bitstream_version_);
- ASSERT_TRUE(DecodeSymbols(in.size(), 1, &db, &out[0]));
- for (uint32_t i = 0; i < in.size(); ++i) {
- ASSERT_EQ(in[i], out[i]);
- }
-}
-
-TEST_F(SymbolCodingTest, TestConversionFullRange) {
- TestConvertToSymbolAndBack(static_cast<int8_t>(-128));
- TestConvertToSymbolAndBack(static_cast<int8_t>(-127));
- TestConvertToSymbolAndBack(static_cast<int8_t>(-1));
- TestConvertToSymbolAndBack(static_cast<int8_t>(0));
- TestConvertToSymbolAndBack(static_cast<int8_t>(1));
- TestConvertToSymbolAndBack(static_cast<int8_t>(127));
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_decoder_helpers.h b/extern/draco/dracoenc/src/draco/compression/mesh/mesh_decoder_helpers.h
deleted file mode 100644
index 12ac46b3698..00000000000
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_decoder_helpers.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#ifndef DRACO_COMPRESSION_MESH_MESH_DECODER_HELPERS_H_
-#define DRACO_COMPRESSION_MESH_MESH_DECODER_HELPERS_H_
-
-#include "draco/compression/mesh/mesh_decoder.h"
-
-namespace draco {
-
-// Function for decoding a stream previously encoded by a MeshEncoder. The
-// result is stored into a stream of single precision floating point numbers
-// in a XYZ|UV format, where one value is stored for every corner of each
-// triangle.
-// On error, the function sets the input stream "is" to an invalid state.
-template <typename InStreamT>
-InStreamT &DecodePos3Tex2DataFromStream(InStreamT &&is,
- std::vector<float> *out_data) {
- // Determine the size of the encoded data and write it into a vector.
- const auto start_pos = is.tellg();
- is.seekg(0, std::ios::end);
- const std::streampos is_size = is.tellg() - start_pos;
- is.seekg(start_pos);
- std::vector<char> data(is_size);
- is.read(&data[0], is_size);
-
- // Create a mesh from the data.
- std::unique_ptr<Mesh> mesh = draco::DecodeMesh(&data[0], data.size());
-
- if (mesh == nullptr) {
- is.setstate(ios_base::badbit);
- return is;
- }
-
- const PointAttribute *pos_att =
- mesh->GetNamedAttribute(GeometryAttribute::POSITION);
- const PointAttribute *tex_att =
- mesh->GetNamedAttribute(GeometryAttribute::TEX_COORD_0);
-
- // Both position and texture attributes must be present.
- if (pos_att == nullptr || tex_att == nullptr) {
- is.setstate(ios_base::badbit);
- return is;
- }
-
- // Copy the mesh data into the provided output.
- constexpr int data_stride = 5;
- // Prepare the output storage for 3 output values per face.
- out_data->resize(mesh->num_faces() * 3 * data_stride);
-
- std::array<float, 3> pos_val;
- std::array<float, 2> tex_val;
- int out_it = 0;
- for (int f = 0; f < mesh->num_faces(); ++f) {
- const Mesh::Face &face = mesh->face(f);
- for (int p = 0; p < 3; ++p) {
- pos_att->ConvertValue<float, 3>(pos_att->mapped_index(face[p]),
- &pos_val[0]);
- memcpy(&out_data->at(0) + out_it, &pos_val[0], sizeof(pos_val));
- out_it += 3;
- tex_att->ConvertValue<float, 2>(tex_att->mapped_index(face[p]),
- &tex_val[0]);
- memcpy(&out_data->at(0) + out_it, &tex_val[0], sizeof(tex_val));
- out_it += 2;
- }
- }
-
- return is;
-}
-
-} // namespace draco
-
-#endif // DRACO_COMPRESSION_MESH_MESH_DECODER_HELPERS_H_
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoding_test.cc b/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoding_test.cc
deleted file mode 100644
index 8313882455b..00000000000
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_edgebreaker_encoding_test.cc
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include <sstream>
-
-#include "draco/compression/encode.h"
-#include "draco/compression/mesh/mesh_edgebreaker_decoder.h"
-#include "draco/compression/mesh/mesh_edgebreaker_encoder.h"
-#include "draco/core/draco_test_base.h"
-#include "draco/core/draco_test_utils.h"
-#include "draco/io/mesh_io.h"
-#include "draco/io/obj_decoder.h"
-#include "draco/mesh/mesh_are_equivalent.h"
-#include "draco/mesh/mesh_cleanup.h"
-#include "draco/mesh/triangle_soup_mesh_builder.h"
-
-namespace draco {
-
-class MeshEdgebreakerEncodingTest : public ::testing::Test {
- protected:
- void TestFile(const std::string &file_name) { TestFile(file_name, -1); }
-
- void TestFile(const std::string &file_name, int compression_level) {
- const std::unique_ptr<Mesh> mesh(ReadMeshFromTestFile(file_name));
- ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
-
- TestMesh(mesh.get(), compression_level);
- }
-
- void TestMesh(Mesh *mesh, int compression_level) {
- EncoderBuffer buffer;
- MeshEdgebreakerEncoder encoder;
- EncoderOptions encoder_options = EncoderOptions::CreateDefaultOptions();
- encoder_options.SetSpeed(10 - compression_level, 10 - compression_level);
- encoder.SetMesh(*mesh);
- ASSERT_TRUE(encoder.Encode(encoder_options, &buffer).ok());
-
- DecoderBuffer dec_buffer;
- dec_buffer.Init(buffer.data(), buffer.size());
- MeshEdgebreakerDecoder decoder;
-
- std::unique_ptr<Mesh> decoded_mesh(new Mesh());
- DecoderOptions dec_options;
- ASSERT_TRUE(
- decoder.Decode(dec_options, &dec_buffer, decoded_mesh.get()).ok());
-
- // Cleanup the input mesh to make sure that input and output can be
- // compared (edgebreaker method discards degenerated triangles and isolated
- // vertices).
- const MeshCleanupOptions options;
- MeshCleanup cleanup;
- ASSERT_TRUE(cleanup(mesh, options)) << "Failed to clean the input mesh.";
-
- MeshAreEquivalent eq;
- ASSERT_TRUE(eq(*mesh, *decoded_mesh.get()))
- << "Decoded mesh is not the same as the input";
- }
-};
-
-TEST_F(MeshEdgebreakerEncodingTest, TestNmOBJ) {
- const std::string file_name = "test_nm.obj";
- TestFile(file_name);
-}
-
-TEST_F(MeshEdgebreakerEncodingTest, ThreeFacesOBJ) {
- const std::string file_name = "extra_vertex.obj";
- TestFile(file_name);
-}
-
-TEST_F(MeshEdgebreakerEncodingTest, TestPly) {
- // Tests whether the edgebreaker successfully encodes and decodes the test
- // file (ply with color).
- const std::string file_name = "test_pos_color.ply";
- TestFile(file_name);
-}
-
-TEST_F(MeshEdgebreakerEncodingTest, TestMultiAttributes) {
- // Tests encoding of model with many attributes.
- const std::string file_name = "cube_att.obj";
- TestFile(file_name, 10);
-}
-
-TEST_F(MeshEdgebreakerEncodingTest, TestEncoderReuse) {
- // Tests whether the edgebreaker encoder can be reused multiple times to
- // encode a given mesh.
- const std::string file_name = "test_pos_color.ply";
- const std::unique_ptr<Mesh> mesh(ReadMeshFromTestFile(file_name));
- ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
-
- MeshEdgebreakerEncoder encoder;
- EncoderOptions encoder_options = EncoderOptions::CreateDefaultOptions();
- encoder.SetMesh(*mesh);
- EncoderBuffer buffer_0, buffer_1;
- ASSERT_TRUE(encoder.Encode(encoder_options, &buffer_0).ok());
- ASSERT_TRUE(encoder.Encode(encoder_options, &buffer_1).ok());
-
- // Make sure both buffer are identical.
- ASSERT_EQ(buffer_0.size(), buffer_1.size());
- for (int i = 0; i < buffer_0.size(); ++i) {
- ASSERT_EQ(buffer_0.data()[i], buffer_1.data()[i]);
- }
-}
-
-TEST_F(MeshEdgebreakerEncodingTest, TestDecoderReuse) {
- // Tests whether the edgebreaker decoder can be reused multiple times to
- // decode a given mesh.
- const std::string file_name = "test_pos_color.ply";
- const std::unique_ptr<Mesh> mesh(ReadMeshFromTestFile(file_name));
- ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
-
- MeshEdgebreakerEncoder encoder;
- EncoderOptions encoder_options = EncoderOptions::CreateDefaultOptions();
- encoder.SetMesh(*mesh);
- EncoderBuffer buffer;
- ASSERT_TRUE(encoder.Encode(encoder_options, &buffer).ok());
-
- DecoderBuffer dec_buffer;
- dec_buffer.Init(buffer.data(), buffer.size());
-
- MeshEdgebreakerDecoder decoder;
-
- // Decode the mesh two times.
- std::unique_ptr<Mesh> decoded_mesh_0(new Mesh());
- DecoderOptions dec_options;
- ASSERT_TRUE(
- decoder.Decode(dec_options, &dec_buffer, decoded_mesh_0.get()).ok());
-
- dec_buffer.Init(buffer.data(), buffer.size());
- std::unique_ptr<Mesh> decoded_mesh_1(new Mesh());
- ASSERT_TRUE(
- decoder.Decode(dec_options, &dec_buffer, decoded_mesh_1.get()).ok());
-
- // Make sure both of the meshes are identical.
- MeshAreEquivalent eq;
- ASSERT_TRUE(eq(*decoded_mesh_0.get(), *decoded_mesh_1.get()))
- << "Decoded meshes are not the same";
-}
-
-TEST_F(MeshEdgebreakerEncodingTest, TestSingleConnectivityEncoding) {
- // Tests whether the edgebreaker method successfully encodes a mesh with
- // multiple attributes using single connectivity by breaking the mesh along
- // attribute seams.
- const std::string file_name = "cube_att.obj";
- const std::unique_ptr<Mesh> mesh(ReadMeshFromTestFile(file_name));
- ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
-
- for (int i = 0; i < 2; ++i) {
- // Set the option to enable/disable single connectivity encoding.
- EncoderOptionsBase<GeometryAttribute::Type> options =
- EncoderOptionsBase<GeometryAttribute::Type>::CreateDefaultOptions();
- options.SetGlobalBool("split_mesh_on_seams", i == 0 ? true : false);
-
- EncoderBuffer buffer;
- draco::Encoder encoder;
- encoder.Reset(options);
- encoder.SetSpeedOptions(0, 0);
- encoder.SetAttributeQuantization(GeometryAttribute::POSITION, 8);
- encoder.SetAttributeQuantization(GeometryAttribute::TEX_COORD, 8);
- encoder.SetAttributeQuantization(GeometryAttribute::NORMAL, 8);
- encoder.SetEncodingMethod(MESH_EDGEBREAKER_ENCODING);
- ASSERT_TRUE(encoder.EncodeMeshToBuffer(*mesh, &buffer).ok());
-
- DecoderBuffer dec_buffer;
- dec_buffer.Init(buffer.data(), buffer.size());
-
- Decoder decoder;
- auto dec_mesh = decoder.DecodeMeshFromBuffer(&dec_buffer).value();
- ASSERT_NE(dec_mesh, nullptr);
- ASSERT_EQ(dec_mesh->num_points(), 24);
- ASSERT_EQ(dec_mesh->num_attributes(), 3);
- ASSERT_EQ(dec_mesh->attribute(0)->size(), i == 0 ? 24 : 8);
- ASSERT_EQ(dec_mesh->attribute(1)->size(), 24);
- ASSERT_EQ(dec_mesh->attribute(2)->size(), 24);
- }
-}
-
-TEST_F(MeshEdgebreakerEncodingTest, TestWrongAttributeOrder) {
- // Tests whether the edgebreaker method successfully encodes a mesh where the
- // input attributes are in wrong order (because of their internal
- // dependencies). In such case the attributes should be rearranged to the
- // correct order.
- TriangleSoupMeshBuilder mb;
- mb.Start(1);
- const int32_t norm_att_id =
- mb.AddAttribute(GeometryAttribute::NORMAL, 3, DT_FLOAT32);
- const int32_t pos_att_id =
- mb.AddAttribute(GeometryAttribute::POSITION, 3, DT_FLOAT32);
-
- mb.SetAttributeValuesForFace(
- pos_att_id, FaceIndex(0), Vector3f(0.f, 0.f, 0.f).data(),
- Vector3f(1.f, 0.f, 0.f).data(), Vector3f(0.f, 1.f, 0.f).data());
-
- mb.SetAttributeValuesForFace(
- norm_att_id, FaceIndex(0), Vector3f(0.f, 0.f, 1.f).data(),
- Vector3f(0.f, 0.f, 0.f).data(), Vector3f(0.f, 0.f, 1.f).data());
- std::unique_ptr<Mesh> mesh = mb.Finalize();
- ASSERT_NE(mesh, nullptr);
- ASSERT_EQ(mesh->num_attributes(), 2);
- ASSERT_EQ(mesh->attribute(0)->attribute_type(), GeometryAttribute::NORMAL);
- ASSERT_EQ(mesh->attribute(1)->attribute_type(), GeometryAttribute::POSITION);
-
- EncoderBuffer buffer;
- draco::Encoder encoder;
- encoder.SetSpeedOptions(3, 3);
- encoder.SetAttributeQuantization(GeometryAttribute::POSITION, 8);
- encoder.SetAttributeQuantization(GeometryAttribute::NORMAL, 8);
- encoder.SetEncodingMethod(MESH_EDGEBREAKER_ENCODING);
- ASSERT_TRUE(encoder.EncodeMeshToBuffer(*mesh, &buffer).ok());
-
- DecoderBuffer dec_buffer;
- dec_buffer.Init(buffer.data(), buffer.size());
-
- Decoder decoder;
- auto dec_mesh = decoder.DecodeMeshFromBuffer(&dec_buffer).value();
- ASSERT_NE(dec_mesh, nullptr);
- ASSERT_EQ(dec_mesh->num_attributes(), 2);
- ASSERT_EQ(dec_mesh->attribute(0)->attribute_type(),
- GeometryAttribute::POSITION);
- ASSERT_EQ(dec_mesh->attribute(1)->attribute_type(),
- GeometryAttribute::NORMAL);
-}
-
-TEST_F(MeshEdgebreakerEncodingTest, TestDegenerateMesh) {
- // Tests whether we can process a mesh that contains degenerate faces only.
- const std::string file_name = "degenerate_mesh.obj";
- const std::unique_ptr<Mesh> mesh(ReadMeshFromTestFile(file_name));
- ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
- EncoderBuffer buffer;
- MeshEdgebreakerEncoder encoder;
- EncoderOptions encoder_options = EncoderOptions::CreateDefaultOptions();
- encoder.SetMesh(*mesh);
- // We expect the encoding to fail as edgebreaker can only process valid faces.
- ASSERT_FALSE(encoder.Encode(encoder_options, &buffer).ok());
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_encoder_helpers.h b/extern/draco/dracoenc/src/draco/compression/mesh/mesh_encoder_helpers.h
deleted file mode 100644
index d809a521369..00000000000
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_encoder_helpers.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#ifndef DRACO_COMPRESSION_MESH_MESH_ENCODER_HELPERS_H_
-#define DRACO_COMPRESSION_MESH_MESH_ENCODER_HELPERS_H_
-
-#include "draco/compression/mesh/mesh_encoder.h"
-#include "draco/mesh/triangle_soup_mesh_builder.h"
-
-namespace draco {
-
-// Helper class for encoding data supplied in a stream of single precision
-// floating point numbers formatted as XYZ|UV. The stream must contain three
-// XYZ|UV values for every face of the mesh.
-// The encoded data is written into the output stream "os".
-// In case of error, the stream is set to an invalid state (ios_base::bad_bit).
-template <typename OStreamT>
-OStreamT EncodePos3Tex2DataToStream(
- const float *data, int num_faces, CompressionMethod method,
- const MeshCompressionOptions &compression_options,
- const MeshAttributeCompressionOptions &pos_options,
- const MeshAttributeCompressionOptions &tex_options, OStreamT &&os) {
- // Build the mesh.
- TriangleSoupMeshBuilder mb;
- mb.Start(num_faces);
- const int pos_att_id =
- mb.AddAttribute(GeometryAttribute::POSITION, 3, DT_FLOAT32);
- const int tex_att_id =
- mb.AddAttribute(GeometryAttribute::TEX_COORD_0, 2, DT_FLOAT32);
- constexpr int data_stride = 5;
- constexpr int tex_offset = 3;
- for (int f = 0; f < num_faces; ++f) {
- int offset = 3 * f * data_stride;
- // Add position data for the face.
- mb.SetAttributeValuesForFace(pos_att_id, f, data + offset,
- data + offset + data_stride,
- data + offset + 2 * data_stride);
- // Add texture data for the face.
- offset += tex_offset;
- mb.SetAttributeValuesForFace(tex_att_id, f, data + offset,
- data + offset + data_stride,
- data + offset + 2 * data_stride);
- }
- std::unique_ptr<Mesh> mesh = mb.Finalize();
- if (mesh == nullptr) {
- os.setstate(ios_base::badbit);
- return os;
- }
-
- // Set up the encoder.
- std::unique_ptr<MeshEncoder> encoder =
- MeshEncoder::CreateEncoderForMethod(method);
- encoder->SetGlobalOptions(compression_options);
- encoder->SetAttributeOptions(GeometryAttribute::POSITION, pos_options);
- encoder->SetAttributeOptions(GeometryAttribute::TEX_COORD_0, tex_options);
-
- if (!encoder->EncodeMesh(mesh.get())) {
- os.setstate(ios_base::badbit);
- return os;
- }
-
- // Write the encoded data into the stream.
- os.write(static_cast<const char *>(encoder->buffer()->data()),
- encoder->buffer()->size());
- return os;
-}
-
-} // namespace draco
-
-#endif // DRACO_COMPRESSION_MESH_MESH_ENCODER_HELPERS_H_
diff --git a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_encoder_test.cc b/extern/draco/dracoenc/src/draco/compression/mesh/mesh_encoder_test.cc
deleted file mode 100644
index 9f056fc22e3..00000000000
--- a/extern/draco/dracoenc/src/draco/compression/mesh/mesh_encoder_test.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/compression/mesh/mesh_encoder.h"
-
-#include "draco/compression/expert_encode.h"
-#include "draco/core/decoder_buffer.h"
-#include "draco/core/draco_test_base.h"
-#include "draco/core/draco_test_utils.h"
-#include "draco/io/obj_decoder.h"
-
-namespace draco {
-
-class MeshEncoderTest : public ::testing::TestWithParam<const char *> {
- protected:
- MeshEncoderTest() {}
-
- // Fills out_method with id of the encoding method used for the test.
- // Returns false if the encoding method is not set properly.
- bool GetMethod(MeshEncoderMethod *out_method) const {
- if (strcmp(GetParam(), "sequential") == 0) {
- *out_method = MESH_SEQUENTIAL_ENCODING;
- return true;
- }
- if (strcmp(GetParam(), "edgebreaker") == 0) {
- *out_method = MESH_EDGEBREAKER_ENCODING;
- return true;
- }
- return false;
- }
-};
-
-TEST_P(MeshEncoderTest, EncodeGoldenMesh) {
- // This test verifies that a given set of meshes are encoded to an expected
- // output. This is useful for catching bugs in code changes that are not
- // supposed to change the encoding.
- // The test is expected to fail when the encoding is modified. In such case,
- // the golden files need to be updated to reflect the changes.
- MeshEncoderMethod method;
- ASSERT_TRUE(GetMethod(&method))
- << "Test is run for an unknown encoding method";
-
- const std::string file_name = "test_nm.obj";
- std::string golden_file_name = file_name;
- golden_file_name += '.';
- golden_file_name += GetParam();
- golden_file_name += ".1.2.0.drc";
- const std::unique_ptr<Mesh> mesh(ReadMeshFromTestFile(file_name));
- ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
-
- ExpertEncoder encoder(*mesh.get());
- encoder.SetEncodingMethod(method);
- encoder.SetAttributeQuantization(0, 20);
- EncoderBuffer buffer;
- ASSERT_TRUE(encoder.EncodeToBuffer(&buffer).ok())
- << "Failed encoding test mesh " << file_name << " with method "
- << GetParam();
- // Check that the encoded mesh was really encoded with the selected method.
- DecoderBuffer decoder_buffer;
- decoder_buffer.Init(buffer.data(), buffer.size());
- decoder_buffer.Advance(8); // Skip the header to the encoding method id.
- uint8_t encoded_method;
- decoder_buffer.Decode(&encoded_method);
- ASSERT_EQ(encoded_method, method);
- if (!FLAGS_update_golden_files) {
- EXPECT_TRUE(
- CompareGoldenFile(golden_file_name, buffer.data(), buffer.size()))
- << "Encoded data is different from the golden file. Please verify that "
- "the encoding works as expected and update the golden file if "
- "necessary (run the test with --update_golden_files flag).";
- } else {
- // Save the files into the local folder.
- EXPECT_TRUE(
- GenerateGoldenFile(golden_file_name, buffer.data(), buffer.size()))
- << "Failed to generate new golden file for " << file_name;
- }
-}
-
-INSTANTIATE_TEST_SUITE_P(MeshEncoderTests, MeshEncoderTest,
- ::testing::Values("sequential", "edgebreaker"));
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_kd_tree_encoding_test.cc b/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_kd_tree_encoding_test.cc
deleted file mode 100644
index 6156cfe02b5..00000000000
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_kd_tree_encoding_test.cc
+++ /dev/null
@@ -1,456 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/compression/point_cloud/point_cloud_kd_tree_decoder.h"
-#include "draco/compression/point_cloud/point_cloud_kd_tree_encoder.h"
-#include "draco/core/draco_test_base.h"
-#include "draco/core/draco_test_utils.h"
-#include "draco/core/vector_d.h"
-#include "draco/io/obj_decoder.h"
-#include "draco/point_cloud/point_cloud_builder.h"
-
-namespace draco {
-
-class PointCloudKdTreeEncodingTest : public ::testing::Test {
- protected:
- void ComparePointClouds(const PointCloud &p0, const PointCloud &p1) const {
- ASSERT_EQ(p0.num_points(), p1.num_points());
- ASSERT_EQ(p0.num_attributes(), p1.num_attributes());
- // Currently works only with one attribute.
- ASSERT_EQ(p0.num_attributes(), p1.num_attributes());
- for (auto index = 0; index < p0.num_attributes(); index += 1) {
- ASSERT_EQ(p0.attribute(index)->num_components(),
- p1.attribute(index)->num_components());
- std::vector<double> points_0, points_1;
- std::vector<double> att_entry_0(p0.attribute(index)->num_components());
- std::vector<double> att_entry_1(p0.attribute(index)->num_components());
- for (PointIndex i(0); i < p0.num_points(); ++i) {
- p0.attribute(index)->ConvertValue(p0.attribute(index)->mapped_index(i),
- &att_entry_0[0]);
- p1.attribute(index)->ConvertValue(p1.attribute(index)->mapped_index(i),
- &att_entry_1[0]);
- for (int d = 0; d < p0.attribute(index)->num_components(); ++d) {
- points_0.push_back(att_entry_0[d]);
- points_1.push_back(att_entry_1[d]);
- }
- }
- // To compare the point clouds we sort points components from both inputs
- // separately, and then we compare all matching coordinates one by one.
- // TODO(ostava): Note that this is not guaranteed to work for quantized
- // point clouds because the order of points may actually change because
- // of the quantization. The test should be make more robust to handle such
- // case.
- std::sort(points_0.begin(), points_0.end());
- std::sort(points_1.begin(), points_1.end());
- for (uint32_t i = 0; i < points_0.size(); ++i) {
- ASSERT_LE(std::fabs(points_0[i] - points_1[i]), 1e-2);
- }
- }
- }
-
- void TestKdTreeEncoding(const PointCloud &pc) {
- EncoderBuffer buffer;
- PointCloudKdTreeEncoder encoder;
- EncoderOptions options = EncoderOptions::CreateDefaultOptions();
- options.SetGlobalInt("quantization_bits", 16);
- for (int compression_level = 0; compression_level <= 6;
- ++compression_level) {
- options.SetSpeed(10 - compression_level, 10 - compression_level);
- encoder.SetPointCloud(pc);
- ASSERT_TRUE(encoder.Encode(options, &buffer).ok());
-
- DecoderBuffer dec_buffer;
- dec_buffer.Init(buffer.data(), buffer.size());
- PointCloudKdTreeDecoder decoder;
-
- std::unique_ptr<PointCloud> out_pc(new PointCloud());
- DecoderOptions dec_options;
- ASSERT_TRUE(decoder.Decode(dec_options, &dec_buffer, out_pc.get()).ok());
-
- ComparePointClouds(pc, *out_pc);
- }
- }
-
- void TestFloatEncoding(const std::string &file_name) {
- std::unique_ptr<PointCloud> pc = ReadPointCloudFromTestFile(file_name);
- ASSERT_NE(pc, nullptr);
-
- TestKdTreeEncoding(*pc.get());
- }
-};
-
-TEST_F(PointCloudKdTreeEncodingTest, TestFloatKdTreeEncoding) {
- TestFloatEncoding("cube_subd.obj");
-}
-
-TEST_F(PointCloudKdTreeEncodingTest, TestIntKdTreeEncoding) {
- constexpr int num_points = 120;
- std::vector<std::array<uint32_t, 3>> points(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<uint32_t, 3> pos;
- // Generate some pseudo-random points.
- pos[0] = 8 * ((i * 7) % 127);
- pos[1] = 13 * ((i * 3) % 321);
- pos[2] = 29 * ((i * 19) % 450);
- points[i] = pos;
- }
-
- PointCloudBuilder builder;
- builder.Start(num_points);
- const int att_id =
- builder.AddAttribute(GeometryAttribute::POSITION, 3, DT_UINT32);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id, PointIndex(i),
- &(points[i.value()])[0]);
- }
- std::unique_ptr<PointCloud> pc = builder.Finalize(false);
- ASSERT_NE(pc, nullptr);
-
- TestKdTreeEncoding(*pc);
-}
-
-// test higher dimensions with more attributes
-TEST_F(PointCloudKdTreeEncodingTest, TestIntKdTreeEncodingHigherDimension) {
- constexpr int num_points = 120;
- std::vector<std::array<uint32_t, 3>> points3(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<uint32_t, 3> pos;
- // Generate some pseudo-random points.
- pos[0] = 8 * ((i * 7) % 127);
- pos[1] = 13 * ((i * 3) % 321);
- pos[2] = 29 * ((i * 19) % 450);
- points3[i] = pos;
- }
- std::vector<std::array<uint32_t, 2>> points2(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<uint32_t, 2> pos;
- // Generate some pseudo-random points.
- pos[0] = 8 * ((i * 7) % 127) + 1;
- pos[1] = 13 * ((i * 3) % 321) + 1;
- points2[i] = pos;
- }
- std::vector<std::array<uint32_t, 1>> points1(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<uint32_t, 1> pos;
- // Generate some pseudo-random points.
- pos[0] = 8 * ((i * 7) % 127) + 11;
- points1[i] = pos;
- }
-
- PointCloudBuilder builder;
- builder.Start(num_points);
- const int att_id3 =
- builder.AddAttribute(GeometryAttribute::POSITION, 3, DT_UINT32);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id3, PointIndex(i),
- &(points3[i.value()])[0]);
- }
- const int att_id2 =
- builder.AddAttribute(GeometryAttribute::POSITION, 2, DT_UINT32);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id2, PointIndex(i),
- &(points2[i.value()])[0]);
- }
- const int att_id1 =
- builder.AddAttribute(GeometryAttribute::GENERIC, 1, DT_UINT32);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id1, PointIndex(i),
- &(points1[i.value()])[0]);
- }
-
- std::unique_ptr<PointCloud> pc = builder.Finalize(false);
- ASSERT_NE(pc, nullptr);
-
- TestKdTreeEncoding(*pc);
-}
-
-// Test 16 and 8 bit encoding.
-TEST_F(PointCloudKdTreeEncodingTest,
- TestIntKdTreeEncodingHigherDimensionVariedTypes) {
- constexpr int num_points = 120;
- std::vector<std::array<uint32_t, 3>> points3(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<uint32_t, 3> pos;
- // Generate some pseudo-random points.
- pos[0] = 8 * ((i * 7) % 127);
- pos[1] = 13 * ((i * 3) % 321);
- pos[2] = 29 * ((i * 19) % 450);
- points3[i] = pos;
- }
- std::vector<std::array<uint16_t, 2>> points2(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<uint16_t, 2> pos;
- // Generate some pseudo-random points.
- pos[0] = 8 * ((i * 7) % 127) + 1;
- pos[1] = 13 * ((i * 3) % 321) + 1;
- points2[i] = pos;
- }
- std::vector<std::array<uint8_t, 1>> points1(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<uint8_t, 1> pos;
- // Generate some pseudo-random points.
- pos[0] = 8 * ((i * 7) % 127) + 11;
- points1[i] = pos;
- }
-
- PointCloudBuilder builder;
- builder.Start(num_points);
- const int att_id3 =
- builder.AddAttribute(GeometryAttribute::POSITION, 3, DT_UINT32);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id3, PointIndex(i),
- &(points3[i.value()])[0]);
- }
- const int att_id2 =
- builder.AddAttribute(GeometryAttribute::POSITION, 2, DT_UINT16);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id2, PointIndex(i),
- &(points2[i.value()])[0]);
- }
- const int att_id1 =
- builder.AddAttribute(GeometryAttribute::GENERIC, 1, DT_UINT8);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id1, PointIndex(i),
- &(points1[i.value()])[0]);
- }
-
- std::unique_ptr<PointCloud> pc = builder.Finalize(false);
- ASSERT_NE(pc, nullptr);
-
- TestKdTreeEncoding(*pc);
-}
-
-// Test 16 only encoding for one attribute.
-TEST_F(PointCloudKdTreeEncodingTest, TestIntKdTreeEncoding16Bit) {
- constexpr int num_points = 120;
- std::vector<std::array<uint16_t, 3>> points3(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<uint16_t, 3> pos;
- // Generate some pseudo-random points.
- pos[0] = 8 * ((i * 7) % 127);
- pos[1] = 13 * ((i * 3) % 321);
- pos[2] = 29 * ((i * 19) % 450);
- points3[i] = pos;
- }
-
- PointCloudBuilder builder;
- builder.Start(num_points);
- const int att_id3 =
- builder.AddAttribute(GeometryAttribute::POSITION, 3, DT_UINT16);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id3, PointIndex(i),
- &(points3[i.value()])[0]);
- }
-
- std::unique_ptr<PointCloud> pc = builder.Finalize(false);
- ASSERT_NE(pc, nullptr);
-
- TestKdTreeEncoding(*pc);
-}
-
-// Test 16 and 8 bit encoding with size bigger than 32bit encoding.
-TEST_F(PointCloudKdTreeEncodingTest,
- TestIntKdTreeEncodingHigherDimensionVariedTypesBig16BitEncoding) {
- constexpr int num_points = 120;
- std::vector<std::array<uint32_t, 3>> points3(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<uint32_t, 3> pos;
- // Generate some pseudo-random points.
- pos[0] = 8 * ((i * 7) % 127);
- pos[1] = 13 * ((i * 3) % 321);
- pos[2] = 29 * ((i * 19) % 450);
- points3[i] = pos;
- }
- // The total size of the 16bit encoding must be bigger than the total size of
- // the 32bit encoding.
- std::vector<std::array<uint16_t, 7>> points7(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<uint16_t, 7> pos;
- // Generate some pseudo-random points.
- pos[0] = 8 * ((i * 7) % 127) + 1;
- pos[1] = 13 * ((i * 3) % 321) + 1;
- pos[2] = pos[0] + 13;
- pos[3] = pos[2] + 13;
- pos[4] = pos[3] + 13;
- pos[5] = pos[4] + 13;
- pos[6] = pos[5] + 13;
- points7[i] = pos;
- }
- std::vector<std::array<uint8_t, 1>> points1(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<uint8_t, 1> pos;
- // Generate some pseudo-random points.
- pos[0] = 8 * ((i * 7) % 127) + 11;
- points1[i] = pos;
- }
-
- PointCloudBuilder builder;
- builder.Start(num_points);
- const int att_id3 =
- builder.AddAttribute(GeometryAttribute::POSITION, 3, DT_UINT32);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id3, PointIndex(i),
- &(points3[i.value()])[0]);
- }
- const int att_id2 =
- builder.AddAttribute(GeometryAttribute::POSITION, 7, DT_UINT16);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id2, PointIndex(i),
- &(points7[i.value()])[0]);
- }
- const int att_id1 =
- builder.AddAttribute(GeometryAttribute::GENERIC, 1, DT_UINT8);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id1, PointIndex(i),
- &(points1[i.value()])[0]);
- }
-
- std::unique_ptr<PointCloud> pc = builder.Finalize(false);
- ASSERT_NE(pc, nullptr);
-
- TestKdTreeEncoding(*pc);
-}
-
-// Test encoding of quantized values.
-TEST_F(PointCloudKdTreeEncodingTest,
- TestIntKdTreeEncodingHigherDimensionFloatTypes) {
- constexpr int num_points = 130;
- std::vector<std::array<uint32_t, 3>> points3(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<uint32_t, 3> pos;
- // Generate some pseudo-random points.
- pos[0] = 8 * ((i * 7) % 125);
- pos[1] = 13 * ((i * 3) % 334);
- pos[2] = 29 * ((i * 19) % 470);
- points3[i] = pos;
- }
- std::vector<std::array<float, 2>> points_float(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<float, 2> pos;
- // Generate some pseudo-random points.
- pos[0] = static_cast<float>(8 * ((i * 7) % 127) + 1) / 2.5f;
- pos[1] = static_cast<float>(13 * ((i * 3) % 321) + 1) / 3.2f;
- points_float[i] = pos;
- }
-
- PointCloudBuilder builder;
- builder.Start(num_points);
- const int att_id3 =
- builder.AddAttribute(GeometryAttribute::POSITION, 3, DT_UINT32);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id3, PointIndex(i),
- &(points3[i.value()])[0]);
- }
- const int att_id_float =
- builder.AddAttribute(GeometryAttribute::GENERIC, 2, DT_FLOAT32);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id_float, PointIndex(i),
- &(points_float[i.value()])[0]);
- }
-
- std::unique_ptr<PointCloud> pc = builder.Finalize(false);
- ASSERT_NE(pc, nullptr);
-
- TestKdTreeEncoding(*pc);
-}
-
-// Test encoding of signed integer values
-TEST_F(PointCloudKdTreeEncodingTest, TestIntKdTreeEncodingSignedTypes) {
- constexpr int num_points = 120;
- std::vector<std::array<uint32_t, 3>> points3(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<uint32_t, 3> pos;
- // Generate some pseudo-random points.
- pos[0] = 8 * ((i * 7) % 127);
- pos[1] = 13 * ((i * 3) % 321);
- pos[2] = 29 * ((i * 19) % 450);
- points3[i] = pos;
- }
- std::vector<std::array<int32_t, 2>> points2(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<int32_t, 2> pos;
- // Generate some pseudo-random points.
- pos[0] = 8 * ((i * 7) % 127) + 1;
- if (i % 3 == 0)
- pos[0] = -pos[0];
- pos[1] = 13 * ((i * 3) % 321) + 1;
- points2[i] = pos;
- }
- std::vector<std::array<int16_t, 1>> points1(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<int16_t, 1> pos;
- // Generate some pseudo-random points.
- pos[0] = 8 * ((i * 7) % 127) + 11;
- if (i % 5 == 0)
- pos[0] = -pos[0];
- points1[i] = pos;
- }
-
- PointCloudBuilder builder;
- builder.Start(num_points);
- const int att_id3 =
- builder.AddAttribute(GeometryAttribute::POSITION, 3, DT_UINT32);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id3, PointIndex(i),
- &(points3[i.value()])[0]);
- }
- const int att_id2 =
- builder.AddAttribute(GeometryAttribute::POSITION, 2, DT_INT32);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id2, PointIndex(i),
- &(points2[i.value()])[0]);
- }
-
- const int att_id1 =
- builder.AddAttribute(GeometryAttribute::GENERIC, 1, DT_INT16);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id1, PointIndex(i),
- &(points1[i.value()])[0]);
- }
-
- std::unique_ptr<PointCloud> pc = builder.Finalize(false);
- ASSERT_NE(pc, nullptr);
-
- TestKdTreeEncoding(*pc);
-}
-
-// Test encoding of integer point clouds with > 16 dimensions.
-TEST_F(PointCloudKdTreeEncodingTest, TestIntKdTreeEncodingHighDimensional) {
- constexpr int num_points = 120;
- constexpr int num_dims = 42;
- std::vector<std::array<uint32_t, num_dims>> points(num_points);
- for (int i = 0; i < num_points; ++i) {
- std::array<uint32_t, num_dims> pos;
- // Generate some pseudo-random points.
- for (int d = 0; d < num_dims; ++d) {
- pos[d] = 8 * ((i + d) * (7 + (d % 4)) % (127 + d % 3));
- }
- points[i] = pos;
- }
- PointCloudBuilder builder;
- builder.Start(num_points);
- const int att_id =
- builder.AddAttribute(GeometryAttribute::POSITION, num_dims, DT_UINT32);
- for (PointIndex i(0); i < num_points; ++i) {
- builder.SetAttributeValueForPoint(att_id, PointIndex(i),
- &(points[i.value()])[0]);
- }
-
- std::unique_ptr<PointCloud> pc = builder.Finalize(false);
- ASSERT_NE(pc, nullptr);
-
- TestKdTreeEncoding(*pc);
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_sequential_encoding_test.cc b/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_sequential_encoding_test.cc
deleted file mode 100644
index beab4bcd7e9..00000000000
--- a/extern/draco/dracoenc/src/draco/compression/point_cloud/point_cloud_sequential_encoding_test.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/compression/point_cloud/point_cloud_sequential_decoder.h"
-#include "draco/compression/point_cloud/point_cloud_sequential_encoder.h"
-#include "draco/core/draco_test_base.h"
-#include "draco/core/draco_test_utils.h"
-#include "draco/io/obj_decoder.h"
-
-namespace draco {
-
-class PointCloudSequentialEncodingTest : public ::testing::Test {
- protected:
- std::unique_ptr<PointCloud> EncodeAndDecodePointCloud(const PointCloud *pc) {
- EncoderBuffer buffer;
- PointCloudSequentialEncoder encoder;
- EncoderOptions options = EncoderOptions::CreateDefaultOptions();
- encoder.SetPointCloud(*pc);
- if (!encoder.Encode(options, &buffer).ok())
- return nullptr;
-
- DecoderBuffer dec_buffer;
- dec_buffer.Init(buffer.data(), buffer.size());
- PointCloudSequentialDecoder decoder;
-
- std::unique_ptr<PointCloud> out_pc(new PointCloud());
- DecoderOptions dec_options;
- if (!decoder.Decode(dec_options, &dec_buffer, out_pc.get()).ok())
- return nullptr;
- return out_pc;
- }
-
- void TestEncoding(const std::string &file_name) {
- std::unique_ptr<PointCloud> pc = ReadPointCloudFromTestFile(file_name);
- ASSERT_NE(pc, nullptr);
-
- std::unique_ptr<PointCloud> decoded_pc =
- EncodeAndDecodePointCloud(pc.get());
- ASSERT_NE(decoded_pc.get(), nullptr);
- ASSERT_EQ(decoded_pc->num_points(), pc->num_points());
- }
-};
-
-TEST_F(PointCloudSequentialEncodingTest, DoesEncodeAndDecode) {
- TestEncoding("test_nm.obj");
-}
-
-TEST_F(PointCloudSequentialEncodingTest, EncodingPointCloudWithMetadata) {
- std::unique_ptr<PointCloud> pc = ReadPointCloudFromTestFile("test_nm.obj");
- ASSERT_NE(pc, nullptr);
- // Add metadata to point cloud.
- std::unique_ptr<GeometryMetadata> metadata =
- std::unique_ptr<GeometryMetadata>(new GeometryMetadata());
- const uint32_t pos_att_id =
- pc->GetNamedAttributeId(GeometryAttribute::POSITION);
- std::unique_ptr<AttributeMetadata> pos_metadata =
- std::unique_ptr<AttributeMetadata>(new AttributeMetadata());
- pos_metadata->AddEntryString("name", "position");
- pc->AddAttributeMetadata(pos_att_id, std::move(pos_metadata));
-
- std::unique_ptr<PointCloud> decoded_pc = EncodeAndDecodePointCloud(pc.get());
- ASSERT_NE(decoded_pc.get(), nullptr);
-
- const GeometryMetadata *const pc_metadata = decoded_pc->GetMetadata();
- ASSERT_NE(pc_metadata, nullptr);
- // Test getting attribute metadata by id.
- ASSERT_NE(pc->GetAttributeMetadataByAttributeId(pos_att_id), nullptr);
- // Test getting attribute metadata by entry name value pair.
- const AttributeMetadata *const requested_att_metadata =
- pc_metadata->GetAttributeMetadataByStringEntry("name", "position");
- ASSERT_NE(requested_att_metadata, nullptr);
- ASSERT_EQ(requested_att_metadata->att_unique_id(),
- pc->attribute(pos_att_id)->unique_id());
-}
-
-// TODO(ostava): Test the reusability of a single instance of the encoder and
-// decoder class.
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/core/buffer_bit_coding_test.cc b/extern/draco/dracoenc/src/draco/core/buffer_bit_coding_test.cc
deleted file mode 100644
index e761284e236..00000000000
--- a/extern/draco/dracoenc/src/draco/core/buffer_bit_coding_test.cc
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/core/decoder_buffer.h"
-#include "draco/core/encoder_buffer.h"
-
-#include "draco/core/draco_test_base.h"
-
-namespace draco {
-
-class BufferBitCodingTest : public ::testing::Test {
- public:
- typedef DecoderBuffer::BitDecoder BitDecoder;
- typedef EncoderBuffer::BitEncoder BitEncoder;
-};
-
-TEST_F(BufferBitCodingTest, TestBitCodersByteAligned) {
- constexpr int buffer_size = 32;
- char buffer[buffer_size];
- BitEncoder encoder(buffer);
- const uint8_t data[] = {0x76, 0x54, 0x32, 0x10, 0x76, 0x54, 0x32, 0x10};
- const int bytes_to_encode = sizeof(data);
-
- for (int i = 0; i < bytes_to_encode; ++i) {
- encoder.PutBits(data[i], sizeof(data[i]) * 8);
- ASSERT_EQ((i + 1) * sizeof(data[i]) * 8, encoder.Bits());
- }
-
- BitDecoder decoder;
- decoder.reset(static_cast<const void *>(buffer), bytes_to_encode);
- for (int i = 0; i < bytes_to_encode; ++i) {
- uint32_t x = 0;
- ASSERT_TRUE(decoder.GetBits(8, &x));
- ASSERT_EQ(x, data[i]);
- }
-
- ASSERT_EQ(bytes_to_encode * 8u, decoder.BitsDecoded());
-}
-
-TEST_F(BufferBitCodingTest, TestBitCodersNonByte) {
- constexpr int buffer_size = 32;
- char buffer[buffer_size];
- BitEncoder encoder(buffer);
- const uint8_t data[] = {0x76, 0x54, 0x32, 0x10, 0x76, 0x54, 0x32, 0x10};
- const uint32_t bits_to_encode = 51;
- const int bytes_to_encode = (bits_to_encode / 8) + 1;
-
- for (int i = 0; i < bytes_to_encode; ++i) {
- const int num_bits = (encoder.Bits() + 8 <= bits_to_encode)
- ? 8
- : bits_to_encode - encoder.Bits();
- encoder.PutBits(data[i], num_bits);
- }
-
- BitDecoder decoder;
- decoder.reset(static_cast<const void *>(buffer), bytes_to_encode);
- int64_t bits_to_decode = encoder.Bits();
- for (int i = 0; i < bytes_to_encode; ++i) {
- uint32_t x = 0;
- const int num_bits = (bits_to_decode > 8) ? 8 : bits_to_decode;
- ASSERT_TRUE(decoder.GetBits(num_bits, &x));
- const int bits_to_shift = 8 - num_bits;
- const uint8_t test_byte =
- ((data[i] << bits_to_shift) & 0xff) >> bits_to_shift;
- ASSERT_EQ(x, test_byte);
- bits_to_decode -= 8;
- }
-
- ASSERT_EQ(bits_to_encode, decoder.BitsDecoded());
-}
-
-TEST_F(BufferBitCodingTest, TestSingleBits) {
- const int data = 0xaaaa;
-
- BitDecoder decoder;
- decoder.reset(static_cast<const void *>(&data), sizeof(data));
-
- for (uint32_t i = 0; i < 16; ++i) {
- uint32_t x = 0;
- ASSERT_TRUE(decoder.GetBits(1, &x));
- ASSERT_EQ(x, (i % 2));
- }
-
- ASSERT_EQ(16u, decoder.BitsDecoded());
-}
-
-TEST_F(BufferBitCodingTest, TestMultipleBits) {
- const uint8_t data[] = {0x76, 0x54, 0x32, 0x10, 0x76, 0x54, 0x32, 0x10};
-
- BitDecoder decoder;
- decoder.reset(static_cast<const void *>(data), sizeof(data));
-
- uint32_t x = 0;
- for (uint32_t i = 0; i < 2; ++i) {
- ASSERT_TRUE(decoder.GetBits(16, &x));
- ASSERT_EQ(x, 0x5476u);
- ASSERT_EQ(16 + (i * 32), decoder.BitsDecoded());
-
- ASSERT_TRUE(decoder.GetBits(16, &x));
- ASSERT_EQ(x, 0x1032u);
- ASSERT_EQ(32 + (i * 32), decoder.BitsDecoded());
- }
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/core/draco_test_base.h b/extern/draco/dracoenc/src/draco/core/draco_test_base.h
deleted file mode 100644
index f5c9d751e03..00000000000
--- a/extern/draco/dracoenc/src/draco/core/draco_test_base.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// Wrapper for including googletest indirectly. Useful when the location of the
-// googletest sources must change depending on build environment and repository
-// source location.
-#ifndef DRACO_CORE_DRACO_TEST_BASE_H_
-#define DRACO_CORE_DRACO_TEST_BASE_H_
-
-static bool FLAGS_update_golden_files;
-#include "gtest/gtest.h"
-#include "testing/draco_test_config.h"
-
-#endif // DRACO_CORE_DRACO_TEST_BASE_H_
diff --git a/extern/draco/dracoenc/src/draco/core/draco_test_utils.cc b/extern/draco/dracoenc/src/draco/core/draco_test_utils.cc
deleted file mode 100644
index a39e19f6b15..00000000000
--- a/extern/draco/dracoenc/src/draco/core/draco_test_utils.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/core/draco_test_utils.h"
-
-#include <fstream>
-
-#include "draco/core/macros.h"
-#include "draco_test_base.h"
-
-namespace draco {
-
-namespace {
-static constexpr char kTestDataDir[] = DRACO_TEST_DATA_DIR;
-static constexpr char kTestTempDir[] = DRACO_TEST_TEMP_DIR;
-} // namespace
-
-std::string GetTestFileFullPath(const std::string &file_name) {
- return std::string(kTestDataDir) + std::string("/") + file_name;
-}
-
-std::string GetTestTempFileFullPath(const std::string &file_name) {
- return std::string(kTestTempDir) + std::string("/") + file_name;
-}
-
-bool GenerateGoldenFile(const std::string &golden_file_name, const void *data,
- int data_size) {
- const std::string path = GetTestFileFullPath(golden_file_name);
- std::ofstream file(path, std::ios::binary);
- if (!file)
- return false;
- file.write(static_cast<const char *>(data), data_size);
- file.close();
- return true;
-}
-
-bool CompareGoldenFile(const std::string &golden_file_name, const void *data,
- int data_size) {
- const std::string golden_path = GetTestFileFullPath(golden_file_name);
- std::ifstream in_file(golden_path, std::ios::binary);
- if (!in_file || data_size < 0)
- return false;
- const char *const data_c8 = static_cast<const char *>(data);
- constexpr int buffer_size = 1024;
- char buffer[buffer_size];
- size_t extracted_size = 0;
- size_t remaining_data_size = data_size;
- int offset = 0;
- while ((extracted_size = in_file.read(buffer, buffer_size).gcount()) > 0) {
- if (remaining_data_size <= 0)
- break; // Input and golden sizes are different.
- size_t size_to_check = extracted_size;
- if (remaining_data_size < size_to_check)
- size_to_check = remaining_data_size;
- for (uint32_t i = 0; i < size_to_check; ++i) {
- if (buffer[i] != data_c8[offset++]) {
- LOG(INFO) << "Test output differed from golden file at byte "
- << offset - 1;
- return false;
- }
- }
- remaining_data_size -= extracted_size;
- }
- if (remaining_data_size != extracted_size) {
- // Both of these values should be 0 at the end.
- LOG(INFO) << "Test output size differed from golden file size";
- return false;
- }
- return true;
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/core/draco_test_utils.h b/extern/draco/dracoenc/src/draco/core/draco_test_utils.h
deleted file mode 100644
index 3113a5d2676..00000000000
--- a/extern/draco/dracoenc/src/draco/core/draco_test_utils.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#ifndef DRACO_CORE_DRACO_TEST_UTILS_H_
-#define DRACO_CORE_DRACO_TEST_UTILS_H_
-
-#include "draco/core/draco_test_base.h"
-#include "draco/io/mesh_io.h"
-#include "draco/io/point_cloud_io.h"
-
-namespace draco {
-
-// Returns the full path to a given file system entry, such as test file or test
-// directory.
-std::string GetTestFileFullPath(const std::string &entry_name);
-
-// Returns the full path to a given temporary file (a location where tests store
-// generated files).
-std::string GetTestTempFileFullPath(const std::string &file_name);
-
-// Generates a new golden file and saves it into the correct folder.
-// Returns false if the file couldn't be created.
-bool GenerateGoldenFile(const std::string &golden_file_name, const void *data,
- int data_size);
-
-// Compare a golden file content with the input data.
-// Function will log the first byte position where the data differ.
-// Returns false if there are any differences.
-bool CompareGoldenFile(const std::string &golden_file_name, const void *data,
- int data_size);
-
-// Loads a mesh / point cloud specified by a |file_name| that is going to be
-// automatically converted to the correct path available to the testing
-// instance.
-inline std::unique_ptr<Mesh> ReadMeshFromTestFile(
- const std::string &file_name) {
- const std::string path = GetTestFileFullPath(file_name);
- return ReadMeshFromFile(path).value();
-}
-inline std::unique_ptr<Mesh> ReadMeshFromTestFile(const std::string &file_name,
- bool use_metadata) {
- const std::string path = GetTestFileFullPath(file_name);
- return ReadMeshFromFile(path, use_metadata).value();
-}
-inline std::unique_ptr<Mesh> ReadMeshFromTestFile(const std::string &file_name,
- const Options &options) {
- const std::string path = GetTestFileFullPath(file_name);
- return ReadMeshFromFile(path, options).value();
-}
-
-inline std::unique_ptr<PointCloud> ReadPointCloudFromTestFile(
- const std::string &file_name) {
- const std::string path = GetTestFileFullPath(file_name);
- return ReadPointCloudFromFile(path).value();
-}
-
-} // namespace draco
-
-#endif // DRACO_CORE_DRACO_TEST_UTILS_H_
diff --git a/extern/draco/dracoenc/src/draco/core/draco_tests.cc b/extern/draco/dracoenc/src/draco/core/draco_tests.cc
deleted file mode 100644
index fdaa14da508..00000000000
--- a/extern/draco/dracoenc/src/draco/core/draco_tests.cc
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "draco/core/draco_test_base.h"
-
-int main(int argc, char *argv[]) {
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/extern/draco/dracoenc/src/draco/core/math_utils_test.cc b/extern/draco/dracoenc/src/draco/core/math_utils_test.cc
deleted file mode 100644
index 8c255d04680..00000000000
--- a/extern/draco/dracoenc/src/draco/core/math_utils_test.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-#include "draco/core/math_utils.h"
-
-#include <cmath>
-#include <random>
-
-#include "draco/core/draco_test_base.h"
-
-using draco::Vector3f;
-
-TEST(MathUtils, Mod) { EXPECT_EQ(DRACO_INCREMENT_MOD(1, 1 << 1), 0); }
-
-TEST(MathUtils, IntSqrt) {
- ASSERT_EQ(IntSqrt(0), 0);
- // 64-bit pseudo random number generator seeded with a predefined number.
- std::mt19937_64 generator(109);
- std::uniform_int_distribution<uint64_t> distribution(0, 1ull << 60);
-
- for (int i = 0; i < 10000; ++i) {
- const uint64_t number = distribution(generator);
- ASSERT_EQ(IntSqrt(number), static_cast<uint64_t>(floor(std::sqrt(number))));
- }
-}
diff --git a/extern/draco/dracoenc/src/draco/core/quantization_utils_test.cc b/extern/draco/dracoenc/src/draco/core/quantization_utils_test.cc
deleted file mode 100644
index b4f0473f204..00000000000
--- a/extern/draco/dracoenc/src/draco/core/quantization_utils_test.cc
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/core/quantization_utils.h"
-
-#include "draco/core/draco_test_base.h"
-
-namespace draco {
-
-class QuantizationUtilsTest : public ::testing::Test {};
-
-TEST_F(QuantizationUtilsTest, TestQuantizer) {
- Quantizer quantizer;
- quantizer.Init(10.f, 255);
- EXPECT_EQ(quantizer.QuantizeFloat(0.f), 0);
- EXPECT_EQ(quantizer.QuantizeFloat(10.f), 255);
- EXPECT_EQ(quantizer.QuantizeFloat(-10.f), -255);
- EXPECT_EQ(quantizer.QuantizeFloat(4.999f), 127);
- EXPECT_EQ(quantizer.QuantizeFloat(5.f), 128);
- EXPECT_EQ(quantizer.QuantizeFloat(-4.9999f), -127);
- // Note: Both -5.f and +5.f lie exactly on the boundary between two
- // quantized values (127.5f and -127.5f). Due to rounding, both values are
- // then converted to 128 and -127 respectively.
- EXPECT_EQ(quantizer.QuantizeFloat(-5.f), -127);
- EXPECT_EQ(quantizer.QuantizeFloat(-5.0001f), -128);
-
- // Out of range quantization.
- // The behavior is technically undefined, but both quantizer and dequantizer
- // should still work correctly unless the quantized values overflow.
- EXPECT_LT(quantizer.QuantizeFloat(-15.f), -255);
- EXPECT_GT(quantizer.QuantizeFloat(15.f), 255);
-}
-
-TEST_F(QuantizationUtilsTest, TestDequantizer) {
- Dequantizer dequantizer;
- ASSERT_TRUE(dequantizer.Init(10.f, 255));
- EXPECT_EQ(dequantizer.DequantizeFloat(0), 0.f);
- EXPECT_EQ(dequantizer.DequantizeFloat(255), 10.f);
- EXPECT_EQ(dequantizer.DequantizeFloat(-255), -10.f);
- EXPECT_EQ(dequantizer.DequantizeFloat(128), 10.f * (128.f / 255.f));
-
- // Test that the dequantizer fails to initialize with invalid input
- // parameters.
- ASSERT_FALSE(dequantizer.Init(1.f, 0));
- ASSERT_FALSE(dequantizer.Init(1.f, -4));
-}
-
-TEST_F(QuantizationUtilsTest, TestDeltaQuantization) {
- // Test verifies that the quantizer and dequantizer work correctly when
- // initialized with a delta value.
- Quantizer quantizer_delta;
- quantizer_delta.Init(0.5f);
-
- Quantizer quantizer_range;
- quantizer_range.Init(50.f, 100);
-
- EXPECT_EQ(quantizer_delta.QuantizeFloat(1.2f), 2);
- EXPECT_EQ(quantizer_delta.QuantizeFloat(10.f),
- quantizer_range.QuantizeFloat(10.f));
- EXPECT_EQ(quantizer_delta.QuantizeFloat(-3.3f),
- quantizer_range.QuantizeFloat(-3.3f));
- EXPECT_EQ(quantizer_delta.QuantizeFloat(0.25f),
- quantizer_range.QuantizeFloat(0.25f));
-
- Dequantizer dequantizer_delta;
- dequantizer_delta.Init(0.5f);
-
- Dequantizer dequantizer_range;
- dequantizer_range.Init(50.f, 100);
-
- EXPECT_EQ(dequantizer_delta.DequantizeFloat(2), 1.f);
- EXPECT_EQ(dequantizer_delta.DequantizeFloat(-4),
- dequantizer_range.DequantizeFloat(-4));
- EXPECT_EQ(dequantizer_delta.DequantizeFloat(9),
- dequantizer_range.DequantizeFloat(9));
- EXPECT_EQ(dequantizer_delta.DequantizeFloat(0),
- dequantizer_range.DequantizeFloat(0));
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/core/status_test.cc b/extern/draco/dracoenc/src/draco/core/status_test.cc
deleted file mode 100644
index c1ad4ab30f4..00000000000
--- a/extern/draco/dracoenc/src/draco/core/status_test.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/core/status.h"
-
-#include <sstream>
-
-#include "draco/core/draco_test_base.h"
-
-namespace {
-
-class StatusTest : public ::testing::Test {
- protected:
- StatusTest() {}
-};
-
-TEST_F(StatusTest, TestStatusOutput) {
- // Tests that the Status can be stored in a provided std::ostream.
- const draco::Status status(draco::Status::DRACO_ERROR, "Error msg.");
- ASSERT_EQ(status.code(), draco::Status::DRACO_ERROR);
-
- std::stringstream str;
- str << status;
- ASSERT_EQ(str.str(), "Error msg.");
-}
-
-} // namespace
diff --git a/extern/draco/dracoenc/src/draco/core/statusor.h b/extern/draco/dracoenc/src/draco/core/statusor.h
deleted file mode 100644
index 7fa42098442..00000000000
--- a/extern/draco/dracoenc/src/draco/core/statusor.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2017 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#ifndef DRACO_CORE_STATUSOR_H_
-#define DRACO_CORE_STATUSOR_H_
-
-#include "draco/core/macros.h"
-#include "draco/core/status.h"
-
-namespace draco {
-
-// Class StatusOr is used to wrap a Status along with a value of a specified
-// type |T|. StatusOr is intended to be returned from functions in situations
-// where it is desirable to carry over more information about the potential
-// errors encountered during the function execution. If there are not errors,
-// the caller can simply use the return value, otherwise the Status object
-// provides more info about the encountered problem.
-template <class T>
-class StatusOr {
- public:
- StatusOr() {}
- // Note: Constructors are intentionally not explicit to allow returning
- // Status or the return value directly from functions.
- StatusOr(const StatusOr &) = default;
- StatusOr(StatusOr &&) = default;
- StatusOr(const Status &status) : status_(status) {}
- StatusOr(const T &value) : status_(OkStatus()), value_(value) {}
- StatusOr(T &&value) : status_(OkStatus()), value_(std::move(value)) {}
- StatusOr(const Status &status, const T &value)
- : status_(status), value_(value) {}
-
- const Status &status() const { return status_; }
- const T &value() const & { return value_; }
- const T &&value() const && { return std::move(value_); }
- T &&value() && { return std::move(value_); }
-
- // For consistency with existing Google StatusOr API we also include
- // ValueOrDie() that currently returns the value().
- const T &ValueOrDie() const & { return value(); }
- T &&ValueOrDie() && { return std::move(value()); }
-
- bool ok() const { return status_.ok(); }
-
- private:
- Status status_;
- T value_;
-};
-
-// In case StatusOr<T> is ok(), this macro assigns value stored in StatusOr<T>
-// to |lhs|, otherwise it returns the error Status.
-//
-// DRACO_ASSIGN_OR_RETURN(lhs, expression)
-//
-#define DRACO_ASSIGN_OR_RETURN(lhs, expression) \
- DRACO_ASSIGN_OR_RETURN_IMPL_(DRACO_MACROS_IMPL_CONCAT_(_statusor, __LINE__), \
- lhs, expression, _status)
-
-// The actual implementation of the above macro.
-#define DRACO_ASSIGN_OR_RETURN_IMPL_(statusor, lhs, expression, error_expr) \
- auto statusor = (expression); \
- if (!statusor.ok()) { \
- auto _status = std::move(statusor.status()); \
- (void)_status; /* error_expression may not use it */ \
- return error_expr; \
- } \
- lhs = std::move(statusor).value();
-
-} // namespace draco
-
-#endif // DRACO_CORE_STATUSOR_H_
diff --git a/extern/draco/dracoenc/src/draco/core/vector_d_test.cc b/extern/draco/dracoenc/src/draco/core/vector_d_test.cc
deleted file mode 100644
index bc2bdadaa9f..00000000000
--- a/extern/draco/dracoenc/src/draco/core/vector_d_test.cc
+++ /dev/null
@@ -1,235 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/core/vector_d.h"
-
-#include <sstream>
-
-#include "draco/core/draco_test_base.h"
-
-namespace {
-
-typedef draco::Vector2f Vector2f;
-typedef draco::Vector3f Vector3f;
-typedef draco::Vector4f Vector4f;
-typedef draco::Vector5f Vector5f;
-typedef draco::Vector2ui Vector2ui;
-typedef draco::Vector3ui Vector3ui;
-typedef draco::Vector4ui Vector4ui;
-typedef draco::Vector5ui Vector5ui;
-
-typedef draco::VectorD<int32_t, 3> Vector3i;
-typedef draco::VectorD<int32_t, 4> Vector4i;
-
-template <class CoeffT, int dimension_t>
-void TestSquaredDistance(const draco::VectorD<CoeffT, dimension_t> v1,
- const draco::VectorD<CoeffT, dimension_t> v2,
- const CoeffT result) {
- CoeffT squared_distance = SquaredDistance(v1, v2);
- ASSERT_EQ(squared_distance, result);
- squared_distance = SquaredDistance(v2, v1);
- ASSERT_EQ(squared_distance, result);
-}
-
-TEST(VectorDTest, TestOperators) {
- {
- const Vector3f v;
- ASSERT_EQ(v[0], 0);
- ASSERT_EQ(v[1], 0);
- ASSERT_EQ(v[2], 0);
- }
- Vector3f v(1, 2, 3);
- ASSERT_EQ(v[0], 1);
- ASSERT_EQ(v[1], 2);
- ASSERT_EQ(v[2], 3);
-
- Vector3f w = v;
- ASSERT_TRUE(v == w);
- ASSERT_FALSE(v != w);
- ASSERT_EQ(w[0], 1);
- ASSERT_EQ(w[1], 2);
- ASSERT_EQ(w[2], 3);
-
- w = -v;
- ASSERT_EQ(w[0], -1);
- ASSERT_EQ(w[1], -2);
- ASSERT_EQ(w[2], -3);
-
- w = v + v;
- ASSERT_EQ(w[0], 2);
- ASSERT_EQ(w[1], 4);
- ASSERT_EQ(w[2], 6);
-
- w = w - v;
- ASSERT_EQ(w[0], 1);
- ASSERT_EQ(w[1], 2);
- ASSERT_EQ(w[2], 3);
-
- // Scalar multiplication from left and right.
- w = v * 2.f;
- ASSERT_EQ(w[0], 2);
- ASSERT_EQ(w[1], 4);
- ASSERT_EQ(w[2], 6);
- w = 2.f * v;
- ASSERT_EQ(w[0], 2);
- ASSERT_EQ(w[1], 4);
- ASSERT_EQ(w[2], 6);
-
- ASSERT_EQ(v.SquaredNorm(), 14);
- ASSERT_EQ(v.Dot(v), 14);
-
- Vector3f new_v = v;
- new_v.Normalize();
- const float eps = 0.001;
- const float magnitude = std::sqrt(v.SquaredNorm());
- const float new_magnitude = std::sqrt(new_v.SquaredNorm());
- ASSERT_LE(new_magnitude, 1 + eps);
- ASSERT_GE(new_magnitude, 1 - eps);
- for (int i = 0; i < 3; ++i) {
- new_v[i] *= magnitude;
- ASSERT_LE(new_v[i], v[i] + eps);
- ASSERT_GE(new_v[i], v[i] - eps);
- }
-
- Vector3f x(0, 0, 0);
- x.Normalize();
- for (int i = 0; i < 3; ++i) {
- ASSERT_EQ(0, x[i]);
- }
-}
-
-TEST(VectorDTest, TestSquaredDistance) {
- // Test Vector2f: float, 2D.
- Vector2f v1_2f(5.5, 10.5);
- Vector2f v2_2f(3.5, 15.5);
- float result_f = 29;
- TestSquaredDistance(v1_2f, v2_2f, result_f);
-
- // Test Vector3f: float, 3D.
- Vector3f v1_3f(5.5, 10.5, 2.3);
- Vector3f v2_3f(3.5, 15.5, 0);
- result_f = 34.29;
- TestSquaredDistance(v1_3f, v2_3f, result_f);
-
- // Test Vector4f: float, 4D.
- Vector4f v1_4f(5.5, 10.5, 2.3, 7.2);
- Vector4f v2_4f(3.5, 15.5, 0, 9.9);
- result_f = 41.58;
- TestSquaredDistance(v1_4f, v2_4f, result_f);
-
- // Test Vector5f: float, 5D.
- Vector5f v1_5f(5.5, 10.5, 2.3, 7.2, 1.0);
- Vector5f v2_5f(3.5, 15.5, 0, 9.9, 0.2);
- result_f = 42.22;
- TestSquaredDistance(v1_5f, v2_5f, result_f);
-
- // Test Vector 2ui: uint32_t, 2D.
- Vector2ui v1_2ui(5, 10);
- Vector2ui v2_2ui(3, 15);
- uint32_t result_ui = 29;
- TestSquaredDistance(v1_2ui, v2_2ui, result_ui);
-
- // Test Vector 3ui: uint32_t, 3D.
- Vector3ui v1_3ui(5, 10, 2);
- Vector3ui v2_3ui(3, 15, 0);
- result_ui = 33;
- TestSquaredDistance(v1_3ui, v2_3ui, result_ui);
-
- // Test Vector 4ui: uint32_t, 4D.
- Vector4ui v1_4ui(5, 10, 2, 7);
- Vector4ui v2_4ui(3, 15, 0, 9);
- result_ui = 37;
- TestSquaredDistance(v1_4ui, v2_4ui, result_ui);
-
- // Test Vector 5ui: uint32_t, 5D.
- Vector5ui v1_5ui(5, 10, 2, 7, 1);
- Vector5ui v2_5ui(3, 15, 0, 9, 12);
- result_ui = 158;
- TestSquaredDistance(v1_5ui, v2_5ui, result_ui);
-}
-
-TEST(VectorDTest, TestCrossProduct3D) {
- const Vector3i e1(1, 0, 0);
- const Vector3i e2(0, 1, 0);
- const Vector3i e3(0, 0, 1);
- const Vector3i o(0, 0, 0);
- ASSERT_EQ(e3, draco::CrossProduct(e1, e2));
- ASSERT_EQ(e1, draco::CrossProduct(e2, e3));
- ASSERT_EQ(e2, draco::CrossProduct(e3, e1));
- ASSERT_EQ(-e3, draco::CrossProduct(e2, e1));
- ASSERT_EQ(-e1, draco::CrossProduct(e3, e2));
- ASSERT_EQ(-e2, draco::CrossProduct(e1, e3));
- ASSERT_EQ(o, draco::CrossProduct(e1, e1));
- ASSERT_EQ(o, draco::CrossProduct(e2, e2));
- ASSERT_EQ(o, draco::CrossProduct(e3, e3));
-
- // Orthogonality of result for some general vectors.
- const Vector3i v1(123, -62, 223);
- const Vector3i v2(734, 244, -13);
- const Vector3i orth = draco::CrossProduct(v1, v2);
- ASSERT_EQ(0, v1.Dot(orth));
- ASSERT_EQ(0, v2.Dot(orth));
-}
-
-TEST(VectorDTest, TestAbsSum) {
- // Testing const of function and zero.
- const Vector3i v(0, 0, 0);
- ASSERT_EQ(v.AbsSum(), 0);
- // Testing semantic.
- ASSERT_EQ(Vector3i(0, 0, 0).AbsSum(), 0);
- ASSERT_EQ(Vector3i(1, 2, 3).AbsSum(), 6);
- ASSERT_EQ(Vector3i(-1, -2, -3).AbsSum(), 6);
- ASSERT_EQ(Vector3i(-2, 4, -8).AbsSum(), 14);
- // Other dimension.
- ASSERT_EQ(Vector4i(-2, 4, -8, 3).AbsSum(), 17);
-}
-
-TEST(VectorDTest, TestMinMaxCoeff) {
- // Test verifies that MinCoeff() and MaxCoeff() functions work as intended.
- const Vector4i vi(-10, 5, 2, 3);
- ASSERT_EQ(vi.MinCoeff(), -10);
- ASSERT_EQ(vi.MaxCoeff(), 5);
-
- const Vector3f vf(6.f, 1000.f, -101.f);
- ASSERT_EQ(vf.MinCoeff(), -101.f);
- ASSERT_EQ(vf.MaxCoeff(), 1000.f);
-}
-
-TEST(VectorDTest, TestOstream) {
- // Tests that the vector can be stored in a provided std::ostream.
- const draco::VectorD<int64_t, 3> vector(1, 2, 3);
- std::stringstream str;
- str << vector << " ";
- ASSERT_EQ(str.str(), "1 2 3 ");
-}
-
-TEST(VectorDTest, TestConvertConstructor) {
- // Tests that a vector can be constructed from another vector with a different
- // type.
- const draco::VectorD<int64_t, 3> vector(1, 2, 3);
-
- const draco::VectorD<float, 3> vector3f(vector);
- ASSERT_EQ(vector3f, draco::Vector3f(1.f, 2.f, 3.f));
-
- const draco::VectorD<float, 2> vector2f(vector);
- ASSERT_EQ(vector2f, draco::Vector2f(1.f, 2.f));
-
- const draco::VectorD<float, 4> vector4f(vector3f);
- ASSERT_EQ(vector4f, draco::Vector4f(1.f, 2.f, 3.f, 0.f));
-
- const draco::VectorD<double, 1> vector1d(vector3f);
- ASSERT_EQ(vector1d[0], 1.0);
-}
-
-} // namespace
diff --git a/extern/draco/dracoenc/src/draco/draco_features.h b/extern/draco/dracoenc/src/draco/draco_features.h
deleted file mode 100644
index f067ca44dd0..00000000000
--- a/extern/draco/dracoenc/src/draco/draco_features.h
+++ /dev/null
@@ -1,8 +0,0 @@
-// GENERATED FILE -- DO NOT EDIT
-
-#ifndef DRACO_FEATURES_H_
-#define DRACO_FEATURES_H_
-
-#define DRACO_ATTRIBUTE_DEDUPLICATION_SUPPORTED
-
-#endif // DRACO_FEATURES_H_ \ No newline at end of file
diff --git a/extern/draco/dracoenc/src/draco/io/mesh_io.cc b/extern/draco/dracoenc/src/draco/io/mesh_io.cc
deleted file mode 100644
index 5e2f9f51d7a..00000000000
--- a/extern/draco/dracoenc/src/draco/io/mesh_io.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/io/mesh_io.h"
-
-#include <fstream>
-
-#include "draco/io/file_utils.h"
-#include "draco/io/obj_decoder.h"
-#include "draco/io/ply_decoder.h"
-
-namespace draco {
-
-StatusOr<std::unique_ptr<Mesh>> ReadMeshFromFile(const std::string &file_name) {
- const Options options;
- return ReadMeshFromFile(file_name, options);
-}
-
-StatusOr<std::unique_ptr<Mesh>> ReadMeshFromFile(const std::string &file_name,
- bool use_metadata) {
- Options options;
- options.SetBool("use_metadata", use_metadata);
- return ReadMeshFromFile(file_name, options);
-}
-
-StatusOr<std::unique_ptr<Mesh>> ReadMeshFromFile(const std::string &file_name,
- const Options &options) {
- std::unique_ptr<Mesh> mesh(new Mesh());
- // Analyze file extension.
- const std::string extension = LowercaseFileExtension(file_name);
- if (extension == "obj") {
- // Wavefront OBJ file format.
- ObjDecoder obj_decoder;
- obj_decoder.set_use_metadata(options.GetBool("use_metadata", false));
- const Status obj_status = obj_decoder.DecodeFromFile(file_name, mesh.get());
- if (!obj_status.ok())
- return obj_status;
- return std::move(mesh);
- }
- if (extension == "ply") {
- // Wavefront PLY file format.
- PlyDecoder ply_decoder;
- DRACO_RETURN_IF_ERROR(ply_decoder.DecodeFromFile(file_name, mesh.get()));
- return std::move(mesh);
- }
-
- // Otherwise not an obj file. Assume the file was encoded with one of the
- // draco encoding methods.
- std::ifstream is(file_name.c_str(), std::ios::binary);
- if (!is)
- return Status(Status::DRACO_ERROR, "Invalid input stream.");
- if (!ReadMeshFromStream(&mesh, is).good())
- return Status(Status::DRACO_ERROR,
- "Unknown error."); // Error reading the stream.
- return std::move(mesh);
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/io/mesh_io.h b/extern/draco/dracoenc/src/draco/io/mesh_io.h
deleted file mode 100644
index 15cfbb30b97..00000000000
--- a/extern/draco/dracoenc/src/draco/io/mesh_io.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#ifndef DRACO_MESH_MESH_IO_H_
-#define DRACO_MESH_MESH_IO_H_
-
-#include "draco/compression/config/compression_shared.h"
-#include "draco/compression/decode.h"
-#include "draco/compression/expert_encode.h"
-#include "draco/core/options.h"
-
-namespace draco {
-
-template <typename OutStreamT>
-OutStreamT WriteMeshIntoStream(const Mesh *mesh, OutStreamT &&os,
- MeshEncoderMethod method,
- const EncoderOptions &options) {
- EncoderBuffer buffer;
- EncoderOptions local_options = options;
- ExpertEncoder encoder(*mesh);
- encoder.Reset(local_options);
- encoder.SetEncodingMethod(method);
- if (!encoder.EncodeToBuffer(&buffer).ok()) {
- os.setstate(std::ios_base::badbit);
- return os;
- }
-
- os.write(static_cast<const char *>(buffer.data()), buffer.size());
-
- return os;
-}
-
-template <typename OutStreamT>
-OutStreamT WriteMeshIntoStream(const Mesh *mesh, OutStreamT &&os,
- MeshEncoderMethod method) {
- const EncoderOptions options = EncoderOptions::CreateDefaultOptions();
- return WriteMeshIntoStream(mesh, os, method, options);
-}
-
-template <typename OutStreamT>
-OutStreamT &WriteMeshIntoStream(const Mesh *mesh, OutStreamT &&os) {
- return WriteMeshIntoStream(mesh, os, MESH_EDGEBREAKER_ENCODING);
-}
-
-template <typename InStreamT>
-InStreamT &ReadMeshFromStream(std::unique_ptr<Mesh> *mesh, InStreamT &&is) {
- // Determine size of stream and write into a vector
- const auto start_pos = is.tellg();
- is.seekg(0, std::ios::end);
- const std::streampos is_size = is.tellg() - start_pos;
- is.seekg(start_pos);
- std::vector<char> data(is_size);
- is.read(&data[0], is_size);
-
- // Create a mesh from that data.
- DecoderBuffer buffer;
- buffer.Init(&data[0], data.size());
- Decoder decoder;
- auto statusor = decoder.DecodeMeshFromBuffer(&buffer);
- *mesh = std::move(statusor).value();
- if (!statusor.ok() || *mesh == nullptr) {
- is.setstate(std::ios_base::badbit);
- }
-
- return is;
-}
-
-// Reads a mesh from a file. The function automatically chooses the correct
-// decoder based on the extension of the files. Currently, .obj and .ply files
-// are supported. Other file extensions are processed by the default
-// draco::MeshDecoder.
-// Returns nullptr with an error status if the decoding failed.
-StatusOr<std::unique_ptr<Mesh>> ReadMeshFromFile(const std::string &file_name);
-
-// Reads a mesh from a file. The function does the same thing as the previous
-// one except using metadata to encode additional information when
-// |use_metadata| is set to true.
-// Returns nullptr with an error status if the decoding failed.
-StatusOr<std::unique_ptr<Mesh>> ReadMeshFromFile(const std::string &file_name,
- bool use_metadata);
-
-// Reads a mesh from a file. Reading is configured with |options|:
-// use_metadata : Read obj file info like material names and object names into
-// metadata. Default is false.
-// Returns nullptr with an error status if the decoding failed.
-StatusOr<std::unique_ptr<Mesh>> ReadMeshFromFile(const std::string &file_name,
- const Options &options);
-
-} // namespace draco
-
-#endif // DRACO_MESH_MESH_IO_H_
diff --git a/extern/draco/dracoenc/src/draco/io/obj_decoder.cc b/extern/draco/dracoenc/src/draco/io/obj_decoder.cc
deleted file mode 100644
index 88f470f8b4a..00000000000
--- a/extern/draco/dracoenc/src/draco/io/obj_decoder.cc
+++ /dev/null
@@ -1,689 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/io/obj_decoder.h"
-
-#include <cctype>
-#include <cmath>
-#include <fstream>
-
-#include "draco/io/file_utils.h"
-#include "draco/io/parser_utils.h"
-#include "draco/metadata/geometry_metadata.h"
-
-namespace draco {
-
-ObjDecoder::ObjDecoder()
- : counting_mode_(true),
- num_obj_faces_(0),
- num_positions_(0),
- num_tex_coords_(0),
- num_normals_(0),
- num_materials_(0),
- last_sub_obj_id_(0),
- pos_att_id_(-1),
- tex_att_id_(-1),
- norm_att_id_(-1),
- material_att_id_(-1),
- sub_obj_att_id_(-1),
- deduplicate_input_values_(true),
- last_material_id_(0),
- use_metadata_(false),
- out_mesh_(nullptr),
- out_point_cloud_(nullptr) {}
-
-Status ObjDecoder::DecodeFromFile(const std::string &file_name,
- Mesh *out_mesh) {
- out_mesh_ = out_mesh;
- return DecodeFromFile(file_name, static_cast<PointCloud *>(out_mesh));
-}
-
-Status ObjDecoder::DecodeFromFile(const std::string &file_name,
- PointCloud *out_point_cloud) {
- std::ifstream file(file_name, std::ios::binary);
- if (!file)
- return Status(Status::IO_ERROR);
- // Read the whole file into a buffer.
- auto pos0 = file.tellg();
- file.seekg(0, std::ios::end);
- auto file_size = file.tellg() - pos0;
- if (file_size == 0)
- return Status(Status::IO_ERROR);
- file.seekg(0, std::ios::beg);
- std::vector<char> data(file_size);
- file.read(&data[0], file_size);
- buffer_.Init(&data[0], file_size);
-
- out_point_cloud_ = out_point_cloud;
- input_file_name_ = file_name;
- return DecodeInternal();
-}
-
-Status ObjDecoder::DecodeFromBuffer(DecoderBuffer *buffer, Mesh *out_mesh) {
- out_mesh_ = out_mesh;
- return DecodeFromBuffer(buffer, static_cast<PointCloud *>(out_mesh));
-}
-
-Status ObjDecoder::DecodeFromBuffer(DecoderBuffer *buffer,
- PointCloud *out_point_cloud) {
- out_point_cloud_ = out_point_cloud;
- buffer_.Init(buffer->data_head(), buffer->remaining_size());
- return DecodeInternal();
-}
-
-Status ObjDecoder::DecodeInternal() {
- // In the first pass, count the number of different elements in the geometry.
- // In case the desired output is just a point cloud (i.e., when
- // out_mesh_ == nullptr) the decoder will ignore all information about the
- // connectivity that may be included in the source data.
- counting_mode_ = true;
- ResetCounters();
- material_name_to_id_.clear();
- last_sub_obj_id_ = 0;
- // Parse all lines.
- Status status(Status::OK);
- while (ParseDefinition(&status) && status.ok()) {
- }
- if (!status.ok())
- return status;
- bool use_identity_mapping = false;
- if (num_obj_faces_ == 0) {
- // Mesh has no faces. In this case we try to read the geometry as a point
- // cloud where every attribute entry is a point.
-
- // Ensure the number of all entries is same for all attributes.
- if (num_positions_ == 0)
- return Status(Status::DRACO_ERROR, "No position attribute");
- if (num_tex_coords_ > 0 && num_tex_coords_ != num_positions_)
- return Status(Status::DRACO_ERROR,
- "Invalid number of texture coordinates for a point cloud");
- if (num_normals_ > 0 && num_normals_ != num_positions_)
- return Status(Status::DRACO_ERROR,
- "Invalid number of normals for a point cloud");
-
- out_mesh_ = nullptr; // Treat the output geometry as a point cloud.
- use_identity_mapping = true;
- }
-
- // Initialize point cloud and mesh properties.
- if (out_mesh_) {
- // Start decoding a mesh with the given number of faces. For point clouds we
- // silently ignore all data about the mesh connectivity.
- out_mesh_->SetNumFaces(num_obj_faces_);
- }
- if (num_obj_faces_ > 0) {
- out_point_cloud_->set_num_points(3 * num_obj_faces_);
- } else {
- out_point_cloud_->set_num_points(num_positions_);
- }
-
- // Add attributes if they are present in the input data.
- if (num_positions_ > 0) {
- GeometryAttribute va;
- va.Init(GeometryAttribute::POSITION, nullptr, 3, DT_FLOAT32, false,
- sizeof(float) * 3, 0);
- pos_att_id_ = out_point_cloud_->AddAttribute(va, use_identity_mapping,
- num_positions_);
- }
- if (num_tex_coords_ > 0) {
- GeometryAttribute va;
- va.Init(GeometryAttribute::TEX_COORD, nullptr, 2, DT_FLOAT32, false,
- sizeof(float) * 2, 0);
- tex_att_id_ = out_point_cloud_->AddAttribute(va, use_identity_mapping,
- num_tex_coords_);
- }
- if (num_normals_ > 0) {
- GeometryAttribute va;
- va.Init(GeometryAttribute::NORMAL, nullptr, 3, DT_FLOAT32, false,
- sizeof(float) * 3, 0);
- norm_att_id_ =
- out_point_cloud_->AddAttribute(va, use_identity_mapping, num_normals_);
- }
- if (num_materials_ > 0 && num_obj_faces_ > 0) {
- GeometryAttribute va;
- const auto geometry_attribute_type = GeometryAttribute::GENERIC;
- if (num_materials_ < 256) {
- va.Init(geometry_attribute_type, nullptr, 1, DT_UINT8, false, 1, 0);
- } else if (num_materials_ < (1 << 16)) {
- va.Init(geometry_attribute_type, nullptr, 1, DT_UINT16, false, 2, 0);
- } else {
- va.Init(geometry_attribute_type, nullptr, 1, DT_UINT32, false, 4, 0);
- }
- material_att_id_ =
- out_point_cloud_->AddAttribute(va, false, num_materials_);
-
- // Fill the material entries.
- for (int i = 0; i < num_materials_; ++i) {
- const AttributeValueIndex avi(i);
- out_point_cloud_->attribute(material_att_id_)->SetAttributeValue(avi, &i);
- }
-
- if (use_metadata_) {
- // Use metadata to store the name of materials.
- std::unique_ptr<AttributeMetadata> material_metadata =
- std::unique_ptr<AttributeMetadata>(new AttributeMetadata());
- material_metadata->AddEntryString("name", "material");
- // Add all material names.
- for (const auto &itr : material_name_to_id_) {
- material_metadata->AddEntryInt(itr.first, itr.second);
- }
- if (!material_file_name_.empty()) {
- material_metadata->AddEntryString("file_name", material_file_name_);
- }
-
- out_point_cloud_->AddAttributeMetadata(material_att_id_,
- std::move(material_metadata));
- }
- }
- if (!obj_name_to_id_.empty() && num_obj_faces_ > 0) {
- GeometryAttribute va;
- if (obj_name_to_id_.size() < 256) {
- va.Init(GeometryAttribute::GENERIC, nullptr, 1, DT_UINT8, false, 1, 0);
- } else if (obj_name_to_id_.size() < (1 << 16)) {
- va.Init(GeometryAttribute::GENERIC, nullptr, 1, DT_UINT16, false, 2, 0);
- } else {
- va.Init(GeometryAttribute::GENERIC, nullptr, 1, DT_UINT32, false, 4, 0);
- }
- sub_obj_att_id_ = out_point_cloud_->AddAttribute(
- va, false, static_cast<uint32_t>(obj_name_to_id_.size()));
- // Fill the sub object id entries.
- for (const auto &itr : obj_name_to_id_) {
- const AttributeValueIndex i(itr.second);
- out_point_cloud_->attribute(sub_obj_att_id_)->SetAttributeValue(i, &i);
- }
- if (use_metadata_) {
- // Use metadata to store the name of materials.
- std::unique_ptr<AttributeMetadata> sub_obj_metadata =
- std::unique_ptr<AttributeMetadata>(new AttributeMetadata());
- sub_obj_metadata->AddEntryString("name", "sub_obj");
- // Add all sub object names.
- for (const auto &itr : obj_name_to_id_) {
- const AttributeValueIndex i(itr.second);
- sub_obj_metadata->AddEntryInt(itr.first, itr.second);
- }
- out_point_cloud_->AddAttributeMetadata(sub_obj_att_id_,
- std::move(sub_obj_metadata));
- }
- }
-
- // Perform a second iteration of parsing and fill all the data.
- counting_mode_ = false;
- ResetCounters();
- // Start parsing from the beginning of the buffer again.
- buffer()->StartDecodingFrom(0);
- while (ParseDefinition(&status) && status.ok()) {
- }
- if (!status.ok())
- return status;
- if (out_mesh_) {
- // Add faces with identity mapping between vertex and corner indices.
- // Duplicate vertices will get removed later.
- Mesh::Face face;
- for (FaceIndex i(0); i < num_obj_faces_; ++i) {
- for (int c = 0; c < 3; ++c)
- face[c] = 3 * i.value() + c;
- out_mesh_->SetFace(i, face);
- }
- }
-
-#ifdef DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED
- if (deduplicate_input_values_) {
- out_point_cloud_->DeduplicateAttributeValues();
- }
-#endif
-#ifdef DRACO_ATTRIBUTE_INDICES_DEDUPLICATION_SUPPORTED
- out_point_cloud_->DeduplicatePointIds();
-#endif
- return status;
-}
-
-void ObjDecoder::ResetCounters() {
- num_obj_faces_ = 0;
- num_positions_ = 0;
- num_tex_coords_ = 0;
- num_normals_ = 0;
- last_material_id_ = 0;
- last_sub_obj_id_ = 0;
-}
-
-bool ObjDecoder::ParseDefinition(Status *status) {
- char c;
- parser::SkipWhitespace(buffer());
- if (!buffer()->Peek(&c)) {
- // End of file reached?.
- return false;
- }
- if (c == '#') {
- // Comment, ignore the line.
- parser::SkipLine(buffer());
- return true;
- }
- if (ParseVertexPosition(status))
- return true;
- if (ParseNormal(status))
- return true;
- if (ParseTexCoord(status))
- return true;
- if (ParseFace(status))
- return true;
- if (ParseMaterial(status))
- return true;
- if (ParseMaterialLib(status))
- return true;
- if (ParseObject(status))
- return true;
- // No known definition was found. Ignore the line.
- parser::SkipLine(buffer());
- return true;
-}
-
-bool ObjDecoder::ParseVertexPosition(Status *status) {
- std::array<char, 2> c;
- if (!buffer()->Peek(&c)) {
- return false;
- }
- if (c[0] != 'v' || c[1] != ' ')
- return false;
- // Vertex definition found!
- buffer()->Advance(2);
- if (!counting_mode_) {
- // Parse three float numbers for vertex position coordinates.
- float val[3];
- for (int i = 0; i < 3; ++i) {
- parser::SkipWhitespace(buffer());
- if (!parser::ParseFloat(buffer(), val + i)) {
- *status = Status(Status::DRACO_ERROR, "Failed to parse a float number");
- // The definition is processed so return true.
- return true;
- }
- }
- out_point_cloud_->attribute(pos_att_id_)
- ->SetAttributeValue(AttributeValueIndex(num_positions_), val);
- }
- ++num_positions_;
- parser::SkipLine(buffer());
- return true;
-}
-
-bool ObjDecoder::ParseNormal(Status *status) {
- std::array<char, 2> c;
- if (!buffer()->Peek(&c)) {
- return false;
- }
- if (c[0] != 'v' || c[1] != 'n')
- return false;
- // Normal definition found!
- buffer()->Advance(2);
- if (!counting_mode_) {
- // Parse three float numbers for the normal vector.
- float val[3];
- for (int i = 0; i < 3; ++i) {
- parser::SkipWhitespace(buffer());
- if (!parser::ParseFloat(buffer(), val + i)) {
- *status = Status(Status::DRACO_ERROR, "Failed to parse a float number");
- // The definition is processed so return true.
- return true;
- }
- }
- out_point_cloud_->attribute(norm_att_id_)
- ->SetAttributeValue(AttributeValueIndex(num_normals_), val);
- }
- ++num_normals_;
- parser::SkipLine(buffer());
- return true;
-}
-
-bool ObjDecoder::ParseTexCoord(Status *status) {
- std::array<char, 2> c;
- if (!buffer()->Peek(&c)) {
- return false;
- }
- if (c[0] != 'v' || c[1] != 't')
- return false;
- // Texture coord definition found!
- buffer()->Advance(2);
- if (!counting_mode_) {
- // Parse two float numbers for the texture coordinate.
- float val[2];
- for (int i = 0; i < 2; ++i) {
- parser::SkipWhitespace(buffer());
- if (!parser::ParseFloat(buffer(), val + i)) {
- *status = Status(Status::DRACO_ERROR, "Failed to parse a float number");
- // The definition is processed so return true.
- return true;
- }
- }
- out_point_cloud_->attribute(tex_att_id_)
- ->SetAttributeValue(AttributeValueIndex(num_tex_coords_), val);
- }
- ++num_tex_coords_;
- parser::SkipLine(buffer());
- return true;
-}
-
-bool ObjDecoder::ParseFace(Status *status) {
- char c;
- if (!buffer()->Peek(&c)) {
- return false;
- }
- if (c != 'f')
- return false;
- // Face definition found!
- buffer()->Advance(1);
- if (!counting_mode_) {
- std::array<int32_t, 3> indices[4];
- // Parse face indices (we try to look for up to four to support quads).
- int num_valid_indices = 0;
- for (int i = 0; i < 4; ++i) {
- if (!ParseVertexIndices(&indices[i])) {
- if (i == 3) {
- break; // It's OK if there is no fourth vertex index.
- }
- *status = Status(Status::DRACO_ERROR, "Failed to parse vertex indices");
- return true;
- }
- ++num_valid_indices;
- }
- // Process the first face.
- for (int i = 0; i < 3; ++i) {
- const PointIndex vert_id(3 * num_obj_faces_ + i);
- MapPointToVertexIndices(vert_id, indices[i]);
- }
- ++num_obj_faces_;
- if (num_valid_indices == 4) {
- // Add an additional triangle for the quad.
- //
- // 3----2
- // | / |
- // | / |
- // 0----1
- //
- const PointIndex vert_id(3 * num_obj_faces_);
- MapPointToVertexIndices(vert_id, indices[0]);
- MapPointToVertexIndices(vert_id + 1, indices[2]);
- MapPointToVertexIndices(vert_id + 2, indices[3]);
- ++num_obj_faces_;
- }
- } else {
- // We are in the counting mode.
- // We need to determine how many triangles are in the obj face.
- // Go over the line and check how many gaps there are between non-empty
- // sub-strings.
- parser::SkipWhitespace(buffer());
- int num_indices = 0;
- bool is_end = false;
- while (buffer()->Peek(&c) && c != '\n') {
- if (parser::PeekWhitespace(buffer(), &is_end)) {
- buffer()->Advance(1);
- } else {
- // Non-whitespace reached.. assume it's index declaration, skip it.
- num_indices++;
- while (!parser::PeekWhitespace(buffer(), &is_end) && !is_end) {
- buffer()->Advance(1);
- }
- }
- }
- if (num_indices < 3 || num_indices > 4) {
- *status =
- Status(Status::DRACO_ERROR, "Invalid number of indices on a face");
- return false;
- }
- // Either one or two new triangles.
- num_obj_faces_ += num_indices - 2;
- }
- parser::SkipLine(buffer());
- return true;
-}
-
-bool ObjDecoder::ParseMaterialLib(Status *status) {
- // Allow only one material library per file for now.
- if (material_name_to_id_.size() > 0)
- return false;
- std::array<char, 6> c;
- if (!buffer()->Peek(&c)) {
- return false;
- }
- if (std::memcmp(&c[0], "mtllib", 6) != 0)
- return false;
- buffer()->Advance(6);
- DecoderBuffer line_buffer = parser::ParseLineIntoDecoderBuffer(buffer());
- parser::SkipWhitespace(&line_buffer);
- material_file_name_.clear();
- if (!parser::ParseString(&line_buffer, &material_file_name_)) {
- *status = Status(Status::DRACO_ERROR, "Failed to parse material file name");
- return true;
- }
- parser::SkipLine(&line_buffer);
-
- if (material_file_name_.size() > 0) {
- if (!ParseMaterialFile(material_file_name_, status)) {
- // Silently ignore problems with material files for now.
- return true;
- }
- }
- return true;
-}
-
-bool ObjDecoder::ParseMaterial(Status * /* status */) {
- // In second pass, skip when we don't use materials.
- if (!counting_mode_ && material_att_id_ < 0)
- return false;
- std::array<char, 6> c;
- if (!buffer()->Peek(&c)) {
- return false;
- }
- if (std::memcmp(&c[0], "usemtl", 6) != 0)
- return false;
- buffer()->Advance(6);
- DecoderBuffer line_buffer = parser::ParseLineIntoDecoderBuffer(buffer());
- parser::SkipWhitespace(&line_buffer);
- std::string mat_name;
- parser::ParseLine(&line_buffer, &mat_name);
- if (mat_name.length() == 0)
- return false;
- auto it = material_name_to_id_.find(mat_name);
- if (it == material_name_to_id_.end()) {
- // In first pass, materials found in obj that's not in the .mtl file
- // will be added to the list.
- last_material_id_ = num_materials_;
- material_name_to_id_[mat_name] = num_materials_++;
-
- return true;
- }
- last_material_id_ = it->second;
- return true;
-}
-
-bool ObjDecoder::ParseObject(Status *status) {
- std::array<char, 2> c;
- if (!buffer()->Peek(&c)) {
- return false;
- }
- if (std::memcmp(&c[0], "o ", 2) != 0)
- return false;
- buffer()->Advance(1);
- DecoderBuffer line_buffer = parser::ParseLineIntoDecoderBuffer(buffer());
- parser::SkipWhitespace(&line_buffer);
- std::string obj_name;
- if (!parser::ParseString(&line_buffer, &obj_name))
- return false;
- if (obj_name.length() == 0)
- return true; // Ignore empty name entries.
- auto it = obj_name_to_id_.find(obj_name);
- if (it == obj_name_to_id_.end()) {
- const int num_obj = static_cast<int>(obj_name_to_id_.size());
- obj_name_to_id_[obj_name] = num_obj;
- last_sub_obj_id_ = num_obj;
- } else {
- last_sub_obj_id_ = it->second;
- }
- return true;
-}
-
-bool ObjDecoder::ParseVertexIndices(std::array<int32_t, 3> *out_indices) {
- // Parsed attribute indices can be in format:
- // 1. POS_INDEX
- // 2. POS_INDEX/TEX_COORD_INDEX
- // 3. POS_INDEX/TEX_COORD_INDEX/NORMAL_INDEX
- // 4. POS_INDEX//NORMAL_INDEX
- parser::SkipCharacters(buffer(), " \t");
- if (!parser::ParseSignedInt(buffer(), &(*out_indices)[0]) ||
- (*out_indices)[0] == 0)
- return false; // Position index must be present and valid.
- (*out_indices)[1] = (*out_indices)[2] = 0;
- char ch;
- if (!buffer()->Peek(&ch))
- return true; // It may be OK if we cannot read any more characters.
- if (ch != '/')
- return true;
- buffer()->Advance(1);
- // Check if we should skip texture index or not.
- if (!buffer()->Peek(&ch))
- return false; // Here, we should be always able to read the next char.
- if (ch != '/') {
- // Must be texture coord index.
- if (!parser::ParseSignedInt(buffer(), &(*out_indices)[1]) ||
- (*out_indices)[1] == 0)
- return false; // Texture index must be present and valid.
- }
- if (!buffer()->Peek(&ch))
- return true;
- if (ch == '/') {
- buffer()->Advance(1);
- // Read normal index.
- if (!parser::ParseSignedInt(buffer(), &(*out_indices)[2]) ||
- (*out_indices)[2] == 0)
- return false; // Normal index must be present and valid.
- }
- return true;
-}
-
-void ObjDecoder::MapPointToVertexIndices(
- PointIndex vert_id, const std::array<int32_t, 3> &indices) {
- // Use face entries to store mapping between vertex and attribute indices
- // (positions, texture coordinates and normal indices).
- // Any given index is used when indices[x] != 0. For positive values, the
- // point is mapped directly to the specified attribute index. Negative input
- // indices indicate addressing from the last element (e.g. -1 is the last
- // attribute value of a given type, -2 the second last, etc.).
- if (indices[0] > 0) {
- out_point_cloud_->attribute(pos_att_id_)
- ->SetPointMapEntry(vert_id, AttributeValueIndex(indices[0] - 1));
- } else if (indices[0] < 0) {
- out_point_cloud_->attribute(pos_att_id_)
- ->SetPointMapEntry(vert_id,
- AttributeValueIndex(num_positions_ + indices[0]));
- }
-
- if (tex_att_id_ >= 0) {
- if (indices[1] > 0) {
- out_point_cloud_->attribute(tex_att_id_)
- ->SetPointMapEntry(vert_id, AttributeValueIndex(indices[1] - 1));
- } else if (indices[1] < 0) {
- out_point_cloud_->attribute(tex_att_id_)
- ->SetPointMapEntry(vert_id,
- AttributeValueIndex(num_tex_coords_ + indices[1]));
- } else {
- // Texture index not provided but expected. Insert 0 entry as the
- // default value.
- out_point_cloud_->attribute(tex_att_id_)
- ->SetPointMapEntry(vert_id, AttributeValueIndex(0));
- }
- }
-
- if (norm_att_id_ >= 0) {
- if (indices[2] > 0) {
- out_point_cloud_->attribute(norm_att_id_)
- ->SetPointMapEntry(vert_id, AttributeValueIndex(indices[2] - 1));
- } else if (indices[2] < 0) {
- out_point_cloud_->attribute(norm_att_id_)
- ->SetPointMapEntry(vert_id,
- AttributeValueIndex(num_normals_ + indices[2]));
- } else {
- // Normal index not provided but expected. Insert 0 entry as the default
- // value.
- out_point_cloud_->attribute(norm_att_id_)
- ->SetPointMapEntry(vert_id, AttributeValueIndex(0));
- }
- }
-
- // Assign material index to the point if it is available.
- if (material_att_id_ >= 0) {
- out_point_cloud_->attribute(material_att_id_)
- ->SetPointMapEntry(vert_id, AttributeValueIndex(last_material_id_));
- }
-
- // Assign sub-object index to the point if it is available.
- if (sub_obj_att_id_ >= 0) {
- out_point_cloud_->attribute(sub_obj_att_id_)
- ->SetPointMapEntry(vert_id, AttributeValueIndex(last_sub_obj_id_));
- }
-}
-
-bool ObjDecoder::ParseMaterialFile(const std::string &file_name,
- Status *status) {
- const std::string full_path = GetFullPath(file_name, input_file_name_);
- std::ifstream file(full_path, std::ios::binary);
- if (!file)
- return false;
- // Read the whole file into a buffer.
- file.seekg(0, std::ios::end);
- const std::string::size_type file_size = file.tellg();
- if (file_size == 0)
- return false;
- file.seekg(0, std::ios::beg);
- std::vector<char> data(file_size);
- file.read(&data[0], file_size);
-
- // Backup the original decoder buffer.
- DecoderBuffer old_buffer = buffer_;
-
- buffer_.Init(&data[0], file_size);
-
- num_materials_ = 0;
- while (ParseMaterialFileDefinition(status)) {
- }
-
- // Restore the original buffer.
- buffer_ = old_buffer;
- return true;
-}
-
-bool ObjDecoder::ParseMaterialFileDefinition(Status * /* status */) {
- char c;
- parser::SkipWhitespace(buffer());
- if (!buffer()->Peek(&c)) {
- // End of file reached?.
- return false;
- }
- if (c == '#') {
- // Comment, ignore the line.
- parser::SkipLine(buffer());
- return true;
- }
- std::string str;
- if (!parser::ParseString(buffer(), &str))
- return false;
- if (str == "newmtl") {
- parser::SkipWhitespace(buffer());
- parser::ParseLine(buffer(), &str);
- if (str.empty())
- return false;
- // Add new material to our map.
- material_name_to_id_[str] = num_materials_++;
- }
- return true;
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/io/obj_decoder.h b/extern/draco/dracoenc/src/draco/io/obj_decoder.h
deleted file mode 100644
index 33b9dee2414..00000000000
--- a/extern/draco/dracoenc/src/draco/io/obj_decoder.h
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#ifndef DRACO_IO_OBJ_DECODER_H_
-#define DRACO_IO_OBJ_DECODER_H_
-
-#include <string>
-#include <unordered_map>
-
-#include "draco/draco_features.h"
-
-#include "draco/core/decoder_buffer.h"
-#include "draco/core/status.h"
-#include "draco/mesh/mesh.h"
-
-namespace draco {
-
-// Decodes a Wavefront OBJ file into draco::Mesh (or draco::PointCloud if the
-// connectivity data is not needed).. This decoder can handle decoding of
-// positions, texture coordinates, normals and triangular faces.
-// All other geometry properties are ignored.
-class ObjDecoder {
- public:
- ObjDecoder();
-
- // Decodes an obj file stored in the input file.
- // Returns nullptr if the decoding failed.
- Status DecodeFromFile(const std::string &file_name, Mesh *out_mesh);
- Status DecodeFromFile(const std::string &file_name,
- PointCloud *out_point_cloud);
-
- Status DecodeFromBuffer(DecoderBuffer *buffer, Mesh *out_mesh);
- Status DecodeFromBuffer(DecoderBuffer *buffer, PointCloud *out_point_cloud);
-
- // Flag that can be used to turn on/off deduplication of input values.
- // This should be disabled only when we are sure that the input data does not
- // contain any duplicate entries.
- // Default: true
- void set_deduplicate_input_values(bool v) { deduplicate_input_values_ = v; }
- // Flag for whether using metadata to record other information in the obj
- // file, e.g. material names, object names.
- void set_use_metadata(bool flag) { use_metadata_ = flag; }
-
- protected:
- Status DecodeInternal();
- DecoderBuffer *buffer() { return &buffer_; }
-
- private:
- // Resets internal counters for attributes and faces.
- void ResetCounters();
-
- // Parses the next mesh property definition (position, tex coord, normal, or
- // face). If the parsed data is unrecognized, it will be skipped.
- // Returns false when the end of file was reached.
- bool ParseDefinition(Status *status);
-
- // Attempts to parse definition of position, normal, tex coord, or face
- // respectively.
- // Returns false when the parsed data didn't contain the given definition.
- bool ParseVertexPosition(Status *status);
- bool ParseNormal(Status *status);
- bool ParseTexCoord(Status *status);
- bool ParseFace(Status *status);
- bool ParseMaterialLib(Status *status);
- bool ParseMaterial(Status *status);
- bool ParseObject(Status *status);
-
- // Parses triplet of position, tex coords and normal indices.
- // Returns false on error.
- bool ParseVertexIndices(std::array<int32_t, 3> *out_indices);
-
- // Maps specified point index to the parsed vertex indices (triplet of
- // position, texture coordinate, and normal indices) .
- void MapPointToVertexIndices(PointIndex pi,
- const std::array<int32_t, 3> &indices);
-
- // Parses material file definitions from a separate file.
- bool ParseMaterialFile(const std::string &file_name, Status *status);
- bool ParseMaterialFileDefinition(Status *status);
-
- // If set to true, the parser will count the number of various definitions
- // but it will not parse the actual data or add any new entries to the mesh.
- bool counting_mode_;
- int num_obj_faces_;
- int num_positions_;
- int num_tex_coords_;
- int num_normals_;
- int num_materials_;
- int last_sub_obj_id_;
-
- int pos_att_id_;
- int tex_att_id_;
- int norm_att_id_;
- int material_att_id_;
- int sub_obj_att_id_; // Attribute id for storing sub-objects.
-
- bool deduplicate_input_values_;
-
- int last_material_id_;
- std::string material_file_name_;
-
- std::string input_file_name_;
-
- std::unordered_map<std::string, int> material_name_to_id_;
- std::unordered_map<std::string, int> obj_name_to_id_;
-
- bool use_metadata_;
-
- DecoderBuffer buffer_;
-
- // Data structure that stores the decoded data. |out_point_cloud_| must be
- // always set but |out_mesh_| is optional.
- Mesh *out_mesh_;
- PointCloud *out_point_cloud_;
-};
-
-} // namespace draco
-
-#endif // DRACO_IO_OBJ_DECODER_H_
diff --git a/extern/draco/dracoenc/src/draco/io/obj_decoder_test.cc b/extern/draco/dracoenc/src/draco/io/obj_decoder_test.cc
deleted file mode 100644
index 3d319a9d44a..00000000000
--- a/extern/draco/dracoenc/src/draco/io/obj_decoder_test.cc
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include <sstream>
-
-#include "draco/core/draco_test_base.h"
-#include "draco/core/draco_test_utils.h"
-#include "draco/io/obj_decoder.h"
-
-namespace draco {
-
-class ObjDecoderTest : public ::testing::Test {
- protected:
- template <class Geometry>
- std::unique_ptr<Geometry> DecodeObj(const std::string &file_name) const {
- return DecodeObj<Geometry>(file_name, false);
- }
-
- template <class Geometry>
- std::unique_ptr<Geometry> DecodeObj(const std::string &file_name,
- bool deduplicate_input_values) const {
- const std::string path = GetTestFileFullPath(file_name);
- ObjDecoder decoder;
- decoder.set_deduplicate_input_values(deduplicate_input_values);
- std::unique_ptr<Geometry> geometry(new Geometry());
- if (!decoder.DecodeFromFile(path, geometry.get()).ok())
- return nullptr;
- return geometry;
- }
-
- template <class Geometry>
- std::unique_ptr<Geometry> DecodeObjWithMetadata(
- const std::string &file_name) const {
- const std::string path = GetTestFileFullPath(file_name);
- ObjDecoder decoder;
- decoder.set_use_metadata(true);
- std::unique_ptr<Geometry> geometry(new Geometry());
- if (!decoder.DecodeFromFile(path, geometry.get()).ok())
- return nullptr;
- return geometry;
- }
-
- void test_decoding(const std::string &file_name) {
- const std::unique_ptr<Mesh> mesh(DecodeObj<Mesh>(file_name));
- ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
- ASSERT_GT(mesh->num_faces(), 0);
-
- const std::unique_ptr<PointCloud> pc(DecodeObj<PointCloud>(file_name));
- ASSERT_NE(pc, nullptr) << "Failed to load test model " << file_name;
- ASSERT_GT(pc->num_points(), 0);
- }
-};
-
-TEST_F(ObjDecoderTest, ExtraVertexOBJ) {
- const std::string file_name = "extra_vertex.obj";
- test_decoding(file_name);
-}
-
-TEST_F(ObjDecoderTest, PartialAttributesOBJ) {
- const std::string file_name = "cube_att_partial.obj";
- test_decoding(file_name);
-}
-
-TEST_F(ObjDecoderTest, SubObjects) {
- // Tests loading an Obj with sub objects.
- const std::string file_name = "cube_att_sub_o.obj";
- const std::unique_ptr<Mesh> mesh(DecodeObj<Mesh>(file_name));
- ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
- ASSERT_GT(mesh->num_faces(), 0);
-
- // A sub object attribute should be the fourth attribute of the mesh (in this
- // case).
- ASSERT_EQ(mesh->num_attributes(), 4);
- ASSERT_EQ(mesh->attribute(3)->attribute_type(), GeometryAttribute::GENERIC);
- // There should be 3 different sub objects used in the model.
- ASSERT_EQ(mesh->attribute(3)->size(), 3);
- // Verify that the sub object attribute has unique id == 3.
- ASSERT_EQ(mesh->attribute(3)->unique_id(), 3);
-}
-
-TEST_F(ObjDecoderTest, SubObjectsWithMetadata) {
- // Tests loading an Obj with sub objects.
- const std::string file_name = "cube_att_sub_o.obj";
- const std::unique_ptr<Mesh> mesh(DecodeObjWithMetadata<Mesh>(file_name));
- ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
- ASSERT_GT(mesh->num_faces(), 0);
-
- ASSERT_EQ(mesh->num_attributes(), 4);
- ASSERT_EQ(mesh->attribute(3)->attribute_type(), GeometryAttribute::GENERIC);
- // There should be 3 different sub objects used in the model.
- ASSERT_EQ(mesh->attribute(3)->size(), 3);
-
- // Test material names stored in metadata.
- ASSERT_NE(mesh->GetMetadata(), nullptr);
- ASSERT_NE(mesh->GetAttributeMetadataByAttributeId(3), nullptr);
- int32_t sub_obj_id = 0;
- ASSERT_TRUE(mesh->GetAttributeMetadataByAttributeId(3)->GetEntryInt(
- "obj2", &sub_obj_id));
- ASSERT_EQ(sub_obj_id, 2);
-}
-
-TEST_F(ObjDecoderTest, QuadOBJ) {
- // Tests loading an Obj with quad faces.
- const std::string file_name = "cube_quads.obj";
- const std::unique_ptr<Mesh> mesh(DecodeObj<Mesh>(file_name));
- ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
- ASSERT_EQ(mesh->num_faces(), 12);
-
- ASSERT_EQ(mesh->num_attributes(), 3);
- ASSERT_EQ(mesh->num_points(), 4 * 6); // Four points per quad face.
-}
-
-TEST_F(ObjDecoderTest, ComplexPolyOBJ) {
- // Tests that we fail to load an obj with complex polygon (expected failure).
- const std::string file_name = "invalid/complex_poly.obj";
- const std::unique_ptr<Mesh> mesh(DecodeObj<Mesh>(file_name));
- ASSERT_EQ(mesh, nullptr);
-}
-
-TEST_F(ObjDecoderTest, EmptyNameOBJ) {
- // Tests that we load an obj file that has an sub-object defined with an empty
- // name.
- const std::string file_name = "empty_name.obj";
- const std::unique_ptr<Mesh> mesh(DecodeObj<Mesh>(file_name));
- ASSERT_NE(mesh, nullptr);
- ASSERT_EQ(mesh->num_attributes(), 1);
- // Three valid entries in the attribute are expected.
- ASSERT_EQ(mesh->attribute(0)->size(), 3);
-}
-
-TEST_F(ObjDecoderTest, PointCloudOBJ) {
- // Tests that we load an obj file that does not contain any faces.
- const std::string file_name = "test_lines.obj";
- const std::unique_ptr<Mesh> mesh(DecodeObj<Mesh>(file_name, false));
- ASSERT_NE(mesh, nullptr);
- ASSERT_EQ(mesh->num_faces(), 0);
- ASSERT_EQ(mesh->num_attributes(), 1);
- ASSERT_EQ(mesh->attribute(0)->size(), 484);
-}
-
-TEST_F(ObjDecoderTest, WrongAttributeMapping) {
- // Tests that we load an obj file that contains invalid mapping between
- // attribute indices and values. In such case the invalid indices should be
- // ignored.
- const std::string file_name = "test_wrong_attribute_mapping.obj";
- const std::unique_ptr<Mesh> mesh(DecodeObj<Mesh>(file_name, false));
- ASSERT_NE(mesh, nullptr);
- ASSERT_EQ(mesh->num_faces(), 1);
- ASSERT_EQ(mesh->num_attributes(), 1);
- ASSERT_EQ(mesh->attribute(0)->size(), 3);
-}
-
-TEST_F(ObjDecoderTest, TestObjDecodingAll) {
- // test if we can read all obj that are currently in test folder.
- test_decoding("bunny_norm.obj");
- // test_decoding("complex_poly.obj"); // not supported see test above
- test_decoding("cube_att.obj");
- test_decoding("cube_att_partial.obj");
- test_decoding("cube_att_sub_o.obj");
- test_decoding("cube_quads.obj");
- test_decoding("cube_subd.obj");
- test_decoding("eof_test.obj");
- test_decoding("extra_vertex.obj");
- test_decoding("mat_test.obj");
- test_decoding("one_face_123.obj");
- test_decoding("one_face_312.obj");
- test_decoding("one_face_321.obj");
- test_decoding("sphere.obj");
- test_decoding("test_nm.obj");
- test_decoding("test_nm_trans.obj");
- test_decoding("test_sphere.obj");
- test_decoding("three_faces_123.obj");
- test_decoding("three_faces_312.obj");
- test_decoding("two_faces_123.obj");
- test_decoding("two_faces_312.obj");
- test_decoding("inf_nan.obj");
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/io/obj_encoder.cc b/extern/draco/dracoenc/src/draco/io/obj_encoder.cc
deleted file mode 100644
index 807506e3536..00000000000
--- a/extern/draco/dracoenc/src/draco/io/obj_encoder.cc
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/io/obj_encoder.h"
-
-#include <fstream>
-
-#include "draco/metadata/geometry_metadata.h"
-
-namespace draco {
-
-ObjEncoder::ObjEncoder()
- : pos_att_(nullptr),
- tex_coord_att_(nullptr),
- normal_att_(nullptr),
- material_att_(nullptr),
- sub_obj_att_(nullptr),
- out_buffer_(nullptr),
- in_point_cloud_(nullptr),
- in_mesh_(nullptr),
- current_sub_obj_id_(-1),
- current_material_id_(-1) {}
-
-bool ObjEncoder::EncodeToFile(const PointCloud &pc,
- const std::string &file_name) {
- std::ofstream file(file_name);
- if (!file)
- return false; // File could not be opened.
- file_name_ = file_name;
- // Encode the mesh into a buffer.
- EncoderBuffer buffer;
- if (!EncodeToBuffer(pc, &buffer))
- return false;
- // Write the buffer into the file.
- file.write(buffer.data(), buffer.size());
- return true;
-}
-
-bool ObjEncoder::EncodeToFile(const Mesh &mesh, const std::string &file_name) {
- in_mesh_ = &mesh;
- return EncodeToFile(static_cast<const PointCloud &>(mesh), file_name);
-}
-
-bool ObjEncoder::EncodeToBuffer(const PointCloud &pc,
- EncoderBuffer *out_buffer) {
- in_point_cloud_ = &pc;
- out_buffer_ = out_buffer;
- if (!EncodeInternal())
- return ExitAndCleanup(false);
- return ExitAndCleanup(true);
-}
-
-bool ObjEncoder::EncodeToBuffer(const Mesh &mesh, EncoderBuffer *out_buffer) {
- in_mesh_ = &mesh;
- return EncodeToBuffer(static_cast<const PointCloud &>(mesh), out_buffer);
-}
-
-bool ObjEncoder::EncodeInternal() {
- pos_att_ = nullptr;
- tex_coord_att_ = nullptr;
- normal_att_ = nullptr;
- material_att_ = nullptr;
- sub_obj_att_ = nullptr;
- current_sub_obj_id_ = -1;
- current_material_id_ = -1;
- if (!GetSubObjects())
- return false;
- if (!EncodeMaterialFileName())
- return false;
- if (!EncodePositions())
- return false;
- if (!EncodeTextureCoordinates())
- return false;
- if (!EncodeNormals())
- return false;
- if (in_mesh_ && !EncodeFaces())
- return false;
- return true;
-}
-
-bool ObjEncoder::ExitAndCleanup(bool return_value) {
- in_mesh_ = nullptr;
- in_point_cloud_ = nullptr;
- out_buffer_ = nullptr;
- pos_att_ = nullptr;
- tex_coord_att_ = nullptr;
- normal_att_ = nullptr;
- material_att_ = nullptr;
- sub_obj_att_ = nullptr;
- current_sub_obj_id_ = -1;
- current_material_id_ = -1;
- file_name_.clear();
- return return_value;
-}
-
-bool ObjEncoder::GetSubObjects() {
- const GeometryMetadata *pc_metadata = in_point_cloud_->GetMetadata();
- if (!pc_metadata)
- return true;
- const AttributeMetadata *sub_obj_metadata =
- pc_metadata->GetAttributeMetadataByStringEntry("name", "sub_obj");
- if (!sub_obj_metadata)
- return true;
- sub_obj_id_to_name_.clear();
- for (const auto &entry : sub_obj_metadata->entries()) {
- // Sub-object id must be int.
- int value = 0;
- if (!entry.second.GetValue(&value))
- continue;
- sub_obj_id_to_name_[value] = entry.first;
- }
- sub_obj_att_ = in_point_cloud_->GetAttributeByUniqueId(
- sub_obj_metadata->att_unique_id());
- if (sub_obj_att_ == nullptr || sub_obj_att_->size() == 0)
- return false;
- return true;
-}
-
-bool ObjEncoder::EncodeMaterialFileName() {
- const GeometryMetadata *pc_metadata = in_point_cloud_->GetMetadata();
- const AttributeMetadata *material_metadata = nullptr;
- if (pc_metadata) {
- material_metadata =
- pc_metadata->GetAttributeMetadataByStringEntry("name", "material");
- }
- std::string material_file_name;
- std::string material_full_path;
- if (!material_metadata)
- return true;
- if (!material_metadata->GetEntryString("file_name", &material_file_name))
- return false;
- buffer()->Encode("mtllib ", 7);
- buffer()->Encode(material_file_name.c_str(), material_file_name.size());
- buffer()->Encode("\n", 1);
- material_id_to_name_.clear();
- for (const auto &entry : material_metadata->entries()) {
- // Material id must be int.
- int value = 0;
- // Found entry that are not material id, e.g. file name as a string.
- if (!entry.second.GetValue(&value))
- continue;
- material_id_to_name_[value] = entry.first;
- }
- material_att_ = in_point_cloud_->GetAttributeByUniqueId(
- material_metadata->att_unique_id());
- if (material_att_ == nullptr || material_att_->size() == 0)
- return false;
- return true;
-}
-
-bool ObjEncoder::EncodePositions() {
- const PointAttribute *const att =
- in_point_cloud_->GetNamedAttribute(GeometryAttribute::POSITION);
- if (att == nullptr || att->size() == 0)
- return false; // Position attribute must be valid.
- std::array<float, 3> value;
- for (AttributeValueIndex i(0); i < static_cast<uint32_t>(att->size()); ++i) {
- if (!att->ConvertValue<float, 3>(i, &value[0]))
- return false;
- buffer()->Encode("v ", 2);
- EncodeFloatList(&value[0], 3);
- buffer()->Encode("\n", 1);
- }
- pos_att_ = att;
- return true;
-}
-
-bool ObjEncoder::EncodeTextureCoordinates() {
- const PointAttribute *const att =
- in_point_cloud_->GetNamedAttribute(GeometryAttribute::TEX_COORD);
- if (att == nullptr || att->size() == 0)
- return true; // It's OK if we don't have texture coordinates.
- std::array<float, 2> value;
- for (AttributeValueIndex i(0); i < static_cast<uint32_t>(att->size()); ++i) {
- if (!att->ConvertValue<float, 2>(i, &value[0]))
- return false;
- buffer()->Encode("vt ", 3);
- EncodeFloatList(&value[0], 2);
- buffer()->Encode("\n", 1);
- }
- tex_coord_att_ = att;
- return true;
-}
-
-bool ObjEncoder::EncodeNormals() {
- const PointAttribute *const att =
- in_point_cloud_->GetNamedAttribute(GeometryAttribute::NORMAL);
- if (att == nullptr || att->size() == 0)
- return true; // It's OK if we don't have normals.
- std::array<float, 3> value;
- for (AttributeValueIndex i(0); i < static_cast<uint32_t>(att->size()); ++i) {
- if (!att->ConvertValue<float, 3>(i, &value[0]))
- return false;
- buffer()->Encode("vn ", 3);
- EncodeFloatList(&value[0], 3);
- buffer()->Encode("\n", 1);
- }
- normal_att_ = att;
- return true;
-}
-
-bool ObjEncoder::EncodeFaces() {
- for (FaceIndex i(0); i < in_mesh_->num_faces(); ++i) {
- if (sub_obj_att_)
- if (!EncodeSubObject(i))
- return false;
- if (material_att_)
- if (!EncodeMaterial(i))
- return false;
- buffer()->Encode('f');
- for (int j = 0; j < 3; ++j) {
- if (!EncodeFaceCorner(i, j))
- return false;
- }
- buffer()->Encode("\n", 1);
- }
- return true;
-}
-
-bool ObjEncoder::EncodeMaterial(FaceIndex face_id) {
- int material_id = 0;
- // Pick the first corner, all corners of a face should have same id.
- const PointIndex vert_index = in_mesh_->face(face_id)[0];
- const AttributeValueIndex index_id(material_att_->mapped_index(vert_index));
- if (!material_att_->ConvertValue<int>(index_id, &material_id)) {
- return false;
- }
-
- if (material_id != current_material_id_) {
- // Update material information.
- buffer()->Encode("usemtl ", 7);
- const auto mat_ptr = material_id_to_name_.find(material_id);
- // If the material id is not found.
- if (mat_ptr == material_id_to_name_.end())
- return false;
- buffer()->Encode(mat_ptr->second.c_str(), mat_ptr->second.size());
- buffer()->Encode("\n", 1);
- current_material_id_ = material_id;
- }
- return true;
-}
-
-bool ObjEncoder::EncodeSubObject(FaceIndex face_id) {
- int sub_obj_id = 0;
- // Pick the first corner, all corners of a face should have same id.
- const PointIndex vert_index = in_mesh_->face(face_id)[0];
- const AttributeValueIndex index_id(sub_obj_att_->mapped_index(vert_index));
- if (!sub_obj_att_->ConvertValue<int>(index_id, &sub_obj_id)) {
- return false;
- }
- if (sub_obj_id != current_sub_obj_id_) {
- buffer()->Encode("o ", 2);
- const auto sub_obj_ptr = sub_obj_id_to_name_.find(sub_obj_id);
- if (sub_obj_ptr == sub_obj_id_to_name_.end())
- return false;
- buffer()->Encode(sub_obj_ptr->second.c_str(), sub_obj_ptr->second.size());
- buffer()->Encode("\n", 1);
- current_sub_obj_id_ = sub_obj_id;
- }
- return true;
-}
-
-bool ObjEncoder::EncodeFaceCorner(FaceIndex face_id, int local_corner_id) {
- buffer()->Encode(' ');
- const PointIndex vert_index = in_mesh_->face(face_id)[local_corner_id];
- // Note that in the OBJ format, all indices are encoded starting from index 1.
- // Encode position index.
- EncodeInt(pos_att_->mapped_index(vert_index).value() + 1);
- if (tex_coord_att_ || normal_att_) {
- // Encoding format is pos_index/tex_coord_index/normal_index.
- // If tex_coords are not present, we must encode pos_index//normal_index.
- buffer()->Encode('/');
- if (tex_coord_att_) {
- EncodeInt(tex_coord_att_->mapped_index(vert_index).value() + 1);
- }
- if (normal_att_) {
- buffer()->Encode('/');
- EncodeInt(normal_att_->mapped_index(vert_index).value() + 1);
- }
- }
- return true;
-}
-
-void ObjEncoder::EncodeFloat(float val) {
- snprintf(num_buffer_, sizeof(num_buffer_), "%f", val);
- buffer()->Encode(num_buffer_, strlen(num_buffer_));
-}
-
-void ObjEncoder::EncodeFloatList(float *vals, int num_vals) {
- for (int i = 0; i < num_vals; ++i) {
- if (i > 0) {
- buffer()->Encode(' ');
- }
- EncodeFloat(vals[i]);
- }
-}
-
-void ObjEncoder::EncodeInt(int32_t val) {
- snprintf(num_buffer_, sizeof(num_buffer_), "%d", val);
- buffer()->Encode(num_buffer_, strlen(num_buffer_));
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/io/obj_encoder.h b/extern/draco/dracoenc/src/draco/io/obj_encoder.h
deleted file mode 100644
index 509d39baf39..00000000000
--- a/extern/draco/dracoenc/src/draco/io/obj_encoder.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#ifndef DRACO_IO_OBJ_ENCODER_H_
-#define DRACO_IO_OBJ_ENCODER_H_
-
-#include <unordered_map>
-
-#include "draco/core/encoder_buffer.h"
-#include "draco/mesh/mesh.h"
-
-namespace draco {
-
-// Class for encoding input draco::Mesh or draco::PointCloud into the Wavefront
-// OBJ format.
-class ObjEncoder {
- public:
- ObjEncoder();
-
- // Encodes the mesh or a point cloud and saves it into a file.
- // Returns false when either the encoding failed or when the file couldn't be
- // opened.
- bool EncodeToFile(const PointCloud &pc, const std::string &file_name);
- bool EncodeToFile(const Mesh &mesh, const std::string &file_name);
-
- // Encodes the mesh or the point cloud into a buffer.
- bool EncodeToBuffer(const PointCloud &pc, EncoderBuffer *out_buffer);
- bool EncodeToBuffer(const Mesh &mesh, EncoderBuffer *out_buffer);
-
- protected:
- bool EncodeInternal();
- EncoderBuffer *buffer() const { return out_buffer_; }
- bool ExitAndCleanup(bool return_value);
-
- private:
- bool GetSubObjects();
- bool EncodeMaterialFileName();
- bool EncodePositions();
- bool EncodeTextureCoordinates();
- bool EncodeNormals();
- bool EncodeFaces();
- bool EncodeSubObject(FaceIndex face_id);
- bool EncodeMaterial(FaceIndex face_id);
- bool EncodeFaceCorner(FaceIndex face_id, int local_corner_id);
-
- void EncodeFloat(float val);
- void EncodeFloatList(float *vals, int num_vals);
- void EncodeInt(int32_t val);
-
- // Various attributes used by the encoder. If an attribute is not used, it is
- // set to nullptr.
- const PointAttribute *pos_att_;
- const PointAttribute *tex_coord_att_;
- const PointAttribute *normal_att_;
- const PointAttribute *material_att_;
- const PointAttribute *sub_obj_att_;
-
- // Buffer used for encoding float/int numbers.
- char num_buffer_[20];
-
- EncoderBuffer *out_buffer_;
-
- const PointCloud *in_point_cloud_;
- const Mesh *in_mesh_;
-
- // Store sub object name for each value.
- std::unordered_map<int, std::string> sub_obj_id_to_name_;
- // Current sub object id of faces.
- int current_sub_obj_id_;
-
- // Store material name for each value in material attribute.
- std::unordered_map<int, std::string> material_id_to_name_;
- // Current material id of faces.
- int current_material_id_;
-
- std::string file_name_;
-};
-
-} // namespace draco
-
-#endif // DRACO_IO_OBJ_ENCODER_H_
diff --git a/extern/draco/dracoenc/src/draco/io/obj_encoder_test.cc b/extern/draco/dracoenc/src/draco/io/obj_encoder_test.cc
deleted file mode 100644
index 79ea1712806..00000000000
--- a/extern/draco/dracoenc/src/draco/io/obj_encoder_test.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2017 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include <fstream>
-#include <sstream>
-
-#include "draco/core/draco_test_base.h"
-#include "draco/core/draco_test_utils.h"
-#include "draco/io/obj_decoder.h"
-#include "draco/io/obj_encoder.h"
-
-namespace draco {
-
-class ObjEncoderTest : public ::testing::Test {
- protected:
- void CompareMeshes(const Mesh *mesh0, const Mesh *mesh1) {
- ASSERT_EQ(mesh0->num_faces(), mesh1->num_faces());
- ASSERT_EQ(mesh0->num_attributes(), mesh1->num_attributes());
- for (size_t att_id = 0; att_id < mesh0->num_attributes(); ++att_id) {
- ASSERT_EQ(mesh0->attribute(att_id)->size(),
- mesh1->attribute(att_id)->size());
- }
- }
-
- // Encode a mesh using the ObjEncoder and then decode to verify the encoding.
- std::unique_ptr<Mesh> EncodeAndDecodeMesh(const Mesh *mesh) {
- EncoderBuffer encoder_buffer;
- ObjEncoder encoder;
- if (!encoder.EncodeToBuffer(*mesh, &encoder_buffer))
- return nullptr;
-
- DecoderBuffer decoder_buffer;
- decoder_buffer.Init(encoder_buffer.data(), encoder_buffer.size());
- std::unique_ptr<Mesh> decoded_mesh(new Mesh());
- ObjDecoder decoder;
- decoder.set_use_metadata(true);
- if (!decoder.DecodeFromBuffer(&decoder_buffer, decoded_mesh.get()).ok())
- return nullptr;
- return decoded_mesh;
- }
-
- void test_encoding(const std::string &file_name) {
- const std::unique_ptr<Mesh> mesh(ReadMeshFromTestFile(file_name, true));
-
- ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
- ASSERT_GT(mesh->num_faces(), 0);
-
- const std::unique_ptr<Mesh> decoded_mesh = EncodeAndDecodeMesh(mesh.get());
- CompareMeshes(mesh.get(), decoded_mesh.get());
- }
-};
-
-TEST_F(ObjEncoderTest, HasSubObject) { test_encoding("cube_att_sub_o.obj"); }
-
-TEST_F(ObjEncoderTest, HasMaterial) {
- const std::unique_ptr<Mesh> mesh0(ReadMeshFromTestFile("mat_test.obj", true));
- ASSERT_NE(mesh0, nullptr);
- const std::unique_ptr<Mesh> mesh1 = EncodeAndDecodeMesh(mesh0.get());
- ASSERT_NE(mesh1, nullptr);
- ASSERT_EQ(mesh0->num_faces(), mesh1->num_faces());
- ASSERT_EQ(mesh0->num_attributes(), mesh1->num_attributes());
- // Position attribute should be the same.
- ASSERT_EQ(mesh0->attribute(0)->size(), mesh1->attribute(0)->size());
- // Since |mesh1| is decoded from buffer, it has not material file. So the
- // size of material attribute is the number of materials used in the obj
- // file which is 7. The size of material attribute of |mesh0| decoded from
- // the obj file will be the number of materials defined in the .mtl file.
- ASSERT_EQ(mesh0->attribute(1)->size(), 29);
- ASSERT_EQ(mesh1->attribute(1)->size(), 7);
-}
-
-TEST_F(ObjEncoderTest, TestObjEncodingAll) {
- // Test decoded mesh from encoded obj file stays the same.
- test_encoding("bunny_norm.obj");
- test_encoding("cube_att.obj");
- test_encoding("cube_att_partial.obj");
- test_encoding("cube_quads.obj");
- test_encoding("cube_subd.obj");
- test_encoding("extra_vertex.obj");
- test_encoding("multiple_isolated_triangles.obj");
- test_encoding("multiple_tetrahedrons.obj");
- test_encoding("one_face_123.obj");
- test_encoding("one_face_312.obj");
- test_encoding("one_face_321.obj");
- test_encoding("sphere.obj");
- test_encoding("test_nm.obj");
- test_encoding("test_nm_trans.obj");
- test_encoding("test_sphere.obj");
- test_encoding("three_faces_123.obj");
- test_encoding("three_faces_312.obj");
- test_encoding("two_faces_123.obj");
- test_encoding("two_faces_312.obj");
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/io/parser_utils.cc b/extern/draco/dracoenc/src/draco/io/parser_utils.cc
deleted file mode 100644
index 0a22ba114ab..00000000000
--- a/extern/draco/dracoenc/src/draco/io/parser_utils.cc
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/io/parser_utils.h"
-
-#include <algorithm>
-#include <cctype>
-#include <cmath>
-#include <iterator>
-
-namespace draco {
-namespace parser {
-
-void SkipCharacters(DecoderBuffer *buffer, const char *skip_chars) {
- if (skip_chars == nullptr)
- return;
- const int num_skip_chars = static_cast<int>(strlen(skip_chars));
- char c;
- while (buffer->Peek(&c)) {
- // Check all characters in the pattern.
- bool skip = false;
- for (int i = 0; i < num_skip_chars; ++i) {
- if (c == skip_chars[i]) {
- skip = true;
- break;
- }
- }
- if (!skip)
- return;
- buffer->Advance(1);
- }
-}
-
-void SkipWhitespace(DecoderBuffer *buffer) {
- bool end_reached = false;
- while (PeekWhitespace(buffer, &end_reached) && !end_reached) {
- // Skip the whitespace character
- buffer->Advance(1);
- }
-}
-
-bool PeekWhitespace(DecoderBuffer *buffer, bool *end_reached) {
- uint8_t c;
- if (!buffer->Peek(&c)) {
- *end_reached = true;
- return false; // eof reached.
- }
- if (!isspace(c))
- return false; // Non-whitespace character reached.
- return true;
-}
-
-void SkipLine(DecoderBuffer *buffer) {
- char c;
- while (buffer->Peek(&c)) {
- // Skip the character.
- buffer->Advance(1);
- if (c == '\n')
- return; // Return at the end of line
- }
-}
-
-bool ParseFloat(DecoderBuffer *buffer, float *value) {
- // Read optional sign.
- char ch;
- if (!buffer->Peek(&ch))
- return false;
- int sign = GetSignValue(ch);
- if (sign != 0) {
- buffer->Advance(1);
- } else {
- sign = 1;
- }
-
- // Parse integer component.
- bool have_digits = false;
- double v = 0.0;
- while (buffer->Peek(&ch) && ch >= '0' && ch <= '9') {
- v *= 10.0;
- v += (ch - '0');
- buffer->Advance(1);
- have_digits = true;
- }
- if (ch == '.') {
- // Parse fractional component.
- buffer->Advance(1);
- double fraction = 1.0;
- while (buffer->Peek(&ch) && ch >= '0' && ch <= '9') {
- fraction *= 0.1;
- v += (ch - '0') * fraction;
- buffer->Advance(1);
- have_digits = true;
- }
- }
-
- if (!have_digits) {
- // Check for special constants (inf, nan, ...).
- std::string text;
- if (!ParseString(buffer, &text))
- return false;
- if (text == "inf" || text == "Inf") {
- v = std::numeric_limits<double>::infinity();
- } else if (text == "nan" || text == "NaN") {
- v = nan("");
- } else {
- // Invalid string.
- return false;
- }
- } else {
- // Handle exponent if present.
- if (ch == 'e' || ch == 'E') {
- buffer->Advance(1); // Skip 'e' marker.
-
- // Parse integer exponent.
- int32_t exponent = 0;
- if (!ParseSignedInt(buffer, &exponent))
- return false;
-
- // Apply exponent scaling to value.
- v *= pow(static_cast<double>(10.0), exponent);
- }
- }
-
- *value = (sign < 0) ? static_cast<float>(-v) : static_cast<float>(v);
- return true;
-}
-
-bool ParseSignedInt(DecoderBuffer *buffer, int32_t *value) {
- // Parse any explicit sign and set the appropriate largest magnitude
- // value that can be represented without overflow.
- char ch;
- if (!buffer->Peek(&ch))
- return false;
- const int sign = GetSignValue(ch);
- if (sign != 0)
- buffer->Advance(1);
-
- // Attempt to parse integer body.
- uint32_t v;
- if (!ParseUnsignedInt(buffer, &v))
- return false;
- *value = (sign < 0) ? -v : v;
- return true;
-}
-
-bool ParseUnsignedInt(DecoderBuffer *buffer, uint32_t *value) {
- // Parse the number until we run out of digits.
- uint32_t v = 0;
- char ch;
- bool have_digits = false;
- while (buffer->Peek(&ch) && ch >= '0' && ch <= '9') {
- v *= 10;
- v += (ch - '0');
- buffer->Advance(1);
- have_digits = true;
- }
- if (!have_digits)
- return false;
- *value = v;
- return true;
-}
-
-int GetSignValue(char c) {
- if (c == '-')
- return -1;
- if (c == '+')
- return 1;
- return 0;
-}
-
-bool ParseString(DecoderBuffer *buffer, std::string *out_string) {
- out_string->clear();
- SkipWhitespace(buffer);
- bool end_reached = false;
- while (!PeekWhitespace(buffer, &end_reached) && !end_reached) {
- char c;
- if (!buffer->Decode(&c))
- return false;
- *out_string += c;
- }
- return true;
-}
-
-void ParseLine(DecoderBuffer *buffer, std::string *out_string) {
- out_string->clear();
- char c;
- while (buffer->Peek(&c)) {
- // Skip the character.
- buffer->Advance(1);
- if (c == '\n')
- return; // Return at the end of line.
- if (c == '\r')
- continue; // Ignore extra line ending characters.
- *out_string += c;
- }
-}
-
-DecoderBuffer ParseLineIntoDecoderBuffer(DecoderBuffer *buffer) {
- const char *const head = buffer->data_head();
- char c;
- while (buffer->Peek(&c)) {
- // Skip the character.
- buffer->Advance(1);
- if (c == '\n')
- break; // End of the line reached.
- if (c == '\r')
- continue; // Ignore extra line ending characters.
- }
- DecoderBuffer out_buffer;
- out_buffer.Init(head, buffer->data_head() - head);
- return out_buffer;
-}
-
-std::string ToLower(const std::string &str) {
- std::string out;
- std::transform(str.begin(), str.end(), std::back_inserter(out), tolower);
- return out;
-}
-
-} // namespace parser
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/io/parser_utils.h b/extern/draco/dracoenc/src/draco/io/parser_utils.h
deleted file mode 100644
index aa629053068..00000000000
--- a/extern/draco/dracoenc/src/draco/io/parser_utils.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#ifndef DRACO_IO_PARSER_UTILS_H_
-#define DRACO_IO_PARSER_UTILS_H_
-
-#include "draco/core/decoder_buffer.h"
-
-namespace draco {
-namespace parser {
-
-// Skips to first character not included in |skip_chars|.
-void SkipCharacters(DecoderBuffer *buffer, const char *skip_chars);
-
-// Skips any whitespace until a regular character is reached.
-void SkipWhitespace(DecoderBuffer *buffer);
-
-// Returns true if the next character is a whitespace.
-// |end_reached| is set to true when the end of the stream is reached.
-bool PeekWhitespace(DecoderBuffer *buffer, bool *end_reached);
-void SkipLine(DecoderBuffer *buffer);
-
-// Parses signed floating point number or returns false on error.
-bool ParseFloat(DecoderBuffer *buffer, float *value);
-
-// Parses a signed integer (can be preceded by '-' or '+' characters.
-bool ParseSignedInt(DecoderBuffer *buffer, int32_t *value);
-
-// Parses an unsigned integer. It cannot be preceded by '-' or '+'
-// characters.
-bool ParseUnsignedInt(DecoderBuffer *buffer, uint32_t *value);
-
-// Returns -1 if c == '-'.
-// Returns +1 if c == '+'.
-// Returns 0 otherwise.
-int GetSignValue(char c);
-
-// Parses a string until a whitespace or end of file is reached.
-bool ParseString(DecoderBuffer *buffer, std::string *out_string);
-
-// Parses the entire line into the buffer (excluding the new line character).
-void ParseLine(DecoderBuffer *buffer, std::string *out_string);
-
-// Parses line and stores into a new decoder buffer.
-DecoderBuffer ParseLineIntoDecoderBuffer(DecoderBuffer *buffer);
-
-// Returns a string with all characters converted to lower case.
-std::string ToLower(const std::string &str);
-
-} // namespace parser
-} // namespace draco
-
-#endif // DRACO_IO_PARSER_UTILS_H_
diff --git a/extern/draco/dracoenc/src/draco/io/ply_decoder.cc b/extern/draco/dracoenc/src/draco/io/ply_decoder.cc
deleted file mode 100644
index 69a1c546cf7..00000000000
--- a/extern/draco/dracoenc/src/draco/io/ply_decoder.cc
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/io/ply_decoder.h"
-
-#include <fstream>
-
-#include "draco/core/macros.h"
-#include "draco/core/status.h"
-#include "draco/io/ply_property_reader.h"
-
-namespace draco {
-
-PlyDecoder::PlyDecoder() : out_mesh_(nullptr), out_point_cloud_(nullptr) {}
-
-Status PlyDecoder::DecodeFromFile(const std::string &file_name,
- Mesh *out_mesh) {
- out_mesh_ = out_mesh;
- return DecodeFromFile(file_name, static_cast<PointCloud *>(out_mesh));
-}
-
-Status PlyDecoder::DecodeFromFile(const std::string &file_name,
- PointCloud *out_point_cloud) {
- std::ifstream file(file_name, std::ios::binary);
- if (!file)
- return Status(Status::IO_ERROR, "Couldn't open file");
- // Read the whole file into a buffer.
- auto pos0 = file.tellg();
- file.seekg(0, std::ios::end);
- auto file_size = file.tellg() - pos0;
- if (file_size == 0)
- return Status(Status::IO_ERROR, "Zero file size");
- file.seekg(0, std::ios::beg);
- std::vector<char> data(file_size);
- file.read(&data[0], file_size);
-
- buffer_.Init(&data[0], file_size);
- return DecodeFromBuffer(&buffer_, out_point_cloud);
-}
-
-Status PlyDecoder::DecodeFromBuffer(DecoderBuffer *buffer, Mesh *out_mesh) {
- out_mesh_ = out_mesh;
- return DecodeFromBuffer(buffer, static_cast<PointCloud *>(out_mesh));
-}
-
-Status PlyDecoder::DecodeFromBuffer(DecoderBuffer *buffer,
- PointCloud *out_point_cloud) {
- out_point_cloud_ = out_point_cloud;
- buffer_.Init(buffer->data_head(), buffer->remaining_size());
- return DecodeInternal();
-}
-
-Status PlyDecoder::DecodeInternal() {
- PlyReader ply_reader;
- DRACO_RETURN_IF_ERROR(ply_reader.Read(buffer()));
- // First, decode the connectivity data.
- if (out_mesh_)
- DRACO_RETURN_IF_ERROR(DecodeFaceData(ply_reader.GetElementByName("face")));
- // Decode all attributes.
- DRACO_RETURN_IF_ERROR(
- DecodeVertexData(ply_reader.GetElementByName("vertex")));
- // In case there are no faces this is just a point cloud which does
- // not require deduplication.
- if (out_mesh_ && out_mesh_->num_faces() != 0) {
-#ifdef DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED
- if (!out_point_cloud_->DeduplicateAttributeValues())
- return Status(Status::DRACO_ERROR,
- "Could not deduplicate attribute values");
-#endif
-#ifdef DRACO_ATTRIBUTE_INDICES_DEDUPLICATION_SUPPORTED
- out_point_cloud_->DeduplicatePointIds();
-#endif
- }
- return OkStatus();
-}
-
-Status PlyDecoder::DecodeFaceData(const PlyElement *face_element) {
- // We accept point clouds now.
- if (face_element == nullptr) {
- return Status(Status::INVALID_PARAMETER, "face_element is null");
- }
- const int64_t num_faces = face_element->num_entries();
- out_mesh_->SetNumFaces(num_faces);
- const PlyProperty *vertex_indices =
- face_element->GetPropertyByName("vertex_indices");
- if (vertex_indices == nullptr) {
- // The property name may be named either "vertex_indices" or "vertex_index".
- vertex_indices = face_element->GetPropertyByName("vertex_index");
- }
- if (vertex_indices == nullptr || !vertex_indices->is_list()) {
- return Status(Status::DRACO_ERROR, "No faces defined");
- }
-
- PlyPropertyReader<PointIndex::ValueType> vertex_index_reader(vertex_indices);
- Mesh::Face face;
- FaceIndex face_index(0);
- for (int i = 0; i < num_faces; ++i) {
- const int64_t list_offset = vertex_indices->GetListEntryOffset(i);
- const int64_t list_size = vertex_indices->GetListEntryNumValues(i);
- // TODO(ostava): Assume triangular faces only for now.
- if (list_size != 3)
- continue; // All non-triangular faces are skipped.
- for (int64_t c = 0; c < 3; ++c)
- face[c] =
- vertex_index_reader.ReadValue(static_cast<int>(list_offset + c));
- out_mesh_->SetFace(face_index, face);
- face_index++;
- }
- out_mesh_->SetNumFaces(face_index.value());
- return OkStatus();
-}
-
-template <typename DataTypeT>
-bool PlyDecoder::ReadPropertiesToAttribute(
- const std::vector<const PlyProperty *> &properties,
- PointAttribute *attribute, int num_vertices) {
- std::vector<std::unique_ptr<PlyPropertyReader<DataTypeT>>> readers;
- readers.reserve(properties.size());
- for (int prop = 0; prop < properties.size(); ++prop) {
- readers.push_back(std::unique_ptr<PlyPropertyReader<DataTypeT>>(
- new PlyPropertyReader<DataTypeT>(properties[prop])));
- }
- std::vector<DataTypeT> memory(properties.size());
- for (PointIndex::ValueType i = 0; i < static_cast<uint32_t>(num_vertices);
- ++i) {
- for (int prop = 0; prop < properties.size(); ++prop) {
- memory[prop] = readers[prop]->ReadValue(i);
- }
- attribute->SetAttributeValue(AttributeValueIndex(i), memory.data());
- }
- return true;
-}
-
-Status PlyDecoder::DecodeVertexData(const PlyElement *vertex_element) {
- if (vertex_element == nullptr)
- return Status(Status::INVALID_PARAMETER, "vertex_element is null");
- // TODO(ostava): For now, try to load x,y,z vertices and red,green,blue,alpha
- // colors. We need to add other properties later.
- const PlyProperty *const x_prop = vertex_element->GetPropertyByName("x");
- const PlyProperty *const y_prop = vertex_element->GetPropertyByName("y");
- const PlyProperty *const z_prop = vertex_element->GetPropertyByName("z");
- if (!x_prop || !y_prop || !z_prop) {
- // Currently, we require 3 vertex coordinates (this should be generalized
- // later on).
- return Status(Status::INVALID_PARAMETER, "x, y, or z property is missing");
- }
- const PointIndex::ValueType num_vertices = vertex_element->num_entries();
- out_point_cloud_->set_num_points(num_vertices);
- // Decode vertex positions.
- {
- // All properties must have the same type.
- if (x_prop->data_type() != y_prop->data_type() ||
- y_prop->data_type() != z_prop->data_type()) {
- return Status(Status::INVALID_PARAMETER,
- "x, y, and z properties must have the same type");
- }
- // TODO(ostava): For now assume the position types are float32 or int32.
- const DataType dt = x_prop->data_type();
- if (dt != DT_FLOAT32 && dt != DT_INT32)
- return Status(Status::INVALID_PARAMETER,
- "x, y, and z properties must be of type float32 or int32");
-
- GeometryAttribute va;
- va.Init(GeometryAttribute::POSITION, nullptr, 3, dt, false,
- DataTypeLength(dt) * 3, 0);
- const int att_id = out_point_cloud_->AddAttribute(va, true, num_vertices);
- std::vector<const PlyProperty *> properties;
- properties.push_back(x_prop);
- properties.push_back(y_prop);
- properties.push_back(z_prop);
- if (dt == DT_FLOAT32) {
- ReadPropertiesToAttribute<float>(
- properties, out_point_cloud_->attribute(att_id), num_vertices);
- } else if (dt == DT_INT32) {
- ReadPropertiesToAttribute<int32_t>(
- properties, out_point_cloud_->attribute(att_id), num_vertices);
- }
- }
-
- // Decode normals if present.
- const PlyProperty *const n_x_prop = vertex_element->GetPropertyByName("nx");
- const PlyProperty *const n_y_prop = vertex_element->GetPropertyByName("ny");
- const PlyProperty *const n_z_prop = vertex_element->GetPropertyByName("nz");
- if (n_x_prop != nullptr && n_y_prop != nullptr && n_z_prop != nullptr) {
- // For now, all normal properties must be set and of type float32
- if (n_x_prop->data_type() == DT_FLOAT32 &&
- n_y_prop->data_type() == DT_FLOAT32 &&
- n_z_prop->data_type() == DT_FLOAT32) {
- PlyPropertyReader<float> x_reader(n_x_prop);
- PlyPropertyReader<float> y_reader(n_y_prop);
- PlyPropertyReader<float> z_reader(n_z_prop);
- GeometryAttribute va;
- va.Init(GeometryAttribute::NORMAL, nullptr, 3, DT_FLOAT32, false,
- sizeof(float) * 3, 0);
- const int att_id = out_point_cloud_->AddAttribute(va, true, num_vertices);
- for (PointIndex::ValueType i = 0; i < num_vertices; ++i) {
- std::array<float, 3> val;
- val[0] = x_reader.ReadValue(i);
- val[1] = y_reader.ReadValue(i);
- val[2] = z_reader.ReadValue(i);
- out_point_cloud_->attribute(att_id)->SetAttributeValue(
- AttributeValueIndex(i), &val[0]);
- }
- }
- }
-
- // Decode color data if present.
- int num_colors = 0;
- const PlyProperty *const r_prop = vertex_element->GetPropertyByName("red");
- const PlyProperty *const g_prop = vertex_element->GetPropertyByName("green");
- const PlyProperty *const b_prop = vertex_element->GetPropertyByName("blue");
- const PlyProperty *const a_prop = vertex_element->GetPropertyByName("alpha");
- if (r_prop)
- ++num_colors;
- if (g_prop)
- ++num_colors;
- if (b_prop)
- ++num_colors;
- if (a_prop)
- ++num_colors;
-
- if (num_colors) {
- std::vector<std::unique_ptr<PlyPropertyReader<uint8_t>>> color_readers;
- const PlyProperty *p;
- if (r_prop) {
- p = r_prop;
- // TODO(ostava): For now ensure the data type of all components is uint8.
- DRACO_DCHECK_EQ(true, p->data_type() == DT_UINT8);
- if (p->data_type() != DT_UINT8)
- return Status(Status::INVALID_PARAMETER,
- "Type of 'red' property must be uint8");
- color_readers.push_back(std::unique_ptr<PlyPropertyReader<uint8_t>>(
- new PlyPropertyReader<uint8_t>(p)));
- }
- if (g_prop) {
- p = g_prop;
- // TODO(ostava): For now ensure the data type of all components is uint8.
- DRACO_DCHECK_EQ(true, p->data_type() == DT_UINT8);
- if (p->data_type() != DT_UINT8)
- return Status(Status::INVALID_PARAMETER,
- "Type of 'green' property must be uint8");
- color_readers.push_back(std::unique_ptr<PlyPropertyReader<uint8_t>>(
- new PlyPropertyReader<uint8_t>(p)));
- }
- if (b_prop) {
- p = b_prop;
- // TODO(ostava): For now ensure the data type of all components is uint8.
- DRACO_DCHECK_EQ(true, p->data_type() == DT_UINT8);
- if (p->data_type() != DT_UINT8)
- return Status(Status::INVALID_PARAMETER,
- "Type of 'blue' property must be uint8");
- color_readers.push_back(std::unique_ptr<PlyPropertyReader<uint8_t>>(
- new PlyPropertyReader<uint8_t>(p)));
- }
- if (a_prop) {
- p = a_prop;
- // TODO(ostava): For now ensure the data type of all components is uint8.
- DRACO_DCHECK_EQ(true, p->data_type() == DT_UINT8);
- if (p->data_type() != DT_UINT8)
- return Status(Status::INVALID_PARAMETER,
- "Type of 'alpha' property must be uint8");
- color_readers.push_back(std::unique_ptr<PlyPropertyReader<uint8_t>>(
- new PlyPropertyReader<uint8_t>(p)));
- }
-
- GeometryAttribute va;
- va.Init(GeometryAttribute::COLOR, nullptr, num_colors, DT_UINT8, true,
- sizeof(uint8_t) * num_colors, 0);
- const int32_t att_id =
- out_point_cloud_->AddAttribute(va, true, num_vertices);
- for (PointIndex::ValueType i = 0; i < num_vertices; ++i) {
- std::array<uint8_t, 4> val;
- for (int j = 0; j < num_colors; j++) {
- val[j] = color_readers[j]->ReadValue(i);
- }
- out_point_cloud_->attribute(att_id)->SetAttributeValue(
- AttributeValueIndex(i), &val[0]);
- }
- }
-
- return OkStatus();
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/io/ply_decoder.h b/extern/draco/dracoenc/src/draco/io/ply_decoder.h
deleted file mode 100644
index 9e667ab192f..00000000000
--- a/extern/draco/dracoenc/src/draco/io/ply_decoder.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#ifndef DRACO_IO_MESH_PLY_DECODER_H_
-#define DRACO_IO_MESH_PLY_DECODER_H_
-
-#include <string>
-
-#include "draco/draco_features.h"
-
-#include "draco/core/decoder_buffer.h"
-#include "draco/core/status.h"
-#include "draco/io/ply_reader.h"
-#include "draco/mesh/mesh.h"
-
-namespace draco {
-
-// Decodes a Wavefront OBJ file into draco::Mesh (or draco::PointCloud if the
-// connectivity data is not needed).
-// TODO(ostava): The current implementation assumes that the input vertices are
-// defined with x, y, z properties. The decoder also reads uint8 red, green,
-// blue, alpha color information, but all other attributes are ignored for now.
-class PlyDecoder {
- public:
- PlyDecoder();
-
- // Decodes an obj file stored in the input file.
- Status DecodeFromFile(const std::string &file_name, Mesh *out_mesh);
- Status DecodeFromFile(const std::string &file_name,
- PointCloud *out_point_cloud);
-
- Status DecodeFromBuffer(DecoderBuffer *buffer, Mesh *out_mesh);
- Status DecodeFromBuffer(DecoderBuffer *buffer, PointCloud *out_point_cloud);
-
- protected:
- Status DecodeInternal();
- DecoderBuffer *buffer() { return &buffer_; }
-
- private:
- Status DecodeFaceData(const PlyElement *face_element);
- Status DecodeVertexData(const PlyElement *vertex_element);
-
- template <typename DataTypeT>
- bool ReadPropertiesToAttribute(
- const std::vector<const PlyProperty *> &properties,
- PointAttribute *attribute, int num_vertices);
-
- DecoderBuffer buffer_;
-
- // Data structure that stores the decoded data. |out_point_cloud_| must be
- // always set but |out_mesh_| is optional.
- Mesh *out_mesh_;
- PointCloud *out_point_cloud_;
-};
-
-} // namespace draco
-
-#endif // DRACO_IO_MESH_PLY_DECODER_H_
diff --git a/extern/draco/dracoenc/src/draco/io/ply_decoder_test.cc b/extern/draco/dracoenc/src/draco/io/ply_decoder_test.cc
deleted file mode 100644
index 647324ea904..00000000000
--- a/extern/draco/dracoenc/src/draco/io/ply_decoder_test.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/io/ply_decoder.h"
-
-#include "draco/core/draco_test_base.h"
-#include "draco/core/draco_test_utils.h"
-
-namespace draco {
-
-class PlyDecoderTest : public ::testing::Test {
- protected:
- template <class Geometry>
- std::unique_ptr<Geometry> DecodePly(const std::string &file_name) const {
- const std::string path = GetTestFileFullPath(file_name);
- PlyDecoder decoder;
- std::unique_ptr<Geometry> geometry(new Geometry());
- Status status = decoder.DecodeFromFile(path, geometry.get());
- if (!status.ok()) {
- LOG(DRACO_ERROR) << "Failed to decode " << file_name << ": " << status;
- return nullptr;
- }
- return geometry;
- }
-
- void test_decoding(const std::string &file_name, int num_faces,
- uint32_t num_points, std::unique_ptr<Mesh> *out_mesh) {
- // Don't test mesh decoding when the input is point cloud.
- if (num_faces > 0) {
- std::unique_ptr<Mesh> mesh(DecodePly<Mesh>(file_name));
- ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
- ASSERT_EQ(mesh->num_faces(), num_faces);
- if (out_mesh)
- *out_mesh = std::move(mesh);
- }
-
- const std::unique_ptr<PointCloud> pc(DecodePly<PointCloud>(file_name));
- ASSERT_NE(pc, nullptr) << "Failed to load test model " << file_name;
- ASSERT_EQ(pc->num_points(), num_points);
- }
- void test_decoding(const std::string &file_name) {
- const std::unique_ptr<Mesh> mesh(DecodePly<Mesh>(file_name));
- ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
- ASSERT_GT(mesh->num_faces(), 0);
-
- const std::unique_ptr<PointCloud> pc(DecodePly<PointCloud>(file_name));
- ASSERT_NE(pc, nullptr) << "Failed to load test model " << file_name;
- ASSERT_GT(pc->num_points(), 0);
- }
-};
-
-TEST_F(PlyDecoderTest, TestPlyDecoding) {
- const std::string file_name = "test_pos_color.ply";
- test_decoding(file_name, 224, 114, nullptr);
-}
-
-TEST_F(PlyDecoderTest, TestPlyNormals) {
- const std::string file_name = "cube_att.ply";
- std::unique_ptr<Mesh> mesh;
- test_decoding(file_name, 12, 3 * 8, &mesh);
- ASSERT_NE(mesh, nullptr);
- const int att_id = mesh->GetNamedAttributeId(GeometryAttribute::NORMAL);
- ASSERT_GE(att_id, 0);
- const PointAttribute *const att = mesh->attribute(att_id);
- ASSERT_EQ(att->size(), 6); // 6 unique normal values.
-}
-
-TEST_F(PlyDecoderTest, TestPlyDecodingAll) {
- // test if we can read all ply that are currently in test folder.
- test_decoding("bun_zipper.ply");
- // test_decoding("cube_att.ply"); // tested
- test_decoding("test_extra_whitespace.ply");
- test_decoding("test_more_datatypes.ply");
- test_decoding("test_pos_color_ascii.ply");
- test_decoding("int_point_cloud.ply", 0, 16, nullptr);
- // test_decoding("test_pos_color.ply"); // tested
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/io/ply_encoder.cc b/extern/draco/dracoenc/src/draco/io/ply_encoder.cc
deleted file mode 100644
index cb25b21d4f8..00000000000
--- a/extern/draco/dracoenc/src/draco/io/ply_encoder.cc
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/io/ply_encoder.h"
-
-#include <fstream>
-#include <sstream>
-
-namespace draco {
-
-PlyEncoder::PlyEncoder()
- : out_buffer_(nullptr), in_point_cloud_(nullptr), in_mesh_(nullptr) {}
-
-bool PlyEncoder::EncodeToFile(const PointCloud &pc,
- const std::string &file_name) {
- std::ofstream file(file_name, std::ios::binary);
- if (!file)
- return false; // File couldn't be opened.
- // Encode the mesh into a buffer.
- EncoderBuffer buffer;
- if (!EncodeToBuffer(pc, &buffer))
- return false;
- // Write the buffer into the file.
- file.write(buffer.data(), buffer.size());
- return true;
-}
-
-bool PlyEncoder::EncodeToFile(const Mesh &mesh, const std::string &file_name) {
- in_mesh_ = &mesh;
- return EncodeToFile(static_cast<const PointCloud &>(mesh), file_name);
-}
-
-bool PlyEncoder::EncodeToBuffer(const PointCloud &pc,
- EncoderBuffer *out_buffer) {
- in_point_cloud_ = &pc;
- out_buffer_ = out_buffer;
- if (!EncodeInternal())
- return ExitAndCleanup(false);
- return ExitAndCleanup(true);
-}
-
-bool PlyEncoder::EncodeToBuffer(const Mesh &mesh, EncoderBuffer *out_buffer) {
- in_mesh_ = &mesh;
- return EncodeToBuffer(static_cast<const PointCloud &>(mesh), out_buffer);
-}
-bool PlyEncoder::EncodeInternal() {
- // Write PLY header.
- // TODO(ostava): Currently works only for xyz positions and rgb(a) colors.
- std::stringstream out;
- out << "ply" << std::endl;
- out << "format binary_little_endian 1.0" << std::endl;
- out << "element vertex " << in_point_cloud_->num_points() << std::endl;
-
- const int pos_att_id =
- in_point_cloud_->GetNamedAttributeId(GeometryAttribute::POSITION);
- int normal_att_id =
- in_point_cloud_->GetNamedAttributeId(GeometryAttribute::NORMAL);
- int tex_coord_att_id =
- in_point_cloud_->GetNamedAttributeId(GeometryAttribute::TEX_COORD);
- const int color_att_id =
- in_point_cloud_->GetNamedAttributeId(GeometryAttribute::COLOR);
-
- if (pos_att_id < 0)
- return false;
-
- // Ensure normals are 3 component. Don't encode them otherwise.
- if (normal_att_id >= 0 &&
- in_point_cloud_->attribute(normal_att_id)->num_components() != 3)
- normal_att_id = -1;
-
- // Ensure texture coordinates have only 2 components. Don't encode them
- // otherwise. TODO(ostava): Add support for 3 component normals (uvw).
- if (tex_coord_att_id >= 0 &&
- in_point_cloud_->attribute(tex_coord_att_id)->num_components() != 2)
- tex_coord_att_id = -1;
-
- out << "property " << GetAttributeDataType(pos_att_id) << " x" << std::endl;
- out << "property " << GetAttributeDataType(pos_att_id) << " y" << std::endl;
- out << "property " << GetAttributeDataType(pos_att_id) << " z" << std::endl;
- if (normal_att_id >= 0) {
- out << "property " << GetAttributeDataType(normal_att_id) << " nx"
- << std::endl;
- out << "property " << GetAttributeDataType(normal_att_id) << " ny"
- << std::endl;
- out << "property " << GetAttributeDataType(normal_att_id) << " nz"
- << std::endl;
- }
- if (color_att_id >= 0) {
- const auto *const attribute = in_point_cloud_->attribute(color_att_id);
- if (attribute->num_components() > 0) {
- out << "property " << GetAttributeDataType(color_att_id) << " red"
- << std::endl;
- }
- if (attribute->num_components() > 1) {
- out << "property " << GetAttributeDataType(color_att_id) << " green"
- << std::endl;
- }
- if (attribute->num_components() > 2) {
- out << "property " << GetAttributeDataType(color_att_id) << " blue"
- << std::endl;
- }
- if (attribute->num_components() > 3) {
- out << "property " << GetAttributeDataType(color_att_id) << " alpha"
- << std::endl;
- }
- }
- if (in_mesh_) {
- out << "element face " << in_mesh_->num_faces() << std::endl;
- out << "property list uchar int vertex_indices" << std::endl;
- if (tex_coord_att_id >= 0) {
- // Texture coordinates are usually encoded in the property list (one value
- // per corner).
- out << "property list uchar " << GetAttributeDataType(tex_coord_att_id)
- << " texcoord" << std::endl;
- }
- }
- out << "end_header" << std::endl;
-
- // Not very efficient but the header should be small so just copy the stream
- // to a string.
- const std::string header_str = out.str();
- buffer()->Encode(header_str.data(), header_str.length());
-
- // Store point attributes.
- for (PointIndex v(0); v < in_point_cloud_->num_points(); ++v) {
- const auto *const pos_att = in_point_cloud_->attribute(pos_att_id);
- buffer()->Encode(pos_att->GetAddress(pos_att->mapped_index(v)),
- pos_att->byte_stride());
- if (normal_att_id >= 0) {
- const auto *const normal_att = in_point_cloud_->attribute(normal_att_id);
- buffer()->Encode(normal_att->GetAddress(normal_att->mapped_index(v)),
- normal_att->byte_stride());
- }
- if (color_att_id >= 0) {
- const auto *const color_att = in_point_cloud_->attribute(color_att_id);
- buffer()->Encode(color_att->GetAddress(color_att->mapped_index(v)),
- color_att->byte_stride());
- }
- }
-
- if (in_mesh_) {
- // Write face data.
- for (FaceIndex i(0); i < in_mesh_->num_faces(); ++i) {
- // Write the number of face indices (always 3).
- buffer()->Encode(static_cast<uint8_t>(3));
-
- const auto &f = in_mesh_->face(i);
- buffer()->Encode(f[0]);
- buffer()->Encode(f[1]);
- buffer()->Encode(f[2]);
-
- if (tex_coord_att_id >= 0) {
- // Two coordinates for every corner -> 6.
- buffer()->Encode(static_cast<uint8_t>(6));
-
- const auto *const tex_att =
- in_point_cloud_->attribute(tex_coord_att_id);
- for (int c = 0; c < 3; ++c) {
- buffer()->Encode(tex_att->GetAddress(tex_att->mapped_index(f[c])),
- tex_att->byte_stride());
- }
- }
- }
- }
- return true;
-}
-
-bool PlyEncoder::ExitAndCleanup(bool return_value) {
- in_mesh_ = nullptr;
- in_point_cloud_ = nullptr;
- out_buffer_ = nullptr;
- return return_value;
-}
-
-const char *PlyEncoder::GetAttributeDataType(int attribute) {
- // TODO(ostava): Add support for more types.
- switch (in_point_cloud_->attribute(attribute)->data_type()) {
- case DT_FLOAT32:
- return "float";
- case DT_UINT8:
- return "uchar";
- case DT_INT32:
- return "int";
- default:
- break;
- }
- return nullptr;
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/io/ply_encoder.h b/extern/draco/dracoenc/src/draco/io/ply_encoder.h
deleted file mode 100644
index 242bbd6d464..00000000000
--- a/extern/draco/dracoenc/src/draco/io/ply_encoder.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#ifndef DRACO_IO_PLY_ENCODER_H_
-#define DRACO_IO_PLY_ENCODER_H_
-
-#include "draco/core/encoder_buffer.h"
-#include "draco/mesh/mesh.h"
-
-namespace draco {
-
-// Class for encoding draco::Mesh or draco::PointCloud into the PLY file format.
-class PlyEncoder {
- public:
- PlyEncoder();
-
- // Encodes the mesh or a point cloud and saves it into a file.
- // Returns false when either the encoding failed or when the file couldn't be
- // opened.
- bool EncodeToFile(const PointCloud &pc, const std::string &file_name);
- bool EncodeToFile(const Mesh &mesh, const std::string &file_name);
-
- // Encodes the mesh or the point cloud into a buffer.
- bool EncodeToBuffer(const PointCloud &pc, EncoderBuffer *out_buffer);
- bool EncodeToBuffer(const Mesh &mesh, EncoderBuffer *out_buffer);
-
- protected:
- bool EncodeInternal();
- EncoderBuffer *buffer() const { return out_buffer_; }
- bool ExitAndCleanup(bool return_value);
-
- private:
- const char *GetAttributeDataType(int attribute);
-
- EncoderBuffer *out_buffer_;
-
- const PointCloud *in_point_cloud_;
- const Mesh *in_mesh_;
-};
-
-} // namespace draco
-
-#endif // DRACO_IO_PLY_ENCODER_H_
diff --git a/extern/draco/dracoenc/src/draco/io/ply_property_reader.h b/extern/draco/dracoenc/src/draco/io/ply_property_reader.h
deleted file mode 100644
index efb8a3a1f9d..00000000000
--- a/extern/draco/dracoenc/src/draco/io/ply_property_reader.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#ifndef DRACO_IO_PLY_PROPERTY_READER_H_
-#define DRACO_IO_PLY_PROPERTY_READER_H_
-
-#include <functional>
-
-#include "draco/io/ply_reader.h"
-
-namespace draco {
-
-// Class for reading PlyProperty with a given type, performing data conversion
-// if necessary.
-template <typename ReadTypeT>
-class PlyPropertyReader {
- public:
- explicit PlyPropertyReader(const PlyProperty *property)
- : property_(property) {
- // Find the suitable function for converting values.
- switch (property->data_type()) {
- case DT_UINT8:
- convert_value_func_ = [=](int val_id) {
- return this->ConvertValue<uint8_t>(val_id);
- };
- break;
- case DT_INT8:
- convert_value_func_ = [=](int val_id) {
- return this->ConvertValue<int8_t>(val_id);
- };
- break;
- case DT_UINT16:
- convert_value_func_ = [=](int val_id) {
- return this->ConvertValue<uint16_t>(val_id);
- };
- break;
- case DT_INT16:
- convert_value_func_ = [=](int val_id) {
- return this->ConvertValue<int16_t>(val_id);
- };
- break;
- case DT_UINT32:
- convert_value_func_ = [=](int val_id) {
- return this->ConvertValue<uint32_t>(val_id);
- };
- break;
- case DT_INT32:
- convert_value_func_ = [=](int val_id) {
- return this->ConvertValue<int32_t>(val_id);
- };
- break;
- case DT_FLOAT32:
- convert_value_func_ = [=](int val_id) {
- return this->ConvertValue<float>(val_id);
- };
- break;
- case DT_FLOAT64:
- convert_value_func_ = [=](int val_id) {
- return this->ConvertValue<double>(val_id);
- };
- break;
- default:
- break;
- }
- }
-
- ReadTypeT ReadValue(int value_id) const {
- return convert_value_func_(value_id);
- }
-
- private:
- template <typename SourceTypeT>
- ReadTypeT ConvertValue(int value_id) const {
- const void *const address = property_->GetDataEntryAddress(value_id);
- const SourceTypeT src_val = *reinterpret_cast<const SourceTypeT *>(address);
- return static_cast<ReadTypeT>(src_val);
- }
-
- const PlyProperty *property_;
- std::function<ReadTypeT(int)> convert_value_func_;
-};
-
-} // namespace draco
-
-#endif // DRACO_IO_PLY_PROPERTY_READER_H_
diff --git a/extern/draco/dracoenc/src/draco/io/ply_property_writer.h b/extern/draco/dracoenc/src/draco/io/ply_property_writer.h
deleted file mode 100644
index 4f243b2860f..00000000000
--- a/extern/draco/dracoenc/src/draco/io/ply_property_writer.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#ifndef DRACO_IO_PLY_PROPERTY_WRITER_H_
-#define DRACO_IO_PLY_PROPERTY_WRITER_H_
-
-#include <functional>
-
-#include "draco/io/ply_reader.h"
-
-namespace draco {
-
-// Class for writing PlyProperty with a given type, performing data conversion
-// if necessary.
-template <typename WriteTypeT>
-class PlyPropertyWriter {
- public:
- explicit PlyPropertyWriter(PlyProperty *property) : property_(property) {
- // Find the suitable function for converting values.
- switch (property->data_type()) {
- case DT_UINT8:
- convert_value_func_ = [=](WriteTypeT val) {
- return this->ConvertValue<uint8_t>(val);
- };
- break;
- case DT_INT8:
- convert_value_func_ = [=](WriteTypeT val) {
- return this->ConvertValue<int8_t>(val);
- };
- break;
- case DT_UINT16:
- convert_value_func_ = [=](WriteTypeT val) {
- return this->ConvertValue<uint16_t>(val);
- };
- break;
- case DT_INT16:
- convert_value_func_ = [=](WriteTypeT val) {
- return this->ConvertValue<int16_t>(val);
- };
- break;
- case DT_UINT32:
- convert_value_func_ = [=](WriteTypeT val) {
- return this->ConvertValue<uint32_t>(val);
- };
- break;
- case DT_INT32:
- convert_value_func_ = [=](WriteTypeT val) {
- return this->ConvertValue<int32_t>(val);
- };
- break;
- case DT_FLOAT32:
- convert_value_func_ = [=](WriteTypeT val) {
- return this->ConvertValue<float>(val);
- };
- break;
- case DT_FLOAT64:
- convert_value_func_ = [=](WriteTypeT val) {
- return this->ConvertValue<double>(val);
- };
- break;
- default:
- break;
- }
- }
-
- void PushBackValue(WriteTypeT value) const {
- return convert_value_func_(value);
- }
-
- private:
- template <typename SourceTypeT>
- void ConvertValue(WriteTypeT value) const {
- const SourceTypeT src_val = static_cast<SourceTypeT>(value);
- property_->push_back_value(&src_val);
- }
-
- PlyProperty *property_;
- std::function<void(WriteTypeT)> convert_value_func_;
-};
-
-} // namespace draco
-
-#endif // DRACO_IO_PLY_PROPERTY_WRITER_H_
diff --git a/extern/draco/dracoenc/src/draco/io/ply_reader.cc b/extern/draco/dracoenc/src/draco/io/ply_reader.cc
deleted file mode 100644
index 772c4381176..00000000000
--- a/extern/draco/dracoenc/src/draco/io/ply_reader.cc
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/io/ply_reader.h"
-
-#include <array>
-#include <regex>
-
-#include "draco/core/status.h"
-#include "draco/io/parser_utils.h"
-#include "draco/io/ply_property_writer.h"
-
-namespace draco {
-
-PlyProperty::PlyProperty(const std::string &name, DataType data_type,
- DataType list_type)
- : name_(name), data_type_(data_type), list_data_type_(list_type) {
- data_type_num_bytes_ = DataTypeLength(data_type);
- list_data_type_num_bytes_ = DataTypeLength(list_type);
-}
-
-PlyElement::PlyElement(const std::string &name, int64_t num_entries)
- : name_(name), num_entries_(num_entries) {}
-
-PlyReader::PlyReader() : format_(kLittleEndian) {}
-
-Status PlyReader::Read(DecoderBuffer *buffer) {
- std::string value;
- // The first line needs to by "ply".
- if (!parser::ParseString(buffer, &value) || value != "ply") {
- return Status(Status::INVALID_PARAMETER, "Not a valid ply file");
- }
- parser::SkipLine(buffer);
-
- // The second line needs to be the format of the ply file.
- parser::ParseLine(buffer, &value);
- std::string format, version;
- const std::vector<std::string> words = SplitWords(value);
- if (words.size() >= 3 && words[0] == "format") {
- format = words[1];
- version = words[2];
- } else {
- return Status(Status::INVALID_PARAMETER, "Missing or wrong format line");
- }
- if (version != "1.0") {
- return Status(Status::UNSUPPORTED_VERSION, "Unsupported PLY version");
- }
- if (format == "binary_big_endian") {
- return Status(Status::UNSUPPORTED_VERSION,
- "Unsupported format. Currently we support only ascii and"
- " binary_little_endian format.");
- }
- if (format == "ascii") {
- format_ = kAscii;
- } else {
- format_ = kLittleEndian;
- }
- DRACO_RETURN_IF_ERROR(ParseHeader(buffer));
- if (!ParsePropertiesData(buffer)) {
- return Status(Status::INVALID_PARAMETER, "Couldn't parse properties");
- }
- return OkStatus();
-}
-
-Status PlyReader::ParseHeader(DecoderBuffer *buffer) {
- while (true) {
- DRACO_ASSIGN_OR_RETURN(bool end, ParseEndHeader(buffer));
- if (end)
- break;
- if (ParseElement(buffer))
- continue;
- DRACO_ASSIGN_OR_RETURN(bool property_parsed, ParseProperty(buffer));
- if (property_parsed)
- continue;
- parser::SkipLine(buffer);
- }
- return OkStatus();
-}
-
-StatusOr<bool> PlyReader::ParseEndHeader(DecoderBuffer *buffer) {
- parser::SkipWhitespace(buffer);
- std::array<char, 10> c;
- if (!buffer->Peek(&c)) {
- return Status(Status::INVALID_PARAMETER,
- "End of file reached before the end_header");
- }
- if (std::memcmp(&c[0], "end_header", 10) != 0)
- return false;
- parser::SkipLine(buffer);
- return true;
-}
-
-bool PlyReader::ParseElement(DecoderBuffer *buffer) {
- DecoderBuffer line_buffer(*buffer);
- std::string line;
- parser::ParseLine(&line_buffer, &line);
-
- std::string element_name;
- int64_t count;
- const std::vector<std::string> words = SplitWords(line);
- if (words.size() >= 3 && words[0] == "element") {
- element_name = words[1];
- const std::string count_str = words[2];
- count = strtoll(count_str.c_str(), NULL, 10);
- } else {
- return false;
- }
- element_index_[element_name] = static_cast<uint32_t>(elements_.size());
- elements_.emplace_back(PlyElement(element_name, count));
- *buffer = line_buffer;
- return true;
-}
-
-StatusOr<bool> PlyReader::ParseProperty(DecoderBuffer *buffer) {
- if (elements_.empty())
- return false; // Ignore properties if there is no active element.
- DecoderBuffer line_buffer(*buffer);
- std::string line;
- parser::ParseLine(&line_buffer, &line);
-
- std::string data_type_str, list_type_str, property_name;
- bool property_search = false;
- const std::vector<std::string> words = SplitWords(line);
- if (words.size() >= 3 && words[0] == "property" && words[1] != "list") {
- property_search = true;
- data_type_str = words[1];
- property_name = words[2];
- }
-
- bool property_list_search = false;
- if (words.size() >= 5 && words[0] == "property" && words[1] == "list") {
- property_list_search = true;
- list_type_str = words[2];
- data_type_str = words[3];
- property_name = words[4];
- }
- if (!property_search && !property_list_search) {
- return false;
- }
- const DataType data_type = GetDataTypeFromString(data_type_str);
- if (data_type == DT_INVALID) {
- return Status(Status::INVALID_PARAMETER, "Wrong property data type");
- }
- DataType list_type = DT_INVALID;
- if (property_list_search) {
- list_type = GetDataTypeFromString(list_type_str);
- if (list_type == DT_INVALID) {
- return Status(Status::INVALID_PARAMETER, "Wrong property list type");
- }
- }
- elements_.back().AddProperty(
- PlyProperty(property_name, data_type, list_type));
- *buffer = line_buffer;
- return true;
-}
-
-bool PlyReader::ParsePropertiesData(DecoderBuffer *buffer) {
- for (int i = 0; i < static_cast<int>(elements_.size()); ++i) {
- if (format_ == kLittleEndian) {
- if (!ParseElementData(buffer, i)) {
- return false;
- }
- } else if (format_ == kAscii) {
- if (!ParseElementDataAscii(buffer, i)) {
- return false;
- }
- }
- }
- return true;
-}
-
-bool PlyReader::ParseElementData(DecoderBuffer *buffer, int element_index) {
- PlyElement &element = elements_[element_index];
- for (int entry = 0; entry < element.num_entries(); ++entry) {
- for (int i = 0; i < element.num_properties(); ++i) {
- PlyProperty &prop = element.property(i);
- if (prop.is_list()) {
- // Parse the number of entries for the list element.
- int64_t num_entries = 0;
- buffer->Decode(&num_entries, prop.list_data_type_num_bytes());
- // Store offset to the main data entry.
- prop.list_data_.push_back(prop.data_.size() /
- prop.data_type_num_bytes_);
- // Store the number of entries.
- prop.list_data_.push_back(num_entries);
- // Read and store the actual property data
- const int64_t num_bytes_to_read =
- prop.data_type_num_bytes() * num_entries;
- prop.data_.insert(prop.data_.end(), buffer->data_head(),
- buffer->data_head() + num_bytes_to_read);
- buffer->Advance(num_bytes_to_read);
- } else {
- // Non-list property
- prop.data_.insert(prop.data_.end(), buffer->data_head(),
- buffer->data_head() + prop.data_type_num_bytes());
- buffer->Advance(prop.data_type_num_bytes());
- }
- }
- }
- return true;
-}
-
-bool PlyReader::ParseElementDataAscii(DecoderBuffer *buffer,
- int element_index) {
- PlyElement &element = elements_[element_index];
- for (int entry = 0; entry < element.num_entries(); ++entry) {
- for (int i = 0; i < element.num_properties(); ++i) {
- PlyProperty &prop = element.property(i);
- PlyPropertyWriter<double> prop_writer(&prop);
- int32_t num_entries = 1;
- if (prop.is_list()) {
- parser::SkipWhitespace(buffer);
- // Parse the number of entries for the list element.
- if (!parser::ParseSignedInt(buffer, &num_entries))
- return false;
-
- // Store offset to the main data entry.
- prop.list_data_.push_back(prop.data_.size() /
- prop.data_type_num_bytes_);
- // Store the number of entries.
- prop.list_data_.push_back(num_entries);
- }
- // Read and store the actual property data.
- for (int v = 0; v < num_entries; ++v) {
- parser::SkipWhitespace(buffer);
- if (prop.data_type() == DT_FLOAT32 || prop.data_type() == DT_FLOAT64) {
- float val;
- if (!parser::ParseFloat(buffer, &val))
- return false;
- prop_writer.PushBackValue(val);
- } else {
- int32_t val;
- if (!parser::ParseSignedInt(buffer, &val))
- return false;
- prop_writer.PushBackValue(val);
- }
- }
- }
- }
- return true;
-}
-
-std::vector<std::string> PlyReader::SplitWords(const std::string &line) {
- std::vector<std::string> output;
- std::string::size_type start = 0;
- std::string::size_type end = 0;
-
- // Check for isspace chars.
- while ((end = line.find_first_of(" \t\n\v\f\r", start)) !=
- std::string::npos) {
- const std::string word(line.substr(start, end - start));
- if (!std::all_of(word.begin(), word.end(), isspace))
- output.push_back(word);
- start = end + 1;
- }
-
- const std::string last_word(line.substr(start));
- if (!std::all_of(last_word.begin(), last_word.end(), isspace))
- output.push_back(last_word);
- return output;
-}
-
-DataType PlyReader::GetDataTypeFromString(const std::string &name) const {
- if (name == "char" || name == "int8")
- return DT_INT8;
- if (name == "uchar" || name == "uint8")
- return DT_UINT8;
- if (name == "short" || name == "int16")
- return DT_INT16;
- if (name == "ushort" || name == "uint16")
- return DT_UINT16;
- if (name == "int" || name == "int32")
- return DT_INT32;
- if (name == "uint" || name == "uint32")
- return DT_UINT32;
- if (name == "float" || name == "float32")
- return DT_FLOAT32;
- if (name == "double" || name == "float64") {
- return DT_FLOAT64;
- }
- return DT_INVALID;
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/io/ply_reader.h b/extern/draco/dracoenc/src/draco/io/ply_reader.h
deleted file mode 100644
index 845ef2326ae..00000000000
--- a/extern/draco/dracoenc/src/draco/io/ply_reader.h
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// File contains helper classes used for parsing of PLY files. The classes are
-// used by the PlyDecoder (ply_decoder.h) to read a point cloud or mesh from a
-// source PLY file.
-// TODO(ostava): Currently, we support only binary PLYs encoded in the little
-// endian format ("format binary_little_endian 1.0").
-
-#ifndef DRACO_IO_PLY_READER_H_
-#define DRACO_IO_PLY_READER_H_
-
-#include <map>
-#include <vector>
-
-#include "draco/core/decoder_buffer.h"
-#include "draco/core/draco_types.h"
-#include "draco/core/status.h"
-#include "draco/core/status_or.h"
-
-namespace draco {
-
-// A single PLY property of a given PLY element. For "vertex" element this can
-// contain data such as "x", "y", or "z" coordinate of the vertex, while for
-// "face" element this usually contains corner indices.
-class PlyProperty {
- public:
- friend class PlyReader;
-
- PlyProperty(const std::string &name, DataType data_type, DataType list_type);
- void ReserveData(int num_entries) {
- data_.reserve(DataTypeLength(data_type_) * num_entries);
- }
-
- int64_t GetListEntryOffset(int entry_id) const {
- return list_data_[entry_id * 2];
- }
- int64_t GetListEntryNumValues(int entry_id) const {
- return list_data_[entry_id * 2 + 1];
- }
- const void *GetDataEntryAddress(int entry_id) const {
- return data_.data() + entry_id * data_type_num_bytes_;
- }
- void push_back_value(const void *data) {
- data_.insert(data_.end(), static_cast<const uint8_t *>(data),
- static_cast<const uint8_t *>(data) + data_type_num_bytes_);
- }
-
- const std::string &name() const { return name_; }
- bool is_list() const { return list_data_type_ != DT_INVALID; }
- DataType data_type() const { return data_type_; }
- int data_type_num_bytes() const { return data_type_num_bytes_; }
- DataType list_data_type() const { return list_data_type_; }
- int list_data_type_num_bytes() const { return list_data_type_num_bytes_; }
-
- private:
- std::string name_;
- std::vector<uint8_t> data_;
- // List data contain pairs of <offset, number_of_values>
- std::vector<int64_t> list_data_;
- DataType data_type_;
- int data_type_num_bytes_;
- DataType list_data_type_;
- int list_data_type_num_bytes_;
-};
-
-// A single PLY element such as "vertex" or "face". Each element can store
-// arbitrary properties such as vertex coordinates or face indices.
-class PlyElement {
- public:
- PlyElement(const std::string &name, int64_t num_entries);
- void AddProperty(const PlyProperty &prop) {
- property_index_[prop.name()] = static_cast<int>(properties_.size());
- properties_.emplace_back(prop);
- if (!properties_.back().is_list())
- properties_.back().ReserveData(static_cast<int>(num_entries_));
- }
-
- const PlyProperty *GetPropertyByName(const std::string &name) const {
- const auto it = property_index_.find(name);
- if (it != property_index_.end())
- return &properties_[it->second];
- return nullptr;
- }
-
- int num_properties() const { return static_cast<int>(properties_.size()); }
- int num_entries() const { return static_cast<int>(num_entries_); }
- const PlyProperty &property(int prop_index) const {
- return properties_[prop_index];
- }
- PlyProperty &property(int prop_index) { return properties_[prop_index]; }
-
- private:
- std::string name_;
- int64_t num_entries_;
- std::vector<PlyProperty> properties_;
- std::map<std::string, int> property_index_;
-};
-
-// Class responsible for parsing PLY data. It produces a list of PLY elements
-// and their properties that can be used to construct a mesh or a point cloud.
-class PlyReader {
- public:
- PlyReader();
- Status Read(DecoderBuffer *buffer);
-
- const PlyElement *GetElementByName(const std::string &name) const {
- const auto it = element_index_.find(name);
- if (it != element_index_.end())
- return &elements_[it->second];
- return nullptr;
- }
-
- int num_elements() const { return static_cast<int>(elements_.size()); }
- const PlyElement &element(int element_index) const {
- return elements_[element_index];
- }
-
- private:
- enum Format { kLittleEndian = 0, kAscii };
-
- Status ParseHeader(DecoderBuffer *buffer);
- StatusOr<bool> ParseEndHeader(DecoderBuffer *buffer);
- bool ParseElement(DecoderBuffer *buffer);
- StatusOr<bool> ParseProperty(DecoderBuffer *buffer);
- bool ParsePropertiesData(DecoderBuffer *buffer);
- bool ParseElementData(DecoderBuffer *buffer, int element_index);
- bool ParseElementDataAscii(DecoderBuffer *buffer, int element_index);
-
- // Splits |line| by whitespace characters.
- std::vector<std::string> SplitWords(const std::string &line);
- DataType GetDataTypeFromString(const std::string &name) const;
-
- std::vector<PlyElement> elements_;
- std::map<std::string, int> element_index_;
- Format format_;
-};
-
-} // namespace draco
-
-#endif // DRACO_IO_PLY_READER_H_
diff --git a/extern/draco/dracoenc/src/draco/io/ply_reader_test.cc b/extern/draco/dracoenc/src/draco/io/ply_reader_test.cc
deleted file mode 100644
index 6804dc33de3..00000000000
--- a/extern/draco/dracoenc/src/draco/io/ply_reader_test.cc
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/io/ply_reader.h"
-
-#include <fstream>
-
-#include "draco/core/draco_test_base.h"
-#include "draco/core/draco_test_utils.h"
-#include "draco/io/ply_property_reader.h"
-
-namespace draco {
-
-class PlyReaderTest : public ::testing::Test {
- protected:
- std::vector<char> ReadPlyFile(const std::string &file_name) const {
- const std::string path = GetTestFileFullPath(file_name);
- std::ifstream file(path.c_str(), std::ios::binary);
- if (!file)
- return std::vector<char>();
- auto is_size = file.tellg();
- file.seekg(0, std::ios::end);
- is_size = file.tellg() - is_size;
- file.seekg(0, std::ios::beg);
- std::vector<char> data(is_size);
- file.read(&data[0], is_size);
- return data;
- }
-};
-
-TEST_F(PlyReaderTest, TestReader) {
- const std::string file_name = "test_pos_color.ply";
- const std::vector<char> data = ReadPlyFile(file_name);
- DecoderBuffer buf;
- buf.Init(data.data(), data.size());
- PlyReader reader;
- Status status = reader.Read(&buf);
- ASSERT_TRUE(status.ok()) << status;
- ASSERT_EQ(reader.num_elements(), 2);
- ASSERT_EQ(reader.element(0).num_properties(), 7);
- ASSERT_EQ(reader.element(1).num_properties(), 1);
- ASSERT_TRUE(reader.element(1).property(0).is_list());
-
- ASSERT_TRUE(reader.element(0).GetPropertyByName("red") != nullptr);
- const PlyProperty *const prop = reader.element(0).GetPropertyByName("red");
- PlyPropertyReader<uint8_t> reader_uint8(prop);
- PlyPropertyReader<uint32_t> reader_uint32(prop);
- PlyPropertyReader<float> reader_float(prop);
- for (int i = 0; i < reader.element(0).num_entries(); ++i) {
- ASSERT_EQ(reader_uint8.ReadValue(i), reader_uint32.ReadValue(i));
- ASSERT_EQ(reader_uint8.ReadValue(i), reader_float.ReadValue(i));
- }
-}
-
-TEST_F(PlyReaderTest, TestReaderAscii) {
- const std::string file_name = "test_pos_color.ply";
- const std::vector<char> data = ReadPlyFile(file_name);
- DecoderBuffer buf;
- buf.Init(data.data(), data.size());
- PlyReader reader;
- Status status = reader.Read(&buf);
- ASSERT_TRUE(status.ok()) << status;
-
- const std::string file_name_ascii = "test_pos_color_ascii.ply";
- const std::vector<char> data_ascii = ReadPlyFile(file_name_ascii);
- buf.Init(data_ascii.data(), data_ascii.size());
- PlyReader reader_ascii;
- status = reader_ascii.Read(&buf);
- ASSERT_TRUE(status.ok()) << status;
- ASSERT_EQ(reader.num_elements(), reader_ascii.num_elements());
- ASSERT_EQ(reader.element(0).num_properties(),
- reader_ascii.element(0).num_properties());
-
- ASSERT_TRUE(reader.element(0).GetPropertyByName("x") != nullptr);
- const PlyProperty *const prop = reader.element(0).GetPropertyByName("x");
- const PlyProperty *const prop_ascii =
- reader_ascii.element(0).GetPropertyByName("x");
- PlyPropertyReader<float> reader_float(prop);
- PlyPropertyReader<float> reader_float_ascii(prop_ascii);
- for (int i = 0; i < reader.element(0).num_entries(); ++i) {
- ASSERT_NEAR(reader_float.ReadValue(i), reader_float_ascii.ReadValue(i),
- 1e-4f);
- }
-}
-
-TEST_F(PlyReaderTest, TestReaderExtraWhitespace) {
- const std::string file_name = "test_extra_whitespace.ply";
- const std::vector<char> data = ReadPlyFile(file_name);
- DecoderBuffer buf;
- buf.Init(data.data(), data.size());
- PlyReader reader;
- Status status = reader.Read(&buf);
- ASSERT_TRUE(status.ok()) << status;
-
- ASSERT_EQ(reader.num_elements(), 2);
- ASSERT_EQ(reader.element(0).num_properties(), 7);
- ASSERT_EQ(reader.element(1).num_properties(), 1);
- ASSERT_TRUE(reader.element(1).property(0).is_list());
-
- ASSERT_TRUE(reader.element(0).GetPropertyByName("red") != nullptr);
- const PlyProperty *const prop = reader.element(0).GetPropertyByName("red");
- PlyPropertyReader<uint8_t> reader_uint8(prop);
- PlyPropertyReader<uint32_t> reader_uint32(prop);
- PlyPropertyReader<float> reader_float(prop);
- for (int i = 0; i < reader.element(0).num_entries(); ++i) {
- ASSERT_EQ(reader_uint8.ReadValue(i), reader_uint32.ReadValue(i));
- ASSERT_EQ(reader_uint8.ReadValue(i), reader_float.ReadValue(i));
- }
-}
-
-TEST_F(PlyReaderTest, TestReaderMoreDataTypes) {
- const std::string file_name = "test_more_datatypes.ply";
- const std::vector<char> data = ReadPlyFile(file_name);
- DecoderBuffer buf;
- buf.Init(data.data(), data.size());
- PlyReader reader;
- Status status = reader.Read(&buf);
- ASSERT_TRUE(status.ok()) << status;
-
- ASSERT_EQ(reader.num_elements(), 2);
- ASSERT_EQ(reader.element(0).num_properties(), 7);
- ASSERT_EQ(reader.element(1).num_properties(), 1);
- ASSERT_TRUE(reader.element(1).property(0).is_list());
-
- ASSERT_TRUE(reader.element(0).GetPropertyByName("red") != nullptr);
- const PlyProperty *const prop = reader.element(0).GetPropertyByName("red");
- PlyPropertyReader<uint8_t> reader_uint8(prop);
- PlyPropertyReader<uint32_t> reader_uint32(prop);
- PlyPropertyReader<float> reader_float(prop);
- for (int i = 0; i < reader.element(0).num_entries(); ++i) {
- ASSERT_EQ(reader_uint8.ReadValue(i), reader_uint32.ReadValue(i));
- ASSERT_EQ(reader_uint8.ReadValue(i), reader_float.ReadValue(i));
- }
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/io/point_cloud_io.cc b/extern/draco/dracoenc/src/draco/io/point_cloud_io.cc
deleted file mode 100644
index e91142eaaea..00000000000
--- a/extern/draco/dracoenc/src/draco/io/point_cloud_io.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/io/point_cloud_io.h"
-
-#include <fstream>
-
-#include "draco/io/obj_decoder.h"
-#include "draco/io/parser_utils.h"
-#include "draco/io/ply_decoder.h"
-
-namespace draco {
-
-StatusOr<std::unique_ptr<PointCloud>> ReadPointCloudFromFile(
- const std::string &file_name) {
- std::unique_ptr<PointCloud> pc(new PointCloud());
- // Analyze file extension.
- const std::string extension = parser::ToLower(
- file_name.size() >= 4 ? file_name.substr(file_name.size() - 4)
- : file_name);
- if (extension == ".obj") {
- // Wavefront OBJ file format.
- ObjDecoder obj_decoder;
- const Status obj_status = obj_decoder.DecodeFromFile(file_name, pc.get());
- if (!obj_status.ok())
- return obj_status;
- return std::move(pc);
- }
- if (extension == ".ply") {
- // Wavefront PLY file format.
- PlyDecoder ply_decoder;
- DRACO_RETURN_IF_ERROR(ply_decoder.DecodeFromFile(file_name, pc.get()));
- return std::move(pc);
- }
-
- // Otherwise not an obj file. Assume the file was encoded with one of the
- // draco encoding methods.
- std::ifstream is(file_name.c_str(), std::ios::binary);
- if (!is)
- return Status(Status::DRACO_ERROR, "Invalid input stream.");
- if (!ReadPointCloudFromStream(&pc, is).good())
- return Status(Status::DRACO_ERROR,
- "Unknown error."); // Error reading the stream.
- return std::move(pc);
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/io/point_cloud_io.h b/extern/draco/dracoenc/src/draco/io/point_cloud_io.h
deleted file mode 100644
index 4e1eb359644..00000000000
--- a/extern/draco/dracoenc/src/draco/io/point_cloud_io.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#ifndef DRACO_IO_POINT_CLOUD_IO_H_
-#define DRACO_IO_POINT_CLOUD_IO_H_
-
-#include "draco/compression/config/compression_shared.h"
-#include "draco/compression/decode.h"
-#include "draco/compression/expert_encode.h"
-
-namespace draco {
-
-template <typename OutStreamT>
-OutStreamT WritePointCloudIntoStream(const PointCloud *pc, OutStreamT &&os,
- PointCloudEncodingMethod method,
- const EncoderOptions &options) {
- EncoderBuffer buffer;
- EncoderOptions local_options = options;
- ExpertEncoder encoder(*pc);
- encoder.Reset(local_options);
- encoder.SetEncodingMethod(method);
- if (!encoder.EncodeToBuffer(&buffer).ok()) {
- os.setstate(std::ios_base::badbit);
- return os;
- }
-
- os.write(static_cast<const char *>(buffer.data()), buffer.size());
-
- return os;
-}
-
-template <typename OutStreamT>
-OutStreamT WritePointCloudIntoStream(const PointCloud *pc, OutStreamT &&os,
- PointCloudEncodingMethod method) {
- const EncoderOptions options = EncoderOptions::CreateDefaultOptions();
- return WritePointCloudIntoStream(pc, os, method, options);
-}
-
-template <typename OutStreamT>
-OutStreamT &WritePointCloudIntoStream(const PointCloud *pc, OutStreamT &&os) {
- return WritePointCloudIntoStream(pc, os, POINT_CLOUD_SEQUENTIAL_ENCODING);
-}
-
-template <typename InStreamT>
-InStreamT &ReadPointCloudFromStream(std::unique_ptr<PointCloud> *point_cloud,
- InStreamT &&is) {
- // Determine size of stream and write into a vector
- const auto start_pos = is.tellg();
- is.seekg(0, std::ios::end);
- const std::streampos is_size = is.tellg() - start_pos;
- is.seekg(start_pos);
- std::vector<char> data(is_size);
- is.read(&data[0], is_size);
-
- // Create a point cloud from that data.
- DecoderBuffer buffer;
- buffer.Init(&data[0], data.size());
- Decoder decoder;
- auto statusor = decoder.DecodePointCloudFromBuffer(&buffer);
- *point_cloud = std::move(statusor).value();
- if (!statusor.ok() || *point_cloud == nullptr) {
- is.setstate(std::ios_base::badbit);
- }
-
- return is;
-}
-
-// Reads a point cloud from a file. The function automatically chooses the
-// correct decoder based on the extension of the files. Currently, .obj and .ply
-// files are supported. Other file extensions are processed by the default
-// draco::PointCloudDecoder.
-// Returns nullptr with an error status if the decoding failed.
-StatusOr<std::unique_ptr<PointCloud>> ReadPointCloudFromFile(
- const std::string &file_name);
-
-} // namespace draco
-
-#endif // DRACO_IO_POINT_CLOUD_IO_H_
diff --git a/extern/draco/dracoenc/src/draco/io/point_cloud_io_test.cc b/extern/draco/dracoenc/src/draco/io/point_cloud_io_test.cc
deleted file mode 100644
index 73674d06f55..00000000000
--- a/extern/draco/dracoenc/src/draco/io/point_cloud_io_test.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/io/point_cloud_io.h"
-
-#include <sstream>
-
-#include "draco/core/draco_test_base.h"
-#include "draco/core/draco_test_utils.h"
-#include "draco/io/obj_decoder.h"
-
-namespace draco {
-
-class IoPointCloudIoTest : public ::testing::Test {
- protected:
- void test_compression_method(PointCloudEncodingMethod method,
- int expected_num_attributes,
- const std::string &file_name) {
- const std::unique_ptr<PointCloud> encoded_pc =
- ReadPointCloudFromTestFile(file_name);
- ASSERT_NE(encoded_pc, nullptr) << "Failed to load test model " << file_name;
- ASSERT_GE(encoded_pc->num_attributes(), expected_num_attributes)
- << "Failed to load test model: " << file_name
- << " wrong number of attributes" << std::endl;
-
- // Set quantization.
- EncoderOptions options = EncoderOptions::CreateDefaultOptions();
- for (int i = 0; i <= GeometryAttribute::NAMED_ATTRIBUTES_COUNT; i++) {
- options.SetAttributeInt(GeometryAttribute::Type(i), "quantization_bits",
- 14);
- }
-
- std::stringstream ss;
- WritePointCloudIntoStream(encoded_pc.get(), ss, method, options);
- ASSERT_TRUE(ss.good());
-
- std::unique_ptr<PointCloud> decoded_pc;
- ReadPointCloudFromStream(&decoded_pc, ss);
- ASSERT_TRUE(ss.good());
-
- for (int i = 0; i <= GeometryAttribute::NAMED_ATTRIBUTES_COUNT; i++) {
- ASSERT_EQ(encoded_pc->NumNamedAttributes(GeometryAttribute::Type(i)),
- decoded_pc->NumNamedAttributes(GeometryAttribute::Type(i)));
- }
-
- ASSERT_EQ(encoded_pc->num_points(), decoded_pc->num_points());
- }
-};
-
-TEST_F(IoPointCloudIoTest, EncodeSequentialPointCloudTestNmObj) {
- test_compression_method(POINT_CLOUD_SEQUENTIAL_ENCODING, 2, "test_nm.obj");
-}
-TEST_F(IoPointCloudIoTest, EncodeSequentialPointCloudTestPosObj) {
- test_compression_method(POINT_CLOUD_SEQUENTIAL_ENCODING, 1,
- "point_cloud_test_pos.obj");
-}
-TEST_F(IoPointCloudIoTest, EncodeSequentialPointCloudTestPosPly) {
- test_compression_method(POINT_CLOUD_SEQUENTIAL_ENCODING, 1,
- "point_cloud_test_pos.ply");
-}
-TEST_F(IoPointCloudIoTest, EncodeSequentialPointCloudTestPosNormObj) {
- test_compression_method(POINT_CLOUD_SEQUENTIAL_ENCODING, 2,
- "point_cloud_test_pos_norm.obj");
-}
-TEST_F(IoPointCloudIoTest, EncodeSequentialPointCloudTestPosNormPly) {
- test_compression_method(POINT_CLOUD_SEQUENTIAL_ENCODING, 2,
- "point_cloud_test_pos_norm.ply");
-}
-
-TEST_F(IoPointCloudIoTest, EncodeKdTreePointCloudTestPosObj) {
- test_compression_method(POINT_CLOUD_KD_TREE_ENCODING, 1,
- "point_cloud_test_pos.obj");
-}
-TEST_F(IoPointCloudIoTest, EncodeKdTreePointCloudTestPosPly) {
- test_compression_method(POINT_CLOUD_KD_TREE_ENCODING, 1,
- "point_cloud_test_pos.ply");
-}
-
-TEST_F(IoPointCloudIoTest, ObjFileInput) {
- // Tests whether loading obj point clouds from files works as expected.
- const std::unique_ptr<PointCloud> pc =
- ReadPointCloudFromTestFile("test_nm.obj");
- ASSERT_NE(pc, nullptr) << "Failed to load the obj point cloud.";
- EXPECT_EQ(pc->num_points(), 97) << "Obj point cloud not loaded properly.";
-}
-
-// Test if we handle wrong input for all file extensions.
-TEST_F(IoPointCloudIoTest, WrongFileObj) {
- const std::unique_ptr<PointCloud> pc =
- ReadPointCloudFromTestFile("wrong_file_name.obj");
- ASSERT_EQ(pc, nullptr);
-}
-TEST_F(IoPointCloudIoTest, WrongFilePly) {
- const std::unique_ptr<PointCloud> pc =
- ReadPointCloudFromTestFile("wrong_file_name.ply");
- ASSERT_EQ(pc, nullptr);
-}
-TEST_F(IoPointCloudIoTest, WrongFile) {
- const std::unique_ptr<PointCloud> pc =
- ReadPointCloudFromTestFile("wrong_file_name");
- ASSERT_EQ(pc, nullptr);
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/mesh/mesh_are_equivalent_test.cc b/extern/draco/dracoenc/src/draco/mesh/mesh_are_equivalent_test.cc
deleted file mode 100644
index ff633bc73d1..00000000000
--- a/extern/draco/dracoenc/src/draco/mesh/mesh_are_equivalent_test.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/mesh/mesh_are_equivalent.h"
-
-#include <sstream>
-
-#include "draco/core/draco_test_base.h"
-#include "draco/core/draco_test_utils.h"
-#include "draco/io/mesh_io.h"
-#include "draco/io/obj_decoder.h"
-#include "draco/mesh/mesh.h"
-
-namespace draco {
-
-class MeshAreEquivalentTest : public ::testing::Test {};
-
-TEST_F(MeshAreEquivalentTest, TestOnIndenticalMesh) {
- const std::string file_name = "test_nm.obj";
- const std::unique_ptr<Mesh> mesh(ReadMeshFromTestFile(file_name));
- ASSERT_NE(mesh, nullptr) << "Failed to load test model." << file_name;
- MeshAreEquivalent equiv;
- ASSERT_TRUE(equiv(*mesh, *mesh));
-}
-
-TEST_F(MeshAreEquivalentTest, TestPermutedOneFace) {
- const std::string file_name_0 = "one_face_123.obj";
- const std::string file_name_1 = "one_face_312.obj";
- const std::string file_name_2 = "one_face_321.obj";
- const std::unique_ptr<Mesh> mesh_0(ReadMeshFromTestFile(file_name_0));
- const std::unique_ptr<Mesh> mesh_1(ReadMeshFromTestFile(file_name_1));
- const std::unique_ptr<Mesh> mesh_2(ReadMeshFromTestFile(file_name_2));
- ASSERT_NE(mesh_0, nullptr) << "Failed to load test model." << file_name_0;
- ASSERT_NE(mesh_1, nullptr) << "Failed to load test model." << file_name_1;
- ASSERT_NE(mesh_2, nullptr) << "Failed to load test model." << file_name_2;
- MeshAreEquivalent equiv;
- ASSERT_TRUE(equiv(*mesh_0, *mesh_0));
- ASSERT_TRUE(equiv(*mesh_0, *mesh_1)); // Face rotated.
- ASSERT_FALSE(equiv(*mesh_0, *mesh_2)); // Face inverted.
-}
-
-TEST_F(MeshAreEquivalentTest, TestPermutedTwoFaces) {
- const std::string file_name_0 = "two_faces_123.obj";
- const std::string file_name_1 = "two_faces_312.obj";
- const std::unique_ptr<Mesh> mesh_0(ReadMeshFromTestFile(file_name_0));
- const std::unique_ptr<Mesh> mesh_1(ReadMeshFromTestFile(file_name_1));
- ASSERT_NE(mesh_0, nullptr) << "Failed to load test model." << file_name_0;
- ASSERT_NE(mesh_1, nullptr) << "Failed to load test model." << file_name_1;
- MeshAreEquivalent equiv;
- ASSERT_TRUE(equiv(*mesh_0, *mesh_0));
- ASSERT_TRUE(equiv(*mesh_1, *mesh_1));
- ASSERT_TRUE(equiv(*mesh_0, *mesh_1));
-}
-
-//
-TEST_F(MeshAreEquivalentTest, TestPermutedThreeFaces) {
- const std::string file_name_0 = "three_faces_123.obj";
- const std::string file_name_1 = "three_faces_312.obj";
- const std::unique_ptr<Mesh> mesh_0(ReadMeshFromTestFile(file_name_0));
- const std::unique_ptr<Mesh> mesh_1(ReadMeshFromTestFile(file_name_1));
- ASSERT_NE(mesh_0, nullptr) << "Failed to load test model." << file_name_0;
- ASSERT_NE(mesh_1, nullptr) << "Failed to load test model." << file_name_1;
- MeshAreEquivalent equiv;
- ASSERT_TRUE(equiv(*mesh_0, *mesh_0));
- ASSERT_TRUE(equiv(*mesh_1, *mesh_1));
- ASSERT_TRUE(equiv(*mesh_0, *mesh_1));
-}
-
-// This test checks that the edgebreaker algorithm does not change the mesh up
-// to the order of faces and vertices.
-TEST_F(MeshAreEquivalentTest, TestOnBigMesh) {
- const std::string file_name = "test_nm.obj";
- const std::unique_ptr<Mesh> mesh0(ReadMeshFromTestFile(file_name));
- ASSERT_NE(mesh0, nullptr) << "Failed to load test model." << file_name;
-
- std::unique_ptr<Mesh> mesh1;
- std::stringstream ss;
- WriteMeshIntoStream(mesh0.get(), ss, MESH_EDGEBREAKER_ENCODING);
- ReadMeshFromStream(&mesh1, ss);
- ASSERT_TRUE(ss.good()) << "Mesh IO failed.";
-
- MeshAreEquivalent equiv;
- ASSERT_TRUE(equiv(*mesh0, *mesh0));
- ASSERT_TRUE(equiv(*mesh1, *mesh1));
- ASSERT_TRUE(equiv(*mesh0, *mesh1));
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/mesh/mesh_cleanup_test.cc b/extern/draco/dracoenc/src/draco/mesh/mesh_cleanup_test.cc
deleted file mode 100644
index 1051d193d87..00000000000
--- a/extern/draco/dracoenc/src/draco/mesh/mesh_cleanup_test.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/mesh/mesh_cleanup.h"
-
-#include "draco/core/draco_test_base.h"
-#include "draco/core/vector_d.h"
-#include "draco/mesh/triangle_soup_mesh_builder.h"
-
-namespace draco {
-
-class MeshCleanupTest : public ::testing::Test {};
-
-TEST_F(MeshCleanupTest, TestDegneratedFaces) {
- // This test verifies that the mesh cleanup tools removes degenerated faces.
- TriangleSoupMeshBuilder mb;
- mb.Start(2);
- const int pos_att_id =
- mb.AddAttribute(GeometryAttribute::POSITION, 3, DT_FLOAT32);
- // clang-format off
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(0),
- Vector3f(0.f, 0.f, 0.f).data(),
- Vector3f(1.f, 0.f, 0.f).data(),
- Vector3f(0.f, 1.f, 0.f).data());
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(1),
- Vector3f(0.f, 1.f, 0.f).data(),
- Vector3f(1.f, 0.f, 0.f).data(),
- Vector3f(1.f, 0.f, 0.f).data());
- // clang-format on
-
- std::unique_ptr<Mesh> mesh = mb.Finalize();
- ASSERT_NE(mesh, nullptr) << "Failed to build the test mesh.";
- ASSERT_EQ(mesh->num_faces(), 2) << "Wrong number of faces in the input mesh.";
- MeshCleanupOptions cleanup_options;
- MeshCleanup cleanup;
- ASSERT_TRUE(cleanup(mesh.get(), cleanup_options))
- << "Failed to cleanup the mesh.";
- ASSERT_EQ(mesh->num_faces(), 1) << "Failed to remove degenerated faces.";
-}
-
-TEST_F(MeshCleanupTest, TestDegneratedFacesAndIsolatedVertices) {
- // This test verifies that the mesh cleanup tools removes degenerated faces
- // and isolated vertices.
- TriangleSoupMeshBuilder mb;
- mb.Start(2);
- const int pos_att_id =
- mb.AddAttribute(GeometryAttribute::POSITION, 3, DT_FLOAT32);
- // clang-format off
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(0),
- Vector3f(0.f, 0.f, 0.f).data(),
- Vector3f(1.f, 0.f, 0.f).data(),
- Vector3f(0.f, 1.f, 0.f).data());
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(1),
- Vector3f(10.f, 1.f, 0.f).data(),
- Vector3f(1.f, 0.f, 0.f).data(),
- Vector3f(10.f, 1.f, 0.f).data());
- // clang-format on
-
- std::unique_ptr<Mesh> mesh = mb.Finalize();
- ASSERT_NE(mesh, nullptr) << "Failed to build the test mesh.";
- ASSERT_EQ(mesh->num_faces(), 2) << "Wrong number of faces in the input mesh.";
- ASSERT_EQ(mesh->num_points(), 4)
- << "Wrong number of point ids in the input mesh.";
- const MeshCleanupOptions cleanup_options;
- MeshCleanup cleanup;
- ASSERT_TRUE(cleanup(mesh.get(), cleanup_options))
- << "Failed to cleanup the mesh.";
- ASSERT_EQ(mesh->num_faces(), 1) << "Failed to remove degenerated faces.";
- ASSERT_EQ(mesh->num_points(), 3)
- << "Failed to remove isolated attribute indices.";
-}
-
-TEST_F(MeshCleanupTest, TestAttributes) {
- TriangleSoupMeshBuilder mb;
- mb.Start(2);
- const int pos_att_id =
- mb.AddAttribute(GeometryAttribute::POSITION, 3, DT_FLOAT32);
- const int generic_att_id =
- mb.AddAttribute(GeometryAttribute::GENERIC, 2, DT_FLOAT32);
- // clang-format off
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(0),
- Vector3f(0.f, 0.f, 0.f).data(),
- Vector3f(1.f, 0.f, 0.f).data(),
- Vector3f(0.f, 1.f, 0.f).data());
- mb.SetAttributeValuesForFace(generic_att_id, FaceIndex(0),
- Vector2f(0.f, 0.f).data(),
- Vector2f(0.f, 0.f).data(),
- Vector2f(0.f, 0.f).data());
-
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(1),
- Vector3f(10.f, 1.f, 0.f).data(),
- Vector3f(1.f, 0.f, 0.f).data(),
- Vector3f(10.f, 1.f, 0.f).data());
- mb.SetAttributeValuesForFace(generic_att_id, FaceIndex(1),
- Vector2f(1.f, 0.f).data(),
- Vector2f(1.f, 0.f).data(),
- Vector2f(1.f, 0.f).data());
- // clang-format on
-
- std::unique_ptr<Mesh> mesh = mb.Finalize();
- ASSERT_NE(mesh, nullptr) << "Failed to build the test mesh.";
- ASSERT_EQ(mesh->num_faces(), 2) << "Wrong number of faces in the input mesh.";
- ASSERT_EQ(mesh->num_points(), 5)
- << "Wrong number of point ids in the input mesh.";
- ASSERT_EQ(mesh->attribute(1)->size(), 2u)
- << "Wrong number of generic attribute entries.";
- const MeshCleanupOptions cleanup_options;
- MeshCleanup cleanup;
- ASSERT_TRUE(cleanup(mesh.get(), cleanup_options))
- << "Failed to cleanup the mesh.";
- ASSERT_EQ(mesh->num_faces(), 1) << "Failed to remove degenerated faces.";
- ASSERT_EQ(mesh->num_points(), 3)
- << "Failed to remove isolated attribute indices.";
- ASSERT_EQ(mesh->attribute(0)->size(), 3u)
- << "Wrong number of unique positions after cleanup.";
- ASSERT_EQ(mesh->attribute(1)->size(), 1u)
- << "Wrong number of generic attribute entries after cleanup.";
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/mesh/triangle_soup_mesh_builder_test.cc b/extern/draco/dracoenc/src/draco/mesh/triangle_soup_mesh_builder_test.cc
deleted file mode 100644
index 171f8fe24a1..00000000000
--- a/extern/draco/dracoenc/src/draco/mesh/triangle_soup_mesh_builder_test.cc
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/mesh/triangle_soup_mesh_builder.h"
-
-#include "draco/core/draco_test_base.h"
-#include "draco/core/vector_d.h"
-
-namespace draco {
-
-class TriangleSoupMeshBuilderTest : public ::testing::Test {};
-
-TEST_F(TriangleSoupMeshBuilderTest, CubeTest) {
- // This tests, verifies that the mesh builder constructs a valid cube out
- // of the provided triangle soup data.
- TriangleSoupMeshBuilder mb;
- mb.Start(12);
- const int pos_att_id =
- mb.AddAttribute(GeometryAttribute::POSITION, 3, DT_FLOAT32);
- // clang-format off
- // Front face.
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(0),
- Vector3f(0.f, 0.f, 0.f).data(),
- Vector3f(1.f, 0.f, 0.f).data(),
- Vector3f(0.f, 1.f, 0.f).data());
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(1),
- Vector3f(0.f, 1.f, 0.f).data(),
- Vector3f(1.f, 0.f, 0.f).data(),
- Vector3f(1.f, 1.f, 0.f).data());
-
- // Back face.
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(2),
- Vector3f(0.f, 1.f, 1.f).data(),
- Vector3f(1.f, 0.f, 1.f).data(),
- Vector3f(0.f, 0.f, 1.f).data());
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(3),
- Vector3f(1.f, 1.f, 1.f).data(),
- Vector3f(1.f, 0.f, 1.f).data(),
- Vector3f(0.f, 1.f, 1.f).data());
-
- // Top face.
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(4),
- Vector3f(0.f, 1.f, 0.f).data(),
- Vector3f(1.f, 1.f, 0.f).data(),
- Vector3f(0.f, 1.f, 1.f).data());
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(5),
- Vector3f(0.f, 1.f, 1.f).data(),
- Vector3f(1.f, 1.f, 0.f).data(),
- Vector3f(1.f, 1.f, 1.f).data());
-
- // Bottom face.
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(6),
- Vector3f(0.f, 0.f, 1.f).data(),
- Vector3f(1.f, 0.f, 0.f).data(),
- Vector3f(0.f, 0.f, 0.f).data());
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(7),
- Vector3f(1.f, 0.f, 1.f).data(),
- Vector3f(1.f, 0.f, 0.f).data(),
- Vector3f(0.f, 0.f, 1.f).data());
-
- // Right face.
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(8),
- Vector3f(1.f, 0.f, 0.f).data(),
- Vector3f(1.f, 0.f, 1.f).data(),
- Vector3f(1.f, 1.f, 0.f).data());
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(9),
- Vector3f(1.f, 1.f, 0.f).data(),
- Vector3f(1.f, 0.f, 1.f).data(),
- Vector3f(1.f, 1.f, 1.f).data());
-
- // Left face.
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(10),
- Vector3f(0.f, 1.f, 0.f).data(),
- Vector3f(0.f, 0.f, 1.f).data(),
- Vector3f(0.f, 0.f, 0.f).data());
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(11),
- Vector3f(0.f, 1.f, 1.f).data(),
- Vector3f(0.f, 0.f, 1.f).data(),
- Vector3f(0.f, 1.f, 0.f).data());
- // clang-format on
-
- std::unique_ptr<Mesh> mesh = mb.Finalize();
- ASSERT_NE(mesh, nullptr) << "Failed to build the cube mesh.";
- EXPECT_EQ(mesh->num_points(), 8) << "Unexpected number of vertices.";
- EXPECT_EQ(mesh->num_faces(), 12) << "Unexpected number of faces.";
-}
-
-TEST_F(TriangleSoupMeshBuilderTest, TestPerFaceAttribs) {
- // This tests, verifies that the mesh builder constructs a valid cube with
- // per face Boolean attributes.
- TriangleSoupMeshBuilder mb;
- mb.Start(12);
- const int pos_att_id =
- mb.AddAttribute(GeometryAttribute::POSITION, 3, DT_FLOAT32);
- const int gen_att_id =
- mb.AddAttribute(GeometryAttribute::GENERIC, 1, DT_BOOL);
- uint8_t bool_true = 1;
- uint8_t bool_false = 0;
- // clang-format off
- // Front face.
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(0),
- Vector3f(0.f, 0.f, 0.f).data(),
- Vector3f(1.f, 0.f, 0.f).data(),
- Vector3f(0.f, 1.f, 0.f).data());
- mb.SetPerFaceAttributeValueForFace(gen_att_id, FaceIndex(0), &bool_false);
-
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(1),
- Vector3f(0.f, 1.f, 0.f).data(),
- Vector3f(1.f, 0.f, 0.f).data(),
- Vector3f(1.f, 1.f, 0.f).data());
- mb.SetPerFaceAttributeValueForFace(gen_att_id, FaceIndex(1), &bool_true);
-
- // Back face.
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(2),
- Vector3f(0.f, 1.f, 1.f).data(),
- Vector3f(1.f, 0.f, 1.f).data(),
- Vector3f(0.f, 0.f, 1.f).data());
- mb.SetPerFaceAttributeValueForFace(gen_att_id, FaceIndex(2), &bool_true);
-
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(3),
- Vector3f(1.f, 1.f, 1.f).data(),
- Vector3f(1.f, 0.f, 1.f).data(),
- Vector3f(0.f, 1.f, 1.f).data());
- mb.SetPerFaceAttributeValueForFace(gen_att_id, FaceIndex(3), &bool_true);
-
- // Top face.
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(4),
- Vector3f(0.f, 1.f, 0.f).data(),
- Vector3f(1.f, 1.f, 0.f).data(),
- Vector3f(0.f, 1.f, 1.f).data());
- mb.SetPerFaceAttributeValueForFace(gen_att_id, FaceIndex(4), &bool_false);;
-
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(5),
- Vector3f(0.f, 1.f, 1.f).data(),
- Vector3f(1.f, 1.f, 0.f).data(),
- Vector3f(1.f, 1.f, 1.f).data());
- mb.SetPerFaceAttributeValueForFace(gen_att_id, FaceIndex(5), &bool_false);
-
- // Bottom face.
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(6),
- Vector3f(0.f, 0.f, 1.f).data(),
- Vector3f(1.f, 0.f, 0.f).data(),
- Vector3f(0.f, 0.f, 0.f).data());
- mb.SetPerFaceAttributeValueForFace(gen_att_id, FaceIndex(6), &bool_true);
-
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(7),
- Vector3f(1.f, 0.f, 1.f).data(),
- Vector3f(1.f, 0.f, 0.f).data(),
- Vector3f(0.f, 0.f, 1.f).data());
- mb.SetPerFaceAttributeValueForFace(gen_att_id, FaceIndex(7), &bool_true);
-
- // Right face.
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(8),
- Vector3f(1.f, 0.f, 0.f).data(),
- Vector3f(1.f, 0.f, 1.f).data(),
- Vector3f(1.f, 1.f, 0.f).data());
- mb.SetPerFaceAttributeValueForFace(gen_att_id, FaceIndex(8), &bool_false);
-
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(9),
- Vector3f(1.f, 1.f, 0.f).data(),
- Vector3f(1.f, 0.f, 1.f).data(),
- Vector3f(1.f, 1.f, 1.f).data());
- mb.SetPerFaceAttributeValueForFace(gen_att_id, FaceIndex(9), &bool_true);
-
- // Left face.
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(10),
- Vector3f(0.f, 1.f, 0.f).data(),
- Vector3f(0.f, 0.f, 1.f).data(),
- Vector3f(0.f, 0.f, 0.f).data());
- mb.SetPerFaceAttributeValueForFace(gen_att_id, FaceIndex(10), &bool_true);
-
- mb.SetAttributeValuesForFace(pos_att_id, FaceIndex(11),
- Vector3f(0.f, 1.f, 1.f).data(),
- Vector3f(0.f, 0.f, 1.f).data(),
- Vector3f(0.f, 1.f, 0.f).data());
- mb.SetPerFaceAttributeValueForFace(gen_att_id, FaceIndex(11), &bool_false);
- // clang-format on
-
- std::unique_ptr<Mesh> mesh = mb.Finalize();
- ASSERT_NE(mesh, nullptr) << "Failed to build the cube mesh.";
- EXPECT_EQ(mesh->num_faces(), 12) << "Unexpected number of faces.";
- EXPECT_EQ(mesh->GetAttributeElementType(gen_att_id), MESH_FACE_ATTRIBUTE)
- << "Unexpected attribute element type.";
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/metadata/metadata_encoder_test.cc b/extern/draco/dracoenc/src/draco/metadata/metadata_encoder_test.cc
deleted file mode 100644
index d8f7f2f6649..00000000000
--- a/extern/draco/dracoenc/src/draco/metadata/metadata_encoder_test.cc
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2017 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/metadata/metadata_encoder.h"
-#include "draco/core/decoder_buffer.h"
-#include "draco/core/draco_test_base.h"
-#include "draco/core/encoder_buffer.h"
-#include "draco/metadata/metadata.h"
-#include "draco/metadata/metadata_decoder.h"
-
-namespace {
-
-class MetadataEncoderTest : public ::testing::Test {
- protected:
- MetadataEncoderTest() {}
-
- void TestEncodingMetadata() {
- ASSERT_TRUE(encoder.EncodeMetadata(&encoder_buffer, &metadata));
-
- draco::Metadata decoded_metadata;
- decoder_buffer.Init(encoder_buffer.data(), encoder_buffer.size());
- ASSERT_TRUE(decoder.DecodeMetadata(&decoder_buffer, &decoded_metadata));
- CheckMetadatasAreEqual(metadata, decoded_metadata);
- }
-
- void TestEncodingGeometryMetadata() {
- ASSERT_TRUE(
- encoder.EncodeGeometryMetadata(&encoder_buffer, &geometry_metadata));
-
- draco::GeometryMetadata decoded_metadata;
- decoder_buffer.Init(encoder_buffer.data(), encoder_buffer.size());
- ASSERT_TRUE(
- decoder.DecodeGeometryMetadata(&decoder_buffer, &decoded_metadata));
- CheckGeometryMetadatasAreEqual(geometry_metadata, decoded_metadata);
- }
-
- void CheckBlobOfDataAreEqual(const std::vector<uint8_t> &data0,
- const std::vector<uint8_t> &data1) {
- ASSERT_EQ(data0.size(), data1.size());
- for (int i = 0; i < data0.size(); ++i)
- ASSERT_EQ(data0[i], data1[i]);
- }
-
- void CheckGeometryMetadatasAreEqual(
- const draco::GeometryMetadata &metadata0,
- const draco::GeometryMetadata &metadata1) {
- ASSERT_EQ(metadata0.attribute_metadatas().size(),
- metadata1.attribute_metadatas().size());
- const std::vector<std::unique_ptr<draco::AttributeMetadata>>
- &att_metadatas0 = metadata0.attribute_metadatas();
- const std::vector<std::unique_ptr<draco::AttributeMetadata>>
- &att_metadatas1 = metadata1.attribute_metadatas();
- // Compare each attribute metadata.
- for (int i = 0; i < metadata0.attribute_metadatas().size(); ++i) {
- CheckMetadatasAreEqual(
- static_cast<const draco::Metadata &>(*att_metadatas0[i]),
- static_cast<const draco::Metadata &>(*att_metadatas1[i]));
- }
- // Compare entries and sub metadata.
- CheckMetadatasAreEqual(static_cast<const draco::Metadata &>(metadata0),
- static_cast<const draco::Metadata &>(metadata1));
- }
-
- void CheckMetadatasAreEqual(const draco::Metadata &metadata0,
- const draco::Metadata &metadata1) {
- ASSERT_EQ(metadata0.num_entries(), metadata1.num_entries());
- const std::map<std::string, draco::EntryValue> &entries0 =
- metadata0.entries();
- const std::map<std::string, draco::EntryValue> &entries1 =
- metadata1.entries();
- for (const auto &entry : entries0) {
- const std::string &entry_name = entry.first;
- const std::vector<uint8_t> &data0 = entry.second.data();
- const auto entry1_ptr = entries1.find(entry_name);
- ASSERT_NE(entry1_ptr, entries1.end());
- const std::vector<uint8_t> &data1 = entry1_ptr->second.data();
- CheckBlobOfDataAreEqual(data0, data1);
- }
- // Check nested metadata.
- ASSERT_EQ(metadata0.sub_metadatas().size(),
- metadata1.sub_metadatas().size());
- const std::map<std::string, std::unique_ptr<draco::Metadata>>
- &sub_metadatas0 = metadata0.sub_metadatas();
- // Encode each sub-metadata
- for (auto &&sub_metadata_entry0 : sub_metadatas0) {
- const auto sub_metadata_ptr1 =
- metadata1.GetSubMetadata(sub_metadata_entry0.first);
- ASSERT_NE(sub_metadata_ptr1, nullptr);
- CheckMetadatasAreEqual(*sub_metadata_entry0.second, *sub_metadata_ptr1);
- }
- }
-
- draco::MetadataEncoder encoder;
- draco::MetadataDecoder decoder;
- draco::EncoderBuffer encoder_buffer;
- draco::DecoderBuffer decoder_buffer;
- draco::Metadata metadata;
- draco::GeometryMetadata geometry_metadata;
-};
-
-TEST_F(MetadataEncoderTest, TestSingleEntry) {
- metadata.AddEntryInt("int", 100);
- ASSERT_EQ(metadata.num_entries(), 1);
-
- TestEncodingMetadata();
-}
-
-TEST_F(MetadataEncoderTest, TestMultipleEntries) {
- metadata.AddEntryInt("int", 100);
- metadata.AddEntryDouble("double", 1.234);
- const std::string entry_value = "test string entry";
- metadata.AddEntryString("string", entry_value);
- ASSERT_EQ(metadata.num_entries(), 3);
-
- TestEncodingMetadata();
-}
-
-TEST_F(MetadataEncoderTest, TestEncodingArrayEntries) {
- std::vector<int32_t> int_array({1, 2, 3});
- metadata.AddEntryIntArray("int_array", int_array);
- std::vector<double> double_array({0.1, 0.2, 0.3});
- metadata.AddEntryDoubleArray("double_array", double_array);
- ASSERT_EQ(metadata.num_entries(), 2);
-
- TestEncodingMetadata();
-}
-
-TEST_F(MetadataEncoderTest, TestEncodingBinaryEntry) {
- const std::vector<uint8_t> binarydata({0x1, 0x2, 0x3, 0x4});
- metadata.AddEntryBinary("binary_data", binarydata);
-
- TestEncodingMetadata();
-}
-
-TEST_F(MetadataEncoderTest, TestEncodingNestedMetadata) {
- metadata.AddEntryDouble("double", 1.234);
- std::unique_ptr<draco::Metadata> sub_metadata =
- std::unique_ptr<draco::Metadata>(new draco::Metadata());
- sub_metadata->AddEntryInt("int", 100);
- metadata.AddSubMetadata("sub0", std::move(sub_metadata));
-
- TestEncodingMetadata();
-}
-
-TEST_F(MetadataEncoderTest, TestEncodingGeometryMetadata) {
- std::unique_ptr<draco::AttributeMetadata> att_metadata =
- std::unique_ptr<draco::AttributeMetadata>(new draco::AttributeMetadata);
- att_metadata->AddEntryInt("int", 100);
- att_metadata->AddEntryString("name", "pos");
- ASSERT_TRUE(geometry_metadata.AddAttributeMetadata(std::move(att_metadata)));
-
- TestEncodingGeometryMetadata();
-}
-} // namespace
diff --git a/extern/draco/dracoenc/src/draco/metadata/metadata_test.cc b/extern/draco/dracoenc/src/draco/metadata/metadata_test.cc
deleted file mode 100644
index ba6a764446c..00000000000
--- a/extern/draco/dracoenc/src/draco/metadata/metadata_test.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2017 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include <memory>
-#include <string>
-
-#include "draco/core/draco_test_base.h"
-#include "draco/metadata/geometry_metadata.h"
-#include "draco/metadata/metadata.h"
-
-namespace {
-
-class MetadataTest : public ::testing::Test {
- protected:
- MetadataTest() {}
-
- draco::Metadata metadata;
- draco::GeometryMetadata geometry_metadata;
-};
-
-TEST_F(MetadataTest, TestRemoveEntry) {
- metadata.AddEntryInt("int", 100);
- metadata.RemoveEntry("int");
- int32_t int_value = 0;
- ASSERT_FALSE(metadata.GetEntryInt("int", &int_value));
-}
-
-TEST_F(MetadataTest, TestSingleEntry) {
- metadata.AddEntryInt("int", 100);
- int32_t int_value = 0;
- ASSERT_TRUE(metadata.GetEntryInt("int", &int_value));
- ASSERT_EQ(int_value, 100);
-
- metadata.AddEntryDouble("double", 1.234);
- double double_value = 0.0;
- ASSERT_TRUE(metadata.GetEntryDouble("double", &double_value));
- ASSERT_EQ(double_value, 1.234);
-}
-
-TEST_F(MetadataTest, TestWriteOverEntry) {
- metadata.AddEntryInt("int", 100);
- metadata.AddEntryInt("int", 200);
- int32_t int_value = 0;
- ASSERT_TRUE(metadata.GetEntryInt("int", &int_value));
- ASSERT_EQ(int_value, 200);
-}
-
-TEST_F(MetadataTest, TestArrayEntry) {
- std::vector<int32_t> int_array({1, 2, 3});
- metadata.AddEntryIntArray("int_array", int_array);
- std::vector<int32_t> return_int_array;
- ASSERT_TRUE(metadata.GetEntryIntArray("int_array", &return_int_array));
- ASSERT_EQ(return_int_array.size(), 3);
- ASSERT_EQ(return_int_array[0], 1);
- ASSERT_EQ(return_int_array[1], 2);
- ASSERT_EQ(return_int_array[2], 3);
-
- std::vector<double> double_array({0.1, 0.2, 0.3});
- metadata.AddEntryDoubleArray("double_array", double_array);
- std::vector<double> return_double_array;
- ASSERT_TRUE(
- metadata.GetEntryDoubleArray("double_array", &return_double_array));
- ASSERT_EQ(return_double_array.size(), 3);
- ASSERT_EQ(return_double_array[0], 0.1);
- ASSERT_EQ(return_double_array[1], 0.2);
- ASSERT_EQ(return_double_array[2], 0.3);
-}
-
-TEST_F(MetadataTest, TestStringEntry) {
- const std::string entry_value = "test string entry";
- metadata.AddEntryString("string", entry_value);
- std::string return_value;
- ASSERT_TRUE(metadata.GetEntryString("string", &return_value));
- ASSERT_EQ(entry_value.size(), return_value.size());
- ASSERT_EQ(entry_value, return_value);
-}
-
-TEST_F(MetadataTest, TestBinaryEntry) {
- const std::vector<uint8_t> binarydata({0x1, 0x2, 0x3, 0x4});
- metadata.AddEntryBinary("binary_data", binarydata);
- std::vector<uint8_t> return_binarydata;
- ASSERT_TRUE(metadata.GetEntryBinary("binary_data", &return_binarydata));
- ASSERT_EQ(binarydata.size(), return_binarydata.size());
- for (int i = 0; i < binarydata.size(); ++i) {
- ASSERT_EQ(binarydata[i], return_binarydata[i]);
- }
-}
-
-TEST_F(MetadataTest, TestNestedMetadata) {
- std::unique_ptr<draco::Metadata> sub_metadata =
- std::unique_ptr<draco::Metadata>(new draco::Metadata());
- sub_metadata->AddEntryInt("int", 100);
-
- metadata.AddSubMetadata("sub0", std::move(sub_metadata));
- const auto sub_metadata_ptr = metadata.GetSubMetadata("sub0");
- ASSERT_NE(sub_metadata_ptr, nullptr);
-
- int32_t int_value = 0;
- ASSERT_TRUE(sub_metadata_ptr->GetEntryInt("int", &int_value));
- ASSERT_EQ(int_value, 100);
-}
-
-TEST_F(MetadataTest, TestHardCopyMetadata) {
- metadata.AddEntryInt("int", 100);
- std::unique_ptr<draco::Metadata> sub_metadata =
- std::unique_ptr<draco::Metadata>(new draco::Metadata());
- sub_metadata->AddEntryInt("int", 200);
- metadata.AddSubMetadata("sub0", std::move(sub_metadata));
-
- draco::Metadata copied_metadata(metadata);
-
- int32_t int_value = 0;
- ASSERT_TRUE(copied_metadata.GetEntryInt("int", &int_value));
- ASSERT_EQ(int_value, 100);
-
- const auto sub_metadata_ptr = copied_metadata.GetSubMetadata("sub0");
- ASSERT_NE(sub_metadata_ptr, nullptr);
-
- int32_t sub_int_value = 0;
- ASSERT_TRUE(sub_metadata_ptr->GetEntryInt("int", &sub_int_value));
- ASSERT_EQ(sub_int_value, 200);
-}
-
-TEST_F(MetadataTest, TestGeometryMetadata) {
- std::unique_ptr<draco::AttributeMetadata> att_metadata =
- std::unique_ptr<draco::AttributeMetadata>(new draco::AttributeMetadata());
- att_metadata->set_att_unique_id(10);
- att_metadata->AddEntryInt("int", 100);
- att_metadata->AddEntryString("name", "pos");
-
- ASSERT_FALSE(geometry_metadata.AddAttributeMetadata(nullptr));
- ASSERT_TRUE(geometry_metadata.AddAttributeMetadata(std::move(att_metadata)));
-
- ASSERT_NE(geometry_metadata.GetAttributeMetadataByUniqueId(10), nullptr);
- ASSERT_EQ(geometry_metadata.GetAttributeMetadataByUniqueId(1), nullptr);
-
- const draco::AttributeMetadata *requested_att_metadata =
- geometry_metadata.GetAttributeMetadataByStringEntry("name", "pos");
- ASSERT_NE(requested_att_metadata, nullptr);
- ASSERT_EQ(
- geometry_metadata.GetAttributeMetadataByStringEntry("name", "not_exists"),
- nullptr);
-}
-
-} // namespace
diff --git a/extern/draco/dracoenc/src/draco/point_cloud/point_cloud_builder_test.cc b/extern/draco/dracoenc/src/draco/point_cloud/point_cloud_builder_test.cc
deleted file mode 100644
index 3222a4c8da8..00000000000
--- a/extern/draco/dracoenc/src/draco/point_cloud/point_cloud_builder_test.cc
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/point_cloud/point_cloud_builder.h"
-
-#include "draco/core/draco_test_base.h"
-
-namespace draco {
-
-class PointCloudBuilderTest : public ::testing::Test {
- protected:
- // Test data.
- // clang-format off
- std::vector<float> pos_data_ = {10.f, 0.f, 1.f,
- 11.f, 1.f, 2.f,
- 12.f, 2.f, 8.f,
- 13.f, 4.f, 7.f,
- 14.f, 5.f, 6.f,
- 15.f, 6.f, 5.f,
- 16.f, 1.f, 3.f,
- 17.f, 1.f, 2.f,
- 11.f, 1.f, 2.f,
- 10.f, 0.f, 1.f};
- std::vector<int16_t> intensity_data_ = {100,
- 200,
- 500,
- 700,
- 400,
- 400,
- 400,
- 100,
- 100,
- 100};
- // clang-format on
-};
-
-TEST_F(PointCloudBuilderTest, IndividualTest_NoDedup) {
- // This test verifies that PointCloudBuilder can construct point cloud using
- // SetAttributeValueForPoint API without deduplication.
- PointCloudBuilder builder;
- builder.Start(10);
- const int pos_att_id =
- builder.AddAttribute(GeometryAttribute::POSITION, 3, DT_FLOAT32);
- const int intensity_att_id =
- builder.AddAttribute(GeometryAttribute::GENERIC, 1, DT_INT16);
- for (PointIndex i(0); i < 10; ++i) {
- builder.SetAttributeValueForPoint(pos_att_id, i,
- pos_data_.data() + 3 * i.value());
- builder.SetAttributeValueForPoint(intensity_att_id, i,
- intensity_data_.data() + i.value());
- }
- std::unique_ptr<PointCloud> res = builder.Finalize(false);
- ASSERT_TRUE(res != nullptr);
- ASSERT_EQ(res->num_points(), 10);
-}
-
-TEST_F(PointCloudBuilderTest, IndividualTest_Dedup) {
- // This test verifies that PointCloudBuilder can construct point cloud using
- // SetAttributeValueForPoint API with deduplication.
- PointCloudBuilder builder;
- builder.Start(10);
- const int pos_att_id =
- builder.AddAttribute(GeometryAttribute::POSITION, 3, DT_FLOAT32);
- const int intensity_att_id =
- builder.AddAttribute(GeometryAttribute::GENERIC, 1, DT_INT16);
- for (PointIndex i(0); i < 10; ++i) {
- builder.SetAttributeValueForPoint(pos_att_id, i,
- pos_data_.data() + 3 * i.value());
- builder.SetAttributeValueForPoint(intensity_att_id, i,
- intensity_data_.data() + i.value());
- }
- std::unique_ptr<PointCloud> res = builder.Finalize(true);
- ASSERT_TRUE(res != nullptr);
- ASSERT_EQ(res->num_points(), 9);
-}
-
-TEST_F(PointCloudBuilderTest, BatchTest) {
- // This test verifies that PointCloudBuilder can construct point cloud using
- // SetAttributeValuesForAllPoints API.
- PointCloudBuilder builder;
- builder.Start(10);
- const int pos_att_id =
- builder.AddAttribute(GeometryAttribute::POSITION, 3, DT_FLOAT32);
- const int intensity_att_id =
- builder.AddAttribute(GeometryAttribute::GENERIC, 1, DT_INT16);
- builder.SetAttributeValuesForAllPoints(pos_att_id, pos_data_.data(), 0);
- builder.SetAttributeValuesForAllPoints(intensity_att_id,
- intensity_data_.data(), 0);
- std::unique_ptr<PointCloud> res = builder.Finalize(false);
- ASSERT_TRUE(res != nullptr);
- ASSERT_EQ(res->num_points(), 10);
- for (PointIndex i(0); i < 10; ++i) {
- float pos_val[3];
- res->attribute(pos_att_id)->GetMappedValue(i, pos_val);
- for (int c = 0; c < 3; ++c) {
- ASSERT_EQ(pos_val[c], pos_data_[3 * i.value() + c]);
- }
- int16_t int_val;
- res->attribute(intensity_att_id)->GetMappedValue(i, &int_val);
- ASSERT_EQ(intensity_data_[i.value()], int_val);
- }
-}
-
-TEST_F(PointCloudBuilderTest, MultiUse) {
- // This test verifies that PointCloudBuilder can be used multiple times
- PointCloudBuilder builder;
- {
- builder.Start(10);
- const int pos_att_id =
- builder.AddAttribute(GeometryAttribute::POSITION, 3, DT_FLOAT32);
- const int intensity_att_id =
- builder.AddAttribute(GeometryAttribute::GENERIC, 1, DT_INT16);
- builder.SetAttributeValuesForAllPoints(pos_att_id, pos_data_.data(), 0);
- builder.SetAttributeValuesForAllPoints(intensity_att_id,
- intensity_data_.data(), 0);
- std::unique_ptr<PointCloud> res = builder.Finalize(false);
- ASSERT_TRUE(res != nullptr);
- ASSERT_EQ(res->num_points(), 10);
- for (PointIndex i(0); i < 10; ++i) {
- float pos_val[3];
- res->attribute(pos_att_id)->GetMappedValue(i, pos_val);
- for (int c = 0; c < 3; ++c) {
- ASSERT_EQ(pos_val[c], pos_data_[3 * i.value() + c]);
- }
- int16_t int_val;
- res->attribute(intensity_att_id)->GetMappedValue(i, &int_val);
- ASSERT_EQ(intensity_data_[i.value()], int_val);
- }
- }
-
- {
- // Use only a sub-set of data (offsetted to avoid possible reuse of old
- // data).
- builder.Start(4);
- const int pos_att_id =
- builder.AddAttribute(GeometryAttribute::POSITION, 3, DT_FLOAT32);
- const int intensity_att_id =
- builder.AddAttribute(GeometryAttribute::GENERIC, 1, DT_INT16);
- constexpr int offset = 5;
- builder.SetAttributeValuesForAllPoints(pos_att_id,
- pos_data_.data() + 3 * offset, 0);
- builder.SetAttributeValuesForAllPoints(intensity_att_id,
- intensity_data_.data() + offset, 0);
- std::unique_ptr<PointCloud> res = builder.Finalize(false);
- ASSERT_TRUE(res != nullptr);
- ASSERT_EQ(res->num_points(), 4);
- for (PointIndex i(0); i < 4; ++i) {
- float pos_val[3];
- res->attribute(pos_att_id)->GetMappedValue(i, pos_val);
- for (int c = 0; c < 3; ++c) {
- ASSERT_EQ(pos_val[c], pos_data_[3 * (i.value() + offset) + c]);
- }
- int16_t int_val;
- res->attribute(intensity_att_id)->GetMappedValue(i, &int_val);
- ASSERT_EQ(intensity_data_[i.value() + offset], int_val);
- }
- }
-}
-
-} // namespace draco
diff --git a/extern/draco/dracoenc/src/draco/point_cloud/point_cloud_test.cc b/extern/draco/dracoenc/src/draco/point_cloud/point_cloud_test.cc
deleted file mode 100644
index 00491b7309a..00000000000
--- a/extern/draco/dracoenc/src/draco/point_cloud/point_cloud_test.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2017 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "draco/core/draco_test_base.h"
-#include "draco/core/draco_test_utils.h"
-
-#include "draco/point_cloud/point_cloud.h"
-
-namespace {
-
-class PointCloudTest : public ::testing::Test {
- protected:
- PointCloudTest() {}
-};
-
-TEST_F(PointCloudTest, TestAttributeDeletion) {
- draco::PointCloud pc;
- // Test whether we can correctly delete an attribute from a point cloud.
- // Create some attributes for the point cloud.
- draco::GeometryAttribute pos_att;
- pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 3,
- draco::DT_FLOAT32, false, 12, 0);
- draco::GeometryAttribute norm_att;
- norm_att.Init(draco::GeometryAttribute::NORMAL, nullptr, 3, draco::DT_FLOAT32,
- false, 12, 0);
- draco::GeometryAttribute gen_att;
- gen_att.Init(draco::GeometryAttribute::GENERIC, nullptr, 3, draco::DT_FLOAT32,
- false, 12, 0);
-
- // Add one position, two normal and two generic attributes.
- pc.AddAttribute(pos_att, false, 0);
- pc.AddAttribute(gen_att, false, 0);
- pc.AddAttribute(norm_att, false, 0);
- pc.AddAttribute(gen_att, false, 0);
- pc.AddAttribute(norm_att, false, 0);
-
- ASSERT_EQ(pc.num_attributes(), 5);
- ASSERT_EQ(pc.attribute(0)->attribute_type(),
- draco::GeometryAttribute::POSITION);
- ASSERT_EQ(pc.attribute(3)->attribute_type(),
- draco::GeometryAttribute::GENERIC);
-
- // Delete generic attribute.
- pc.DeleteAttribute(1);
- ASSERT_EQ(pc.num_attributes(), 4);
- ASSERT_EQ(pc.attribute(1)->attribute_type(),
- draco::GeometryAttribute::NORMAL);
- ASSERT_EQ(pc.NumNamedAttributes(draco::GeometryAttribute::NORMAL), 2);
- ASSERT_EQ(pc.GetNamedAttributeId(draco::GeometryAttribute::NORMAL, 1), 3);
-
- // Delete the first normal attribute.
- pc.DeleteAttribute(1);
- ASSERT_EQ(pc.num_attributes(), 3);
- ASSERT_EQ(pc.attribute(1)->attribute_type(),
- draco::GeometryAttribute::GENERIC);
- ASSERT_EQ(pc.NumNamedAttributes(draco::GeometryAttribute::NORMAL), 1);
- ASSERT_EQ(pc.GetNamedAttributeId(draco::GeometryAttribute::NORMAL, 0), 2);
-}
-
-TEST_F(PointCloudTest, TestPointCloudWithMetadata) {
- draco::PointCloud pc;
- std::unique_ptr<draco::GeometryMetadata> metadata =
- std::unique_ptr<draco::GeometryMetadata>(new draco::GeometryMetadata());
-
- // Add a position attribute metadata.
- draco::GeometryAttribute pos_att;
- pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 3,
- draco::DT_FLOAT32, false, 12, 0);
- const uint32_t pos_att_id = pc.AddAttribute(pos_att, false, 0);
- ASSERT_EQ(pos_att_id, 0);
- std::unique_ptr<draco::AttributeMetadata> pos_metadata =
- std::unique_ptr<draco::AttributeMetadata>(new draco::AttributeMetadata());
- pos_metadata->AddEntryString("name", "position");
- pc.AddAttributeMetadata(pos_att_id, std::move(pos_metadata));
- const draco::GeometryMetadata *pc_metadata = pc.GetMetadata();
- ASSERT_NE(pc_metadata, nullptr);
- // Add a generic material attribute metadata.
- draco::GeometryAttribute material_att;
- material_att.Init(draco::GeometryAttribute::GENERIC, nullptr, 3,
- draco::DT_FLOAT32, false, 12, 0);
- const uint32_t material_att_id = pc.AddAttribute(material_att, false, 0);
- ASSERT_EQ(material_att_id, 1);
- std::unique_ptr<draco::AttributeMetadata> material_metadata =
- std::unique_ptr<draco::AttributeMetadata>(new draco::AttributeMetadata());
- material_metadata->AddEntryString("name", "material");
- // The material attribute has id of 1 now.
- pc.AddAttributeMetadata(material_att_id, std::move(material_metadata));
-
- // Test if the attribute metadata is correctly added.
- const draco::AttributeMetadata *requested_pos_metadata =
- pc.GetAttributeMetadataByStringEntry("name", "position");
- ASSERT_NE(requested_pos_metadata, nullptr);
- const draco::AttributeMetadata *requested_mat_metadata =
- pc.GetAttributeMetadataByStringEntry("name", "material");
- ASSERT_NE(requested_mat_metadata, nullptr);
-
- // Attribute id should be preserved.
- ASSERT_EQ(
- pc.GetAttributeIdByUniqueId(requested_pos_metadata->att_unique_id()), 0);
- ASSERT_EQ(
- pc.GetAttributeIdByUniqueId(requested_mat_metadata->att_unique_id()), 1);
-
- // Test deleting attribute with metadata.
- pc.DeleteAttribute(pos_att_id);
- ASSERT_EQ(pc.GetAttributeMetadataByStringEntry("name", "position"), nullptr);
-
- requested_mat_metadata =
- pc.GetAttributeMetadataByStringEntry("name", "material");
- // The unique id should not be changed.
- ASSERT_EQ(requested_mat_metadata->att_unique_id(), 1);
- // Now position attribute is removed, material attribute should have the
- // attribute id of 0.
- ASSERT_EQ(
- pc.GetAttributeIdByUniqueId(requested_mat_metadata->att_unique_id()), 0);
- // Should be able to get metadata using the current attribute id.
- // Attribute id of material attribute is changed from 1 to 0.
- ASSERT_NE(pc.GetAttributeMetadataByAttributeId(0), nullptr);
-}
-
-} // namespace
diff --git a/extern/draco/dracoenc/src/draco/tools/draco_decoder.cc b/extern/draco/dracoenc/src/draco/tools/draco_decoder.cc
deleted file mode 100644
index 5b06e8caa3b..00000000000
--- a/extern/draco/dracoenc/src/draco/tools/draco_decoder.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include <cinttypes>
-#include <fstream>
-
-#include "draco/compression/decode.h"
-#include "draco/core/cycle_timer.h"
-#include "draco/io/obj_encoder.h"
-#include "draco/io/parser_utils.h"
-#include "draco/io/ply_encoder.h"
-
-namespace {
-
-struct Options {
- Options();
-
- std::string input;
- std::string output;
-};
-
-Options::Options() {}
-
-void Usage() {
- printf("Usage: draco_decoder [options] -i input\n");
- printf("\n");
- printf("Main options:\n");
- printf(" -h | -? show help.\n");
- printf(" -o <output> output file name.\n");
-}
-
-int ReturnError(const draco::Status &status) {
- printf("Failed to decode the input file %s\n", status.error_msg());
- return -1;
-}
-
-} // namespace
-
-int main(int argc, char **argv) {
- Options options;
- const int argc_check = argc - 1;
-
- for (int i = 1; i < argc; ++i) {
- if (!strcmp("-h", argv[i]) || !strcmp("-?", argv[i])) {
- Usage();
- return 0;
- } else if (!strcmp("-i", argv[i]) && i < argc_check) {
- options.input = argv[++i];
- } else if (!strcmp("-o", argv[i]) && i < argc_check) {
- options.output = argv[++i];
- }
- }
- if (argc < 3 || options.input.empty()) {
- Usage();
- return -1;
- }
-
- std::ifstream input_file(options.input, std::ios::binary);
- if (!input_file) {
- printf("Failed opening the input file.\n");
- return -1;
- }
-
- // Read the file stream into a buffer.
- std::streampos file_size = 0;
- input_file.seekg(0, std::ios::end);
- file_size = input_file.tellg() - file_size;
- input_file.seekg(0, std::ios::beg);
- std::vector<char> data(file_size);
- input_file.read(data.data(), file_size);
-
- if (data.empty()) {
- printf("Empty input file.\n");
- return -1;
- }
-
- // Create a draco decoding buffer. Note that no data is copied in this step.
- draco::DecoderBuffer buffer;
- buffer.Init(data.data(), data.size());
-
- draco::CycleTimer timer;
- // Decode the input data into a geometry.
- std::unique_ptr<draco::PointCloud> pc;
- draco::Mesh *mesh = nullptr;
- auto type_statusor = draco::Decoder::GetEncodedGeometryType(&buffer);
- if (!type_statusor.ok()) {
- return ReturnError(type_statusor.status());
- }
- const draco::EncodedGeometryType geom_type = type_statusor.value();
- if (geom_type == draco::TRIANGULAR_MESH) {
- timer.Start();
- draco::Decoder decoder;
- auto statusor = decoder.DecodeMeshFromBuffer(&buffer);
- if (!statusor.ok()) {
- return ReturnError(statusor.status());
- }
- std::unique_ptr<draco::Mesh> in_mesh = std::move(statusor).value();
- timer.Stop();
- if (in_mesh) {
- mesh = in_mesh.get();
- pc = std::move(in_mesh);
- }
- } else if (geom_type == draco::POINT_CLOUD) {
- // Failed to decode it as mesh, so let's try to decode it as a point cloud.
- timer.Start();
- draco::Decoder decoder;
- auto statusor = decoder.DecodePointCloudFromBuffer(&buffer);
- if (!statusor.ok()) {
- return ReturnError(statusor.status());
- }
- pc = std::move(statusor).value();
- timer.Stop();
- }
-
- if (pc == nullptr) {
- printf("Failed to decode the input file.\n");
- return -1;
- }
-
- if (options.output.empty()) {
- // Save the output model into a ply file.
- options.output = options.input + ".ply";
- }
-
- // Save the decoded geometry into a file.
- // TODO(fgalligan): Change extension code to look for '.'.
- const std::string extension = draco::parser::ToLower(
- options.output.size() >= 4
- ? options.output.substr(options.output.size() - 4)
- : options.output);
-
- if (extension == ".obj") {
- draco::ObjEncoder obj_encoder;
- if (mesh) {
- if (!obj_encoder.EncodeToFile(*mesh, options.output)) {
- printf("Failed to store the decoded mesh as OBJ.\n");
- return -1;
- }
- } else {
- if (!obj_encoder.EncodeToFile(*pc.get(), options.output)) {
- printf("Failed to store the decoded point cloud as OBJ.\n");
- return -1;
- }
- }
- } else if (extension == ".ply") {
- draco::PlyEncoder ply_encoder;
- if (mesh) {
- if (!ply_encoder.EncodeToFile(*mesh, options.output)) {
- printf("Failed to store the decoded mesh as PLY.\n");
- return -1;
- }
- } else {
- if (!ply_encoder.EncodeToFile(*pc.get(), options.output)) {
- printf("Failed to store the decoded point cloud as PLY.\n");
- return -1;
- }
- }
- } else {
- printf(
- "Invalid extension of the output file. Use either .ply, .obj, or "
- ".gltf\n");
- return -1;
- }
- printf("Decoded geometry saved to %s (%" PRId64 " ms to decode)\n",
- options.output.c_str(), timer.GetInMs());
- return 0;
-}
diff --git a/extern/draco/dracoenc/src/draco/tools/draco_encoder.cc b/extern/draco/dracoenc/src/draco/tools/draco_encoder.cc
deleted file mode 100644
index e44d0939048..00000000000
--- a/extern/draco/dracoenc/src/draco/tools/draco_encoder.cc
+++ /dev/null
@@ -1,373 +0,0 @@
-// Copyright 2016 The Draco Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include <cinttypes>
-#include <cstdlib>
-#include <fstream>
-
-#include "draco/compression/encode.h"
-#include "draco/core/cycle_timer.h"
-#include "draco/io/mesh_io.h"
-#include "draco/io/point_cloud_io.h"
-
-namespace {
-
-struct Options {
- Options();
-
- bool is_point_cloud;
- int pos_quantization_bits;
- int tex_coords_quantization_bits;
- bool tex_coords_deleted;
- int normals_quantization_bits;
- bool normals_deleted;
- int generic_quantization_bits;
- bool generic_deleted;
- int compression_level;
- bool use_metadata;
- std::string input;
- std::string output;
-};
-
-Options::Options()
- : is_point_cloud(false),
- pos_quantization_bits(14),
- tex_coords_quantization_bits(12),
- tex_coords_deleted(false),
- normals_quantization_bits(10),
- normals_deleted(false),
- generic_quantization_bits(8),
- generic_deleted(false),
- compression_level(7),
- use_metadata(false) {}
-
-void Usage() {
- printf("Usage: draco_encoder [options] -i input\n");
- printf("\n");
- printf("Main options:\n");
- printf(" -h | -? show help.\n");
- printf(" -i <input> input file name.\n");
- printf(" -o <output> output file name.\n");
- printf(
- " -point_cloud forces the input to be encoded as a point "
- "cloud.\n");
- printf(
- " -qp <value> quantization bits for the position "
- "attribute, default=14.\n");
- printf(
- " -qt <value> quantization bits for the texture coordinate "
- "attribute, default=12.\n");
- printf(
- " -qn <value> quantization bits for the normal vector "
- "attribute, default=10.\n");
- printf(
- " -qg <value> quantization bits for any generic attribute, "
- "default=8.\n");
- printf(
- " -cl <value> compression level [0-10], most=10, least=0, "
- "default=7.\n");
- printf(
- " --skip ATTRIBUTE_NAME skip a given attribute (NORMAL, TEX_COORD, "
- "GENERIC)\n");
- printf(
- " --metadata use metadata to encode extra information in "
- "mesh files.\n");
- printf(
- "\nUse negative quantization values to skip the specified attribute\n");
-}
-
-int StringToInt(const std::string &s) {
- char *end;
- return strtol(s.c_str(), &end, 10); // NOLINT
-}
-
-void PrintOptions(const draco::PointCloud &pc, const Options &options) {
- printf("Encoder options:\n");
- printf(" Compression level = %d\n", options.compression_level);
- if (options.pos_quantization_bits == 0) {
- printf(" Positions: No quantization\n");
- } else {
- printf(" Positions: Quantization = %d bits\n",
- options.pos_quantization_bits);
- }
-
- if (pc.GetNamedAttributeId(draco::GeometryAttribute::TEX_COORD) >= 0) {
- if (options.tex_coords_quantization_bits == 0) {
- printf(" Texture coordinates: No quantization\n");
- } else {
- printf(" Texture coordinates: Quantization = %d bits\n",
- options.tex_coords_quantization_bits);
- }
- } else if (options.tex_coords_deleted) {
- printf(" Texture coordinates: Skipped\n");
- }
-
- if (pc.GetNamedAttributeId(draco::GeometryAttribute::NORMAL) >= 0) {
- if (options.normals_quantization_bits == 0) {
- printf(" Normals: No quantization\n");
- } else {
- printf(" Normals: Quantization = %d bits\n",
- options.normals_quantization_bits);
- }
- } else if (options.normals_deleted) {
- printf(" Normals: Skipped\n");
- }
-
- if (pc.GetNamedAttributeId(draco::GeometryAttribute::GENERIC) >= 0) {
- if (options.generic_quantization_bits == 0) {
- printf(" Generic: No quantization\n");
- } else {
- printf(" Generic: Quantization = %d bits\n",
- options.generic_quantization_bits);
- }
- } else if (options.generic_deleted) {
- printf(" Generic: Skipped\n");
- }
- printf("\n");
-}
-
-int EncodePointCloudToFile(const draco::PointCloud &pc, const std::string &file,
- draco::Encoder *encoder) {
- draco::CycleTimer timer;
- // Encode the geometry.
- draco::EncoderBuffer buffer;
- timer.Start();
- const draco::Status status = encoder->EncodePointCloudToBuffer(pc, &buffer);
- if (!status.ok()) {
- printf("Failed to encode the point cloud.\n");
- printf("%s\n", status.error_msg());
- return -1;
- }
- timer.Stop();
- // Save the encoded geometry into a file.
- std::ofstream out_file(file, std::ios::binary);
- if (!out_file) {
- printf("Failed to create the output file.\n");
- return -1;
- }
- out_file.write(buffer.data(), buffer.size());
- printf("Encoded point cloud saved to %s (%" PRId64 " ms to encode).\n",
- file.c_str(), timer.GetInMs());
- printf("\nEncoded size = %zu bytes\n\n", buffer.size());
- return 0;
-}
-
-int EncodeMeshToFile(const draco::Mesh &mesh, const std::string &file,
- draco::Encoder *encoder) {
- draco::CycleTimer timer;
- // Encode the geometry.
- draco::EncoderBuffer buffer;
- timer.Start();
- const draco::Status status = encoder->EncodeMeshToBuffer(mesh, &buffer);
- if (!status.ok()) {
- printf("Failed to encode the mesh.\n");
- printf("%s\n", status.error_msg());
- return -1;
- }
- timer.Stop();
- // Save the encoded geometry into a file.
- std::ofstream out_file(file, std::ios::binary);
- if (!out_file) {
- printf("Failed to create the output file.\n");
- return -1;
- }
- out_file.write(buffer.data(), buffer.size());
- printf("Encoded mesh saved to %s (%" PRId64 " ms to encode).\n", file.c_str(),
- timer.GetInMs());
- printf("\nEncoded size = %zu bytes\n\n", buffer.size());
- return 0;
-}
-
-} // anonymous namespace
-
-int main(int argc, char **argv) {
- Options options;
- const int argc_check = argc - 1;
-
- for (int i = 1; i < argc; ++i) {
- if (!strcmp("-h", argv[i]) || !strcmp("-?", argv[i])) {
- Usage();
- return 0;
- } else if (!strcmp("-i", argv[i]) && i < argc_check) {
- options.input = argv[++i];
- } else if (!strcmp("-o", argv[i]) && i < argc_check) {
- options.output = argv[++i];
- } else if (!strcmp("-point_cloud", argv[i])) {
- options.is_point_cloud = true;
- } else if (!strcmp("-qp", argv[i]) && i < argc_check) {
- options.pos_quantization_bits = StringToInt(argv[++i]);
- if (options.pos_quantization_bits > 30) {
- printf(
- "Error: The maximum number of quantization bits for the position "
- "attribute is 30.\n");
- return -1;
- }
- } else if (!strcmp("-qt", argv[i]) && i < argc_check) {
- options.tex_coords_quantization_bits = StringToInt(argv[++i]);
- if (options.tex_coords_quantization_bits > 30) {
- printf(
- "Error: The maximum number of quantization bits for the texture "
- "coordinate attribute is 30.\n");
- return -1;
- }
- } else if (!strcmp("-qn", argv[i]) && i < argc_check) {
- options.normals_quantization_bits = StringToInt(argv[++i]);
- if (options.normals_quantization_bits > 30) {
- printf(
- "Error: The maximum number of quantization bits for the normal "
- "attribute is 30.\n");
- return -1;
- }
- } else if (!strcmp("-qg", argv[i]) && i < argc_check) {
- options.generic_quantization_bits = StringToInt(argv[++i]);
- if (options.generic_quantization_bits > 30) {
- printf(
- "Error: The maximum number of quantization bits for generic "
- "attributes is 30.\n");
- return -1;
- }
- } else if (!strcmp("-cl", argv[i]) && i < argc_check) {
- options.compression_level = StringToInt(argv[++i]);
- } else if (!strcmp("--skip", argv[i]) && i < argc_check) {
- if (!strcmp("NORMAL", argv[i + 1])) {
- options.normals_quantization_bits = -1;
- } else if (!strcmp("TEX_COORD", argv[i + 1])) {
- options.tex_coords_quantization_bits = -1;
- } else if (!strcmp("GENERIC", argv[i + 1])) {
- options.generic_quantization_bits = -1;
- } else {
- printf("Error: Invalid attribute name after --skip\n");
- return -1;
- }
- ++i;
- } else if (!strcmp("--metadata", argv[i])) {
- options.use_metadata = true;
- }
- }
- if (argc < 3 || options.input.empty()) {
- Usage();
- return -1;
- }
-
- std::unique_ptr<draco::PointCloud> pc;
- draco::Mesh *mesh = nullptr;
- if (!options.is_point_cloud) {
- auto maybe_mesh =
- draco::ReadMeshFromFile(options.input, options.use_metadata);
- if (!maybe_mesh.ok()) {
- printf("Failed loading the input mesh: %s.\n",
- maybe_mesh.status().error_msg());
- return -1;
- }
- mesh = maybe_mesh.value().get();
- pc = std::move(maybe_mesh).value();
- } else {
- auto maybe_pc = draco::ReadPointCloudFromFile(options.input);
- if (!maybe_pc.ok()) {
- printf("Failed loading the input point cloud: %s.\n",
- maybe_pc.status().error_msg());
- return -1;
- }
- pc = std::move(maybe_pc).value();
- }
-
- if (options.pos_quantization_bits < 0) {
- printf("Error: Position attribute cannot be skipped.\n");
- return -1;
- }
-
- // Delete attributes if needed. This needs to happen before we set any
- // quantization settings.
- if (options.tex_coords_quantization_bits < 0) {
- if (pc->NumNamedAttributes(draco::GeometryAttribute::TEX_COORD) > 0) {
- options.tex_coords_deleted = true;
- }
- while (pc->NumNamedAttributes(draco::GeometryAttribute::TEX_COORD) > 0) {
- pc->DeleteAttribute(
- pc->GetNamedAttributeId(draco::GeometryAttribute::TEX_COORD, 0));
- }
- }
- if (options.normals_quantization_bits < 0) {
- if (pc->NumNamedAttributes(draco::GeometryAttribute::NORMAL) > 0) {
- options.normals_deleted = true;
- }
- while (pc->NumNamedAttributes(draco::GeometryAttribute::NORMAL) > 0) {
- pc->DeleteAttribute(
- pc->GetNamedAttributeId(draco::GeometryAttribute::NORMAL, 0));
- }
- }
- if (options.generic_quantization_bits < 0) {
- if (pc->NumNamedAttributes(draco::GeometryAttribute::GENERIC) > 0) {
- options.generic_deleted = true;
- }
- while (pc->NumNamedAttributes(draco::GeometryAttribute::GENERIC) > 0) {
- pc->DeleteAttribute(
- pc->GetNamedAttributeId(draco::GeometryAttribute::GENERIC, 0));
- }
- }
-#ifdef DRACO_ATTRIBUTE_INDICES_DEDUPLICATION_SUPPORTED
- // If any attribute has been deleted, run deduplication of point indices again
- // as some points can be possibly combined.
- if (options.tex_coords_deleted || options.normals_deleted ||
- options.generic_deleted) {
- pc->DeduplicatePointIds();
- }
-#endif
-
- // Convert compression level to speed (that 0 = slowest, 10 = fastest).
- const int speed = 10 - options.compression_level;
-
- draco::Encoder encoder;
-
- // Setup encoder options.
- if (options.pos_quantization_bits > 0) {
- encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION,
- options.pos_quantization_bits);
- }
- if (options.tex_coords_quantization_bits > 0) {
- encoder.SetAttributeQuantization(draco::GeometryAttribute::TEX_COORD,
- options.tex_coords_quantization_bits);
- }
- if (options.normals_quantization_bits > 0) {
- encoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL,
- options.normals_quantization_bits);
- }
- if (options.generic_quantization_bits > 0) {
- encoder.SetAttributeQuantization(draco::GeometryAttribute::GENERIC,
- options.generic_quantization_bits);
- }
- encoder.SetSpeedOptions(speed, speed);
-
- if (options.output.empty()) {
- // Create a default output file by attaching .drc to the input file name.
- options.output = options.input + ".drc";
- }
-
- PrintOptions(*pc.get(), options);
-
- int ret = -1;
- const bool input_is_mesh = mesh && mesh->num_faces() > 0;
- if (input_is_mesh)
- ret = EncodeMeshToFile(*mesh, options.output, &encoder);
- else
- ret = EncodePointCloudToFile(*pc.get(), options.output, &encoder);
-
- if (ret != -1 && options.compression_level < 10) {
- printf(
- "For better compression, increase the compression level up to '-cl 10' "
- ".\n\n");
- }
-
- return ret;
-}
diff --git a/extern/draco/src/common.cpp b/extern/draco/src/common.cpp
new file mode 100644
index 00000000000..6f98d8db7ef
--- /dev/null
+++ b/extern/draco/src/common.cpp
@@ -0,0 +1,77 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "common.h"
+
+#include <cstring>
+
+size_t getNumberOfComponents(char *dataType)
+{
+ if (!strcmp(dataType, "SCALAR"))
+ {
+ return 1;
+ }
+ if (!strcmp(dataType, "VEC2"))
+ {
+ return 2;
+ }
+ if (!strcmp(dataType, "VEC3"))
+ {
+ return 3;
+ }
+ if (!strcmp(dataType, "VEC4"))
+ {
+ return 4;
+ }
+ if (!strcmp(dataType, "MAT2"))
+ {
+ return 4;
+ }
+ if (!strcmp(dataType, "MAT3"))
+ {
+ return 9;
+ }
+ if (!strcmp(dataType, "MAT4"))
+ {
+ return 16;
+ }
+
+ return 0;
+}
+
+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;
+ }
+}
+
+size_t getAttributeStride(size_t componentType, char *dataType)
+{
+ return getComponentByteLength(componentType) * getNumberOfComponents(dataType);
+}
diff --git a/extern/draco/src/common.h b/extern/draco/src/common.h
new file mode 100644
index 00000000000..beaf7d91adb
--- /dev/null
+++ b/extern/draco/src/common.h
@@ -0,0 +1,50 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Library for the Draco encoding/decoding feature inside the glTF-Blender-IO project.
+ *
+ * The python script within glTF-Blender-IO uses the CTypes library to open the DLL,
+ * load function pointers add pass the raw data to the encoder.
+ *
+ * @author Jim Eckerlein <eckerlein@ux3d.io>
+ * @date 2020-11-18
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <cstddef>
+
+#if defined(_MSC_VER)
+#define API(returnType) extern "C" __declspec(dllexport) returnType __cdecl
+#else
+#define API(returnType) extern "C" returnType
+#endif
+
+enum ComponentType: size_t
+{
+ Byte = 5120,
+ UnsignedByte = 5121,
+ Short = 5122,
+ UnsignedShort = 5123,
+ UnsignedInt = 5125,
+ Float = 5126,
+};
+
+size_t getNumberOfComponents(char *dataType);
+
+size_t getComponentByteLength(size_t componentType);
+
+size_t getAttributeStride(size_t componentType, char *dataType);
diff --git a/extern/draco/src/decoder.cpp b/extern/draco/src/decoder.cpp
new file mode 100644
index 00000000000..3f3e03bd9f2
--- /dev/null
+++ b/extern/draco/src/decoder.cpp
@@ -0,0 +1,222 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jim Eckerlein <eckerlein@ux3d.io>
+ * @date 2020-11-18
+ */
+
+
+#include "decoder.h"
+
+#include <memory>
+#include <vector>
+#include <cinttypes>
+
+#include "draco/mesh/mesh.h"
+#include "draco/core/decoder_buffer.h"
+#include "draco/compression/decode.h"
+
+#define LOG_PREFIX "DracoDecoder | "
+
+struct Decoder {
+ std::unique_ptr<draco::Mesh> mesh;
+ std::vector<uint8_t> indexBuffer;
+ std::map<uint32_t, std::vector<uint8_t>> buffers;
+ draco::DecoderBuffer decoderBuffer;
+ uint32_t vertexCount;
+ uint32_t indexCount;
+};
+
+Decoder *decoderCreate()
+{
+ return new Decoder;
+}
+
+void decoderRelease(Decoder *decoder)
+{
+ delete decoder;
+}
+
+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;
+}
+
+uint32_t decoderGetVertexCount(Decoder *decoder)
+{
+ return decoder->vertexCount;
+}
+
+uint32_t decoderGetIndexCount(Decoder *decoder)
+{
+ return decoder->indexCount;
+}
+
+bool decoderAttributeIsNormalized(Decoder *decoder, uint32_t 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);
+
+ 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:
+ converted = attribute->ConvertValue(index, reinterpret_cast<int8_t *>(value));
+ break;
+ case ComponentType::UnsignedByte:
+ converted = attribute->ConvertValue(index, reinterpret_cast<uint8_t *>(value));
+ break;
+ case ComponentType::Short:
+ converted = attribute->ConvertValue(index, reinterpret_cast<int16_t *>(value));
+ break;
+ case ComponentType::UnsignedShort:
+ converted = attribute->ConvertValue(index, reinterpret_cast<uint16_t *>(value));
+ break;
+ case ComponentType::UnsignedInt:
+ converted = attribute->ConvertValue(index, reinterpret_cast<uint32_t *>(value));
+ break;
+ case ComponentType::Float:
+ converted = attribute->ConvertValue(index, reinterpret_cast<float *>(value));
+ break;
+ default:
+ break;
+ }
+
+ if (!converted)
+ {
+ printf(LOG_PREFIX "Failed to convert Draco attribute type to glTF accessor type for attribute with id=%" PRIu32 "\n", id);
+ return false;
+ }
+ }
+
+ decoder->buffers[id] = decodedData;
+ return true;
+}
+
+size_t decoderGetAttributeByteLength(Decoder *decoder, size_t id)
+{
+ auto iter = decoder->buffers.find(id);
+ if (iter != decoder->buffers.end())
+ {
+ return iter->second.size();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void decoderCopyAttribute(Decoder *decoder, size_t id, void *output)
+{
+ auto iter = decoder->buffers.find(id);
+ if (iter != decoder->buffers.end())
+ {
+ memcpy(output, iter->second.data(), iter->second.size());
+ }
+}
+
+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));
+ typedView[faceIndex * 3 + 0] = face[0].value();
+ typedView[faceIndex * 3 + 1] = face[1].value();
+ typedView[faceIndex * 3 + 2] = face[2].value();
+ }
+
+ decoder->indexBuffer = decodedIndices;
+}
+
+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;
+ }
+
+ return true;
+}
+
+size_t decoderGetIndicesByteLength(Decoder *decoder)
+{
+ return decoder->indexBuffer.size();
+}
+
+void decoderCopyIndices(Decoder *decoder, void *output)
+{
+ memcpy(output, decoder->indexBuffer.data(), decoder->indexBuffer.size());
+}
diff --git a/extern/draco/src/decoder.h b/extern/draco/src/decoder.h
new file mode 100644
index 00000000000..914eb776e8f
--- /dev/null
+++ b/extern/draco/src/decoder.h
@@ -0,0 +1,53 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Library for the Draco encoding/decoding feature inside the glTF-Blender-IO project.
+ *
+ * The python script within glTF-Blender-IO uses the CTypes library to open the DLL,
+ * load function pointers add pass the raw data to the encoder.
+ *
+ * @author Jim Eckerlein <eckerlein@ux3d.io>
+ * @date 2020-11-18
+ */
+
+#pragma once
+
+#include "common.h"
+
+struct Decoder;
+
+API(Decoder *) decoderCreate();
+
+API(void) decoderRelease(Decoder *decoder);
+
+API(bool) decoderDecode(Decoder *decoder, void *data, size_t byteLength);
+
+API(uint32_t) decoderGetVertexCount(Decoder *decoder);
+
+API(uint32_t) decoderGetIndexCount(Decoder *decoder);
+
+API(bool) decoderAttributeIsNormalized(Decoder *decoder, uint32_t id);
+
+API(bool) decoderReadAttribute(Decoder *decoder, uint32_t id, size_t componentType, char *dataType);
+
+API(size_t) decoderGetAttributeByteLength(Decoder *decoder, size_t id);
+
+API(void) decoderCopyAttribute(Decoder *decoder, size_t id, void *output);
+
+API(bool) decoderReadIndices(Decoder *decoder, size_t indexComponentType);
+
+API(size_t) decoderGetIndicesByteLength(Decoder *decoder);
+
+API(void) decoderCopyIndices(Decoder *decoder, void *output);
diff --git a/extern/draco/src/draco-compressor.cpp b/extern/draco/src/draco-compressor.cpp
deleted file mode 100644
index 4ae528888fe..00000000000
--- a/extern/draco/src/draco-compressor.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @author Jim Eckerlein <eckerlein@ux3d.io>
- * @date 2019-11-29
- */
-
-#include "draco-compressor.h"
-
-#include <memory>
-#include <vector>
-
-#include "draco/mesh/mesh.h"
-#include "draco/core/encoder_buffer.h"
-#include "draco/compression/encode.h"
-
-/**
- * Prefix used for logging messages.
- */
-const char *logTag = "DRACO-COMPRESSOR";
-
-struct DracoCompressor {
- draco::Mesh mesh;
-
- // One data buffer per attribute.
- std::vector<std::unique_ptr<draco::DataBuffer>> buffers;
-
- // The buffer the mesh is compressed into.
- draco::EncoderBuffer encoderBuffer;
-
- // Level of compression [0-10].
- // Higher values mean slower encoding.
- uint32_t compressionLevel = 7;
-
- struct {
- uint32_t positions = 14;
- uint32_t normals = 10;
- uint32_t uvs = 12;
- uint32_t generic = 12;
- } quantization;
-};
-
-DracoCompressor *create_compressor() {
- return new DracoCompressor;
-}
-
-void set_compression_level(
- DracoCompressor *const compressor,
- uint32_t const compressionLevel
-) {
- compressor->compressionLevel = compressionLevel;
-}
-
-void set_position_quantization(
- DracoCompressor *const compressor,
- uint32_t const quantizationBitsPosition
-) {
- compressor->quantization.positions = quantizationBitsPosition;
-}
-
-void set_normal_quantization(
- DracoCompressor *const compressor,
- uint32_t const quantizationBitsNormal
-) {
- compressor->quantization.normals = quantizationBitsNormal;
-}
-
-void set_uv_quantization(
- DracoCompressor *const compressor,
- uint32_t const quantizationBitsTexCoord
-) {
- compressor->quantization.uvs = quantizationBitsTexCoord;
-}
-
-void set_generic_quantization(
- DracoCompressor *const compressor,
- uint32_t const bits
-) {
- compressor->quantization.generic = bits;
-}
-
-bool compress(
- DracoCompressor *const compressor
-) {
- draco::Encoder encoder;
-
- encoder.SetSpeedOptions(10 - (int)compressor->compressionLevel, 10 - (int)compressor->compressionLevel);
- encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, compressor->quantization.positions);
- encoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL, compressor->quantization.normals);
- encoder.SetAttributeQuantization(draco::GeometryAttribute::TEX_COORD, compressor->quantization.uvs);
- encoder.SetAttributeQuantization(draco::GeometryAttribute::GENERIC, compressor->quantization.generic);
-
- return encoder.EncodeMeshToBuffer(compressor->mesh, &compressor->encoderBuffer).ok();
-}
-
-bool compress_morphed(
- DracoCompressor *const compressor
-) {
- draco::Encoder encoder;
-
- encoder.SetSpeedOptions(10 - (int)compressor->compressionLevel, 10 - (int)compressor->compressionLevel);
-
- // For some reason, `EncodeMeshToBuffer` crashes when not disabling prediction or when enabling quantization
- // for attributes other position.
- encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, compressor->quantization.positions);
- encoder.SetAttributePredictionScheme(draco::GeometryAttribute::POSITION, draco::PREDICTION_NONE);
- encoder.SetAttributePredictionScheme(draco::GeometryAttribute::NORMAL, draco::PREDICTION_NONE);
- encoder.SetAttributePredictionScheme(draco::GeometryAttribute::TEX_COORD, draco::PREDICTION_NONE);
- encoder.SetAttributePredictionScheme(draco::GeometryAttribute::GENERIC, draco::PREDICTION_NONE);
-
- // Enforce triangle order preservation.
- encoder.SetEncodingMethod(draco::MESH_SEQUENTIAL_ENCODING);
-
- return encoder.EncodeMeshToBuffer(compressor->mesh, &compressor->encoderBuffer).ok();
-}
-
-uint64_t get_compressed_size(
- DracoCompressor const *const compressor
-) {
- return compressor->encoderBuffer.size();
-}
-
-void copy_to_bytes(
- DracoCompressor const *const compressor,
- uint8_t *const o_data
-) {
- memcpy(o_data, compressor->encoderBuffer.data(), compressor->encoderBuffer.size());
-}
-
-void destroy_compressor(
- DracoCompressor *const compressor
-) {
- delete compressor;
-}
-
-template<class T>
-void set_faces_impl(
- draco::Mesh &mesh,
- int const index_count,
- T const *const indices
-) {
- mesh.SetNumFaces((size_t) index_count / 3);
-
- for (int i = 0; i < index_count; i += 3)
- {
- const auto a = draco::PointIndex(indices[i]);
- const auto b = draco::PointIndex(indices[i + 1]);
- const auto c = draco::PointIndex(indices[i + 2]);
- mesh.SetFace(draco::FaceIndex((uint32_t) i), {a, b, c});
- }
-}
-
-void set_faces(
- DracoCompressor *const compressor,
- uint32_t const index_count,
- uint32_t const index_byte_length,
- uint8_t const *const indices
-) {
- switch (index_byte_length)
- {
- case 1:
- {
- set_faces_impl(compressor->mesh, index_count, (uint8_t *) indices);
- break;
- }
- case 2:
- {
- set_faces_impl(compressor->mesh, index_count, (uint16_t *) indices);
- break;
- }
- case 4:
- {
- set_faces_impl(compressor->mesh, index_count, (uint32_t *) indices);
- break;
- }
- default:
- {
- printf("%s: Unsupported index size %d\n", logTag, index_byte_length);
- break;
- }
- }
-}
-
-uint32_t add_attribute_to_mesh(
- DracoCompressor *const compressor,
- draco::GeometryAttribute::Type const semantics,
- draco::DataType const data_type,
- uint32_t const count,
- uint8_t const component_count,
- uint8_t const component_size,
- uint8_t const *const data
-) {
- auto buffer = std::make_unique<draco::DataBuffer>();
-
- draco::GeometryAttribute attribute;
-
- attribute.Init(
- semantics,
- &*buffer,
- component_count,
- data_type,
- false,
- component_size * component_count,
- 0
- );
-
- auto const id = (uint32_t)compressor->mesh.AddAttribute(attribute, true, count);
-
- for (uint32_t i = 0; i < count; i++)
- {
- compressor->mesh.attribute(id)->SetAttributeValue(
- draco::AttributeValueIndex(i),
- data + i * component_count * component_size
- );
- }
-
- compressor->buffers.emplace_back(std::move(buffer));
-
- return id;
-}
-
-uint32_t add_positions_f32(
- DracoCompressor *const compressor,
- uint32_t const count,
- uint8_t const *const data
-) {
- return add_attribute_to_mesh(compressor, draco::GeometryAttribute::POSITION,
- draco::DT_FLOAT32, count, 3, sizeof(float), data);
-}
-
-uint32_t add_normals_f32(
- DracoCompressor *const compressor,
- uint32_t const count,
- uint8_t const *const data
-) {
- return add_attribute_to_mesh(compressor, draco::GeometryAttribute::NORMAL,
- draco::DT_FLOAT32, count, 3, sizeof(float), data);
-}
-
-uint32_t add_uvs_f32(
- DracoCompressor *const compressor,
- uint32_t const count,
- uint8_t const *const data
-) {
- return add_attribute_to_mesh(compressor, draco::GeometryAttribute::TEX_COORD,
- draco::DT_FLOAT32, count, 2, sizeof(float), data);
-}
-
-uint32_t add_joints_u16(
- DracoCompressor *compressor,
- uint32_t const count,
- uint8_t const *const data
-) {
- return add_attribute_to_mesh(compressor, draco::GeometryAttribute::GENERIC,
- draco::DT_UINT16, count, 4, sizeof(uint16_t), data);
-}
-
-uint32_t add_weights_f32(
- DracoCompressor *compressor,
- uint32_t const count,
- uint8_t const *const data
-) {
- return add_attribute_to_mesh(compressor, draco::GeometryAttribute::GENERIC,
- draco::DT_FLOAT32, count, 4, sizeof(float), data);
-}
diff --git a/extern/draco/src/draco-compressor.h b/extern/draco/src/draco-compressor.h
deleted file mode 100644
index fb6168a61af..00000000000
--- a/extern/draco/src/draco-compressor.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * C++ library for the Draco compression feature inside the glTF-Blender-IO project.
- *
- * The python side uses the CTypes library to open the DLL, load function
- * pointers add pass the data to the compressor as raw bytes.
- *
- * The compressor intercepts the regular glTF exporter after data has been
- * gathered and right before the data is converted to a JSON representation,
- * which is going to be written out.
- *
- * The original uncompressed data is removed and replaces an extension,
- * pointing to the newly created buffer containing the compressed data.
- *
- * @author Jim Eckerlein <eckerlein@ux3d.io>
- * @date 2019-11-29
- */
-
-#include <cstdint>
-
-#if defined(_MSC_VER)
-#define DLL_EXPORT(retType) extern "C" __declspec(dllexport) retType __cdecl
-#else
-#define DLL_EXPORT(retType) extern "C" retType
-#endif
-
-/**
- * This tuple is opaquely exposed to Python through a pointer.
- * It encapsulates the complete current compressor state.
- *
- * A single instance is only intended to compress a single primitive.
- */
-struct DracoCompressor;
-
-DLL_EXPORT(DracoCompressor *)
-create_compressor ();
-
-DLL_EXPORT(void)
-set_compression_level (
- DracoCompressor *compressor,
- uint32_t compressionLevel
-);
-
-DLL_EXPORT(void)
-set_position_quantization (
- DracoCompressor *compressor,
- uint32_t quantizationBitsPosition
-);
-
-DLL_EXPORT(void)
-set_normal_quantization (
- DracoCompressor *compressor,
- uint32_t quantizationBitsNormal
-);
-
-DLL_EXPORT(void)
-set_uv_quantization (
- DracoCompressor *compressor,
- uint32_t quantizationBitsTexCoord
-);
-
-DLL_EXPORT(void)
-set_generic_quantization (
- DracoCompressor *compressor,
- uint32_t bits
-);
-
-/// Compresses a mesh.
-/// Use `compress_morphed` when compressing primitives which have morph targets.
-DLL_EXPORT(bool)
-compress (
- DracoCompressor *compressor
-);
-
-/// Compresses the mesh.
-/// Use this instead of `compress`, because this procedure takes into account that mesh triangles must not be reordered.
-DLL_EXPORT(bool)
-compress_morphed (
- DracoCompressor *compressor
-);
-
-/**
- * Returns the size of the compressed data in bytes.
- */
-DLL_EXPORT(uint64_t)
-get_compressed_size (
- DracoCompressor const *compressor
-);
-
-/**
- * Copies the compressed mesh into the given byte buffer.
- *
- * @param[o_data] A Python `bytes` object.
- */
-DLL_EXPORT(void)
-copy_to_bytes (
- DracoCompressor const *compressor,
- uint8_t *o_data
-);
-
-/**
- * Releases all memory allocated by the compressor.
- */
-DLL_EXPORT(void)
-destroy_compressor (
- DracoCompressor *compressor
-);
-
-DLL_EXPORT(void)
-set_faces (
- DracoCompressor *compressor,
- uint32_t index_count,
- uint32_t index_byte_length,
- uint8_t const *indices
-);
-
-/// Adds a `float` position attribute to the current mesh.
-/// Returns the id Draco has assigned to this attribute.
-DLL_EXPORT(uint32_t)
-add_positions_f32 (
- DracoCompressor *compressor,
- uint32_t count,
- uint8_t const *data
-);
-
-/// Adds a `float` normal attribute to the current mesh.
-/// Returns the id Draco has assigned to this attribute.
-DLL_EXPORT(uint32_t)
-add_normals_f32 (
- DracoCompressor *compressor,
- uint32_t count,
- uint8_t const *data
-);
-
-/// Adds a `float` texture coordinate attribute to the current mesh.
-/// Returns the id Draco has assigned to this attribute.
-DLL_EXPORT(uint32_t)
-add_uvs_f32 (
- DracoCompressor *compressor,
- uint32_t count,
- uint8_t const *data
-);
-
-/// Adds a `unsigned short` joint attribute to the current mesh.
-/// Returns the id Draco has assigned to this attribute.
-DLL_EXPORT(uint32_t)
-add_joints_u16 (
- DracoCompressor *compressor,
- uint32_t count,
- uint8_t const *data
-);
-
-/// Adds a `float` weight attribute to the current mesh.
-/// Returns the id Draco has assigned to this attribute.
-DLL_EXPORT(uint32_t)
-add_weights_f32 (
- DracoCompressor *compressor,
- uint32_t count,
- uint8_t const *data
-);
diff --git a/extern/draco/src/encoder.cpp b/extern/draco/src/encoder.cpp
new file mode 100644
index 00000000000..ff7570ecfcd
--- /dev/null
+++ b/extern/draco/src/encoder.cpp
@@ -0,0 +1,247 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jim Eckerlein <eckerlein@ux3d.io>
+ * @date 2019-11-18
+ */
+
+#include "encoder.h"
+
+#include <memory>
+#include <vector>
+
+#include "draco/mesh/mesh.h"
+#include "draco/core/encoder_buffer.h"
+#include "draco/compression/encode.h"
+
+#define LOG_PREFIX "DracoEncoder | "
+
+struct Encoder
+{
+ draco::Mesh mesh;
+ uint32_t encodedVertices;
+ uint32_t encodedIndices;
+ std::vector<std::unique_ptr<draco::DataBuffer>> buffers;
+ draco::EncoderBuffer encoderBuffer;
+ uint32_t compressionLevel = 7;
+ size_t rawSize = 0;
+ struct
+ {
+ uint32_t position = 14;
+ uint32_t normal = 10;
+ uint32_t uv = 12;
+ uint32_t color = 10;
+ uint32_t generic = 12;
+ } quantization;
+};
+
+Encoder *encoderCreate(uint32_t vertexCount)
+{
+ Encoder *encoder = new Encoder;
+ encoder->mesh.set_num_points(vertexCount);
+ return encoder;
+}
+
+void encoderRelease(Encoder *encoder)
+{
+ delete encoder;
+}
+
+void encoderSetCompressionLevel(Encoder *encoder, uint32_t compressionLevel) {
+ encoder->compressionLevel = compressionLevel;
+}
+
+void encoderSetQuantizationBits(Encoder *encoder, uint32_t position, uint32_t normal, uint32_t uv, uint32_t color, uint32_t generic)
+{
+ encoder->quantization.position = position;
+ encoder->quantization.normal = normal;
+ encoder->quantization.uv = uv;
+ encoder->quantization.color = color;
+ encoder->quantization.generic = generic;
+}
+
+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);
+ dracoEncoder.SetSpeedOptions(speed, speed);
+
+ dracoEncoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, encoder->quantization.position);
+ dracoEncoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL, encoder->quantization.normal);
+ dracoEncoder.SetAttributeQuantization(draco::GeometryAttribute::TEX_COORD, encoder->quantization.uv);
+ 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())
+ {
+ encoder->encodedVertices = static_cast<uint32_t>(dracoEncoder.num_encoded_points());
+ encoder->encodedIndices = static_cast<uint32_t>(dracoEncoder.num_encoded_faces() * 3);
+ size_t encodedSize = encoder->encoderBuffer.size();
+ float compressionRatio = static_cast<float>(encoder->rawSize) / static_cast<float>(encodedSize);
+ printf(LOG_PREFIX "Encoded %" PRIu32 " vertices, %" PRIu32 " indices, raw size: %zu, encoded size: %zu, compression ratio: %.2f\n", encoder->encodedVertices, encoder->encodedIndices, encoder->rawSize, encodedSize, compressionRatio);
+ return true;
+ }
+ else
+ {
+ printf(LOG_PREFIX "Error during Draco encoding: %s\n", encoderStatus.error_msg());
+ return false;
+ }
+}
+
+uint32_t encoderGetEncodedVertexCount(Encoder *encoder)
+{
+ return encoder->encodedVertices;
+}
+
+uint32_t encoderGetEncodedIndexCount(Encoder *encoder)
+{
+ return encoder->encodedIndices;
+}
+
+uint64_t encoderGetByteLength(Encoder *encoder)
+{
+ return encoder->encoderBuffer.size();
+}
+
+void encoderCopy(Encoder *encoder, uint8_t *data)
+{
+ memcpy(data, encoder->encoderBuffer.data(), encoder->encoderBuffer.size());
+}
+
+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])
+ };
+ encoder->mesh.SetFace(draco::FaceIndex(static_cast<uint32_t>(i)), face);
+ }
+}
+
+void encoderSetIndices(Encoder *encoder, size_t indexComponentType, uint32_t indexCount, void *indices)
+{
+ 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);
+ }
+}
+
+draco::GeometryAttribute::Type getAttributeSemantics(char *attribute)
+{
+ if (!strcmp(attribute, "POSITION"))
+ {
+ return draco::GeometryAttribute::POSITION;
+ }
+ if (!strcmp(attribute, "NORMAL"))
+ {
+ return draco::GeometryAttribute::NORMAL;
+ }
+ if (!strncmp(attribute, "TEXCOORD", strlen("TEXCOORD")))
+ {
+ return draco::GeometryAttribute::TEX_COORD;
+ }
+ if (!strncmp(attribute, "COLOR", strlen("COLOR")))
+ {
+ return draco::GeometryAttribute::COLOR;
+ }
+
+ return draco::GeometryAttribute::GENERIC;
+}
+
+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;
+ }
+}
+
+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);
+
+ auto id = static_cast<uint32_t>(encoder->mesh.AddAttribute(attribute, true, count));
+ auto dataBytes = reinterpret_cast<uint8_t *>(data);
+
+ for (uint32_t i = 0; i < count; i++)
+ {
+ encoder->mesh.attribute(id)->SetAttributeValue(draco::AttributeValueIndex(i), dataBytes + i * stride);
+ }
+
+ encoder->buffers.emplace_back(std::move(buffer));
+ encoder->rawSize += count * stride;
+ return id;
+}
diff --git a/extern/draco/src/encoder.h b/extern/draco/src/encoder.h
new file mode 100644
index 00000000000..2f7f21a469b
--- /dev/null
+++ b/extern/draco/src/encoder.h
@@ -0,0 +1,51 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Library for the Draco encoding/decoding feature inside the glTF-Blender-IO project.
+ *
+ * The python script within glTF-Blender-IO uses the CTypes library to open the DLL,
+ * load function pointers add pass the raw data to the encoder.
+ *
+ * @author Jim Eckerlein <eckerlein@ux3d.io>
+ * @date 2020-11-18
+ */
+
+#pragma once
+
+#include "common.h"
+
+struct Encoder;
+
+API(Encoder *) encoderCreate(uint32_t vertexCount);
+
+API(void) encoderRelease(Encoder *encoder);
+
+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(bool) encoderEncode(Encoder *encoder, uint8_t preserveTriangleOrder);
+
+API(uint64_t) encoderGetByteLength(Encoder *encoder);
+
+API(void) encoderCopy(Encoder *encoder, uint8_t *data);
+
+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) encoderGetEncodedVertexCount(Encoder *encoder);
+
+API(uint32_t) encoderGetEncodedIndexCount(Encoder *encoder);
diff --git a/extern/gflags/README.blender b/extern/gflags/README.blender
index be68c310997..068c0507d04 100644
--- a/extern/gflags/README.blender
+++ b/extern/gflags/README.blender
@@ -1,6 +1,6 @@
Project: Google Flags
URL: https://github.com/gflags/gflags
-License: New BSD
+License: BSD 3-Clause
Upstream version: 2.2.1 (46f73f88b18)
Local modifications:
diff --git a/extern/glew-es/LICENSE.txt b/extern/glew-es/LICENSE.txt
new file mode 100644
index 00000000000..f7078042e95
--- /dev/null
+++ b/extern/glew-es/LICENSE.txt
@@ -0,0 +1,73 @@
+The OpenGL Extension Wrangler Library
+Copyright (C) 2002-2007, Milan Ikits <milan ikits[]ieee org>
+Copyright (C) 2002-2007, Marcelo E. Magallon <mmagallo[]debian org>
+Copyright (C) 2002, Lev Povalahev
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* The name of the author may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Mesa 3-D graphics library
+Version: 7.0
+
+Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+Copyright (c) 2007 The Khronos Group Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and/or associated documentation files (the
+"Materials"), to deal in the Materials without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Materials, and to
+permit persons to whom the Materials are furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Materials.
+
+THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
diff --git a/extern/glew-es/README.blender b/extern/glew-es/README.blender
new file mode 100644
index 00000000000..59a932a07f1
--- /dev/null
+++ b/extern/glew-es/README.blender
@@ -0,0 +1,5 @@
+Project: The OpenGL Extension Wrangler Library
+URL: http://glew.sourceforge.net/
+License: Check LICENSE.txt
+Upstream version: 2.0.0
+Local modifications: None
diff --git a/extern/glew/LICENSE.txt b/extern/glew/LICENSE.txt
new file mode 100644
index 00000000000..f7078042e95
--- /dev/null
+++ b/extern/glew/LICENSE.txt
@@ -0,0 +1,73 @@
+The OpenGL Extension Wrangler Library
+Copyright (C) 2002-2007, Milan Ikits <milan ikits[]ieee org>
+Copyright (C) 2002-2007, Marcelo E. Magallon <mmagallo[]debian org>
+Copyright (C) 2002, Lev Povalahev
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* The name of the author may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Mesa 3-D graphics library
+Version: 7.0
+
+Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+Copyright (c) 2007 The Khronos Group Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and/or associated documentation files (the
+"Materials"), to deal in the Materials without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Materials, and to
+permit persons to whom the Materials are furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Materials.
+
+THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
diff --git a/extern/glew/README.blender b/extern/glew/README.blender
new file mode 100644
index 00000000000..59a932a07f1
--- /dev/null
+++ b/extern/glew/README.blender
@@ -0,0 +1,5 @@
+Project: The OpenGL Extension Wrangler Library
+URL: http://glew.sourceforge.net/
+License: Check LICENSE.txt
+Upstream version: 2.0.0
+Local modifications: None
diff --git a/extern/glog/README.blender b/extern/glog/README.blender
index 62cd065ef0f..5b4dab199bf 100644
--- a/extern/glog/README.blender
+++ b/extern/glog/README.blender
@@ -1,6 +1,6 @@
Project: Google Logging
URL: https://github.com/google/glog
-License: New BSD
+License: BSD 3-Clause
Upstream version: 0.4.0, 96a2f23dca4
Local modifications:
* Added per-platform config.h files so no configuration-time
diff --git a/extern/gmock/README.blender b/extern/gmock/README.blender
index 3f9d80362d8..23e750177b8 100644
--- a/extern/gmock/README.blender
+++ b/extern/gmock/README.blender
@@ -1,5 +1,5 @@
Project: Google C++ Testing Framework
URL: https://github.com/google/googletest
-License: New BSD
+License: BSD 3-Clause
Upstream version: 1.10.0 (703bd9caab5)
Local modifications: None
diff --git a/extern/gtest/README.blender b/extern/gtest/README.blender
index 3f9d80362d8..23e750177b8 100644
--- a/extern/gtest/README.blender
+++ b/extern/gtest/README.blender
@@ -1,5 +1,5 @@
Project: Google C++ Testing Framework
URL: https://github.com/google/googletest
-License: New BSD
+License: BSD 3-Clause
Upstream version: 1.10.0 (703bd9caab5)
Local modifications: None
diff --git a/extern/lzma/README.blender b/extern/lzma/README.blender
new file mode 100644
index 00000000000..0111946e30e
--- /dev/null
+++ b/extern/lzma/README.blender
@@ -0,0 +1,5 @@
+Project: LZMA SDK
+URL: https://www.7-zip.org/sdk.html
+License: Public Domain
+Upstream version: 4.65
+Local modifications: None
diff --git a/extern/lzo/README.blender b/extern/lzo/README.blender
new file mode 100644
index 00000000000..d91500b7780
--- /dev/null
+++ b/extern/lzo/README.blender
@@ -0,0 +1,5 @@
+Project: miniLZO - mini subset of the LZO real-time data compression librar
+URL: http://www.oberhumer.com/opensource/lzo/
+License: GPLv2+
+Upstream version: 2.08
+Local modifications: None
diff --git a/extern/mantaflow/README.blender b/extern/mantaflow/README.blender
new file mode 100644
index 00000000000..bc1e2a164dc
--- /dev/null
+++ b/extern/mantaflow/README.blender
@@ -0,0 +1,5 @@
+Project: Mantaflow
+URL: http://mantaflow.com/
+License: Apache 2.0
+Upstream version: 0.13
+Local modifications: None
diff --git a/extern/mantaflow/preprocessed/gitinfo.h b/extern/mantaflow/preprocessed/gitinfo.h
index d7a69564a3b..a0590e6a0b0 100644
--- a/extern/mantaflow/preprocessed/gitinfo.h
+++ b/extern/mantaflow/preprocessed/gitinfo.h
@@ -1,3 +1,3 @@
-#define MANTA_GIT_VERSION "commit bb7cde47b6e04fa62815c70775dc70f02065599f"
+#define MANTA_GIT_VERSION "commit 327917cd59b03bef3a953b5f58fc1637b3a83e01"
diff --git a/extern/mantaflow/preprocessed/plugin/advection.cpp b/extern/mantaflow/preprocessed/plugin/advection.cpp
index 4ccf33cc362..dd891e22088 100644
--- a/extern/mantaflow/preprocessed/plugin/advection.cpp
+++ b/extern/mantaflow/preprocessed/plugin/advection.cpp
@@ -1090,8 +1090,8 @@ struct extrapolateVelConvectiveBC : public KernelBase {
Real timeStep) const
{
if (flags.isOutflow(i, j, k)) {
- Vec3 bulkVel = getBulkVel(flags, vel, i, j, k);
- int dim = flags.is3D() ? 3 : 2;
+ const Vec3 bulkVel = getBulkVel(flags, vel, i, j, k);
+ const int dim = flags.is3D() ? 3 : 2;
const Vec3i cur = Vec3i(i, j, k);
Vec3i low, up, flLow, flUp;
int cnt = 0;
@@ -1099,8 +1099,8 @@ struct extrapolateVelConvectiveBC : public KernelBase {
for (int c = 0; c < dim; c++) {
low = up = flLow = flUp = cur;
Real factor = timeStep *
- max((Real)1.0, bulkVel[c]); // prevent the extrapolated velocity from
- // exploding when bulk velocity below 1
+ max((Real)1.0, abs(bulkVel[c])); // prevent the extrapolated velocity from
+ // exploding when bulk velocity below 1
low[c] = flLow[c] = cur[c] - 1;
up[c] = flUp[c] = cur[c] + 1;
// iterate over bWidth to allow for extrapolation into more distant outflow cells;
diff --git a/extern/mantaflow/preprocessed/plugin/pressure.cpp b/extern/mantaflow/preprocessed/plugin/pressure.cpp
index dfba8e0082b..1100a58db47 100644
--- a/extern/mantaflow/preprocessed/plugin/pressure.cpp
+++ b/extern/mantaflow/preprocessed/plugin/pressure.cpp
@@ -1147,26 +1147,18 @@ void solvePressureSystem(Grid<Real> &rhs,
gcg->setAccuracy(cgAccuracy);
gcg->setUseL2Norm(useL2Norm);
- int maxIter = 0;
+ int maxIter = (int)(cgMaxIterFac * flags.getSize().max()) * (flags.is3D() ? 1 : 4);
Grid<Real> *pca0 = nullptr, *pca1 = nullptr, *pca2 = nullptr, *pca3 = nullptr;
GridMg *pmg = nullptr;
// optional preconditioning
- if (preconditioner == PcNone || preconditioner == PcMIC) {
- maxIter = (int)(cgMaxIterFac * flags.getSize().max()) * (flags.is3D() ? 1 : 4);
-
+ if (preconditioner == PcMIC) {
pca0 = new Grid<Real>(parent);
pca1 = new Grid<Real>(parent);
pca2 = new Grid<Real>(parent);
pca3 = new Grid<Real>(parent);
-
- gcg->setICPreconditioner(preconditioner == PcMIC ? GridCgInterface::PC_mICP :
- GridCgInterface::PC_None,
- pca0,
- pca1,
- pca2,
- pca3);
+ gcg->setICPreconditioner(GridCgInterface::PC_mICP, pca0, pca1, pca2, pca3);
}
else if (preconditioner == PcMGDynamic || preconditioner == PcMGStatic) {
maxIter = 100;
diff --git a/intern/atomic/atomic_ops.h b/intern/atomic/atomic_ops.h
index e6ca7a105ba..ad404c756ce 100644
--- a/intern/atomic/atomic_ops.h
+++ b/intern/atomic/atomic_ops.h
@@ -87,6 +87,9 @@ ATOMIC_INLINE int32_t atomic_fetch_and_add_int32(int32_t *p, int32_t x);
ATOMIC_INLINE int32_t atomic_fetch_and_or_int32(int32_t *p, int32_t x);
ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t x);
+ATOMIC_INLINE int16_t atomic_fetch_and_or_int16(int16_t *p, int16_t b);
+ATOMIC_INLINE int16_t atomic_fetch_and_and_int16(int16_t *p, int16_t b);
+
ATOMIC_INLINE uint8_t atomic_fetch_and_or_uint8(uint8_t *p, uint8_t b);
ATOMIC_INLINE uint8_t atomic_fetch_and_and_uint8(uint8_t *p, uint8_t b);
diff --git a/intern/atomic/intern/atomic_ops_msvc.h b/intern/atomic/intern/atomic_ops_msvc.h
index 356140541ba..c9ad1a46ab9 100644
--- a/intern/atomic/intern/atomic_ops_msvc.h
+++ b/intern/atomic/intern/atomic_ops_msvc.h
@@ -163,6 +163,20 @@ ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t x)
}
/******************************************************************************/
+/* 16-bit operations. */
+
+/* Signed */
+ATOMIC_INLINE int16_t atomic_fetch_and_or_int16(int16_t *p, int16_t x)
+{
+ return InterlockedOr16((short *)p, x);
+}
+
+ATOMIC_INLINE int16_t atomic_fetch_and_and_int16(int16_t *p, int16_t x)
+{
+ return InterlockedAnd16((short *)p, x);
+}
+
+/******************************************************************************/
/* 8-bit operations. */
/* Unsigned */
diff --git a/intern/atomic/intern/atomic_ops_unix.h b/intern/atomic/intern/atomic_ops_unix.h
index 0de9daaaf5f..dc1e71cda76 100644
--- a/intern/atomic/intern/atomic_ops_unix.h
+++ b/intern/atomic/intern/atomic_ops_unix.h
@@ -55,6 +55,7 @@
* its gcc doesn't have __GCC_HAVE_SYNC_COMPARE_AND_SWAP_n defined.
*/
# define JE_FORCE_SYNC_COMPARE_AND_SWAP_1
+# define JE_FORCE_SYNC_COMPARE_AND_SWAP_2
# define JE_FORCE_SYNC_COMPARE_AND_SWAP_4
# define JE_FORCE_SYNC_COMPARE_AND_SWAP_8
#endif
@@ -326,6 +327,24 @@ ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t x)
#endif
/******************************************************************************/
+/* 16-bit operations. */
+#if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_2))
+
+/* Signed */
+ATOMIC_INLINE int16_t atomic_fetch_and_and_int16(int16_t *p, int16_t b)
+{
+ return __sync_fetch_and_and(p, b);
+}
+ATOMIC_INLINE int16_t atomic_fetch_and_or_int16(int16_t *p, int16_t b)
+{
+ return __sync_fetch_and_or(p, b);
+}
+
+#else
+# error "Missing implementation for 16-bit atomic operations"
+#endif
+
+/******************************************************************************/
/* 8-bit operations. */
#if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_1))
/* Unsigned */
diff --git a/intern/atomic/tests/atomic_test.cc b/intern/atomic/tests/atomic_test.cc
index 6178b5074a7..661c130c65d 100644
--- a/intern/atomic/tests/atomic_test.cc
+++ b/intern/atomic/tests/atomic_test.cc
@@ -559,6 +559,39 @@ TEST(atomic, atomic_fetch_and_and_int32)
/** \} */
+/** \name 16 bit signed int atomics
+ * \{ */
+
+TEST(atomic, atomic_fetch_and_or_int16)
+{
+ {
+ int16_t value = 12;
+ EXPECT_EQ(atomic_fetch_and_or_int16(&value, 5), 12);
+ EXPECT_EQ(value, 13);
+ }
+
+ {
+ int16_t value = 0x1234;
+ EXPECT_EQ(atomic_fetch_and_or_int16(&value, -0x5678), 0x1234);
+ EXPECT_EQ(value, -0x4444);
+ }
+}
+
+TEST(atomic, atomic_fetch_and_and_int16)
+{
+ {
+ int16_t value = 12;
+ EXPECT_EQ(atomic_fetch_and_and_int16(&value, 5), 12);
+ EXPECT_EQ(value, 4);
+ }
+
+ {
+ int16_t value = 0x1234;
+ EXPECT_EQ(atomic_fetch_and_and_int16(&value, -0x789A), 0x1234);
+ EXPECT_EQ(value, 0x224);
+ }
+}
+
/** \name 8 bit unsigned int atomics
* \{ */
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index 807dcaf7f43..69ad1321c1a 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -270,14 +270,14 @@ def list_render_passes(scene, srl):
if crl.use_pass_volume_indirect: yield ("VolumeInd", "RGB", 'COLOR')
# Cryptomatte passes.
- crypto_depth = (crl.pass_crypto_depth + 1) // 2
- if crl.use_pass_crypto_object:
+ crypto_depth = (srl.pass_cryptomatte_depth + 1) // 2
+ if srl.use_pass_cryptomatte_object:
for i in range(0, crypto_depth):
yield ("CryptoObject" + '{:02d}'.format(i), "RGBA", 'COLOR')
- if crl.use_pass_crypto_material:
+ if srl.use_pass_cryptomatte_material:
for i in range(0, crypto_depth):
yield ("CryptoMaterial" + '{:02d}'.format(i), "RGBA", 'COLOR')
- if srl.cycles.use_pass_crypto_asset:
+ if srl.use_pass_cryptomatte_asset:
for i in range(0, crypto_depth):
yield ("CryptoAsset" + '{:02d}'.format(i), "RGBA", 'COLOR')
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 054fd900419..1cb29fc6cb0 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -1470,37 +1470,6 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
default='RGB_ALBEDO_NORMAL',
)
- use_pass_crypto_object: BoolProperty(
- name="Cryptomatte Object",
- description="Render cryptomatte object pass, for isolating objects in compositing",
- default=False,
- update=update_render_passes,
- )
- use_pass_crypto_material: BoolProperty(
- name="Cryptomatte Material",
- description="Render cryptomatte material pass, for isolating materials in compositing",
- default=False,
- update=update_render_passes,
- )
- use_pass_crypto_asset: BoolProperty(
- name="Cryptomatte Asset",
- description="Render cryptomatte asset pass, for isolating groups of objects with the same parent",
- default=False,
- update=update_render_passes,
- )
- pass_crypto_depth: IntProperty(
- name="Cryptomatte Levels",
- description="Sets how many unique objects can be distinguished per pixel",
- default=6, min=2, max=16, step=2,
- update=update_render_passes,
- )
- pass_crypto_accurate: BoolProperty(
- name="Cryptomatte Accurate",
- description="Generate a more accurate Cryptomatte pass. CPU only, may render slower and use more memory",
- default=True,
- update=update_render_passes,
- )
-
aovs: CollectionProperty(
type=CyclesAOVPass,
description="Custom render passes that can be output by shader nodes",
@@ -1651,11 +1620,6 @@ class CyclesPreferences(bpy.types.AddonPreferences):
for device in devices:
box.prop(device, "use", text=device.name)
- if device_type == 'OPTIX':
- col = box.column(align=True)
- col.label(text="OptiX support is experimental", icon='INFO')
- col.label(text="Not all Cycles features are supported yet", icon='BLANK1')
-
def draw_impl(self, layout, context):
row = layout.row()
row.prop(self, "compute_device_type", expand=True)
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 6b88be3e7aa..f24265d256a 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -23,6 +23,7 @@ from bl_ui.utils import PresetPanel
from bpy.types import Panel
from bl_ui.properties_grease_pencil_common import GreasePencilSimplifyPanel
+from bl_ui.properties_view_layer import ViewLayerCryptomattePanel
class CYCLES_PT_sampling_presets(PresetPanel, Panel):
@@ -885,31 +886,11 @@ class CYCLES_RENDER_PT_passes_light(CyclesButtonsPanel, Panel):
col.prop(view_layer, "use_pass_ambient_occlusion", text="Ambient Occlusion")
-class CYCLES_RENDER_PT_passes_crypto(CyclesButtonsPanel, Panel):
+class CYCLES_RENDER_PT_passes_crypto(CyclesButtonsPanel, ViewLayerCryptomattePanel):
bl_label = "Cryptomatte"
bl_context = "view_layer"
bl_parent_id = "CYCLES_RENDER_PT_passes"
- def draw(self, context):
- import _cycles
-
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False
-
- cycles_view_layer = context.view_layer.cycles
-
- col = layout.column(heading="Include", align=True)
- col.prop(cycles_view_layer, "use_pass_crypto_object", text="Object")
- col.prop(cycles_view_layer, "use_pass_crypto_material", text="Material")
- col.prop(cycles_view_layer, "use_pass_crypto_asset", text="Asset")
-
- layout.prop(cycles_view_layer, "pass_crypto_depth", text="Levels")
-
- row = layout.row(align=True)
- row.active = use_cpu(context)
- row.prop(cycles_view_layer, "pass_crypto_accurate", text="Accurate Mode")
-
class CYCLES_RENDER_PT_passes_debug(CyclesButtonsPanel, Panel):
bl_label = "Debug"
@@ -1841,10 +1822,6 @@ class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel):
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'CYCLES'}
- @classmethod
- def poll(cls, context):
- return CyclesButtonsPanel.poll(context) and not use_optix(context)
-
def draw(self, context):
layout = self.layout
layout.use_property_split = True
@@ -1855,6 +1832,9 @@ class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel):
cbk = scene.render.bake
rd = scene.render
+ if use_optix(context):
+ layout.label(text="Baking is performed using CUDA instead of OptiX", icon='INFO')
+
if rd.use_bake_multires:
layout.operator("object.bake_image", icon='RENDER_STILL')
layout.prop(rd, "use_bake_multires")
diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py
index f7e3e693858..5dae88d60c7 100644
--- a/intern/cycles/blender/addon/version_update.py
+++ b/intern/cycles/blender/addon/version_update.py
@@ -108,7 +108,7 @@ def do_versions(self):
library_versions.setdefault(library.version, []).append(library)
# Do versioning per library, since they might have different versions.
- max_need_versioning = (2, 80, 41)
+ max_need_versioning = (2, 92, 4)
for version, libraries in library_versions.items():
if version > max_need_versioning:
continue
@@ -194,6 +194,16 @@ def do_versions(self):
if not cscene.is_property_set("sample_clamp_indirect"):
cscene.sample_clamp_indirect = 0.0
+ if version <= (2, 92, 4):
+ if scene.render.engine == 'CYCLES':
+ for view_layer in scene.view_layers:
+ cview_layer = view_layer.cycles
+ view_layer.use_pass_cryptomatte_object = cview_layer.get("use_pass_crypto_object", False)
+ view_layer.use_pass_cryptomatte_material = cview_layer.get("use_pass_crypto_material", False)
+ view_layer.use_pass_cryptomatte_asset = cview_layer.get("use_pass_crypto_asset", False)
+ view_layer.pass_cryptomatte_depth = cview_layer.get("pass_crypto_depth", 6)
+ view_layer.use_pass_cryptomatte_accurate = cview_layer.get("pass_crypto_accurate", True)
+
# Lamps
for light in bpy.data.lights:
if light.library not in libraries:
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index e85b4ee1fc6..3420025f472 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -1064,6 +1064,8 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *me
/* update original sockets */
+ mesh->clear_non_sockets();
+
for (const SocketType &socket : new_mesh.type->inputs) {
/* Those sockets are updated in sync_object, so do not modify them. */
if (socket.name == "use_motion_blur" || socket.name == "motion_steps" ||
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 94ff0ff1473..b830db7485b 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -667,10 +667,10 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
/* Cryptomatte stores two ID/weight pairs per RGBA layer.
* User facing parameter is the number of pairs. */
- int crypto_depth = divide_up(min(16, get_int(crl, "pass_crypto_depth")), 2);
+ int crypto_depth = divide_up(min(16, b_view_layer.pass_cryptomatte_depth()), 2);
scene->film->set_cryptomatte_depth(crypto_depth);
CryptomatteType cryptomatte_passes = CRYPT_NONE;
- if (get_boolean(crl, "use_pass_crypto_object")) {
+ if (b_view_layer.use_pass_cryptomatte_object()) {
for (int i = 0; i < crypto_depth; i++) {
string passname = cryptomatte_prefix + string_printf("Object%02d", i);
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
@@ -678,7 +678,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
}
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_OBJECT);
}
- if (get_boolean(crl, "use_pass_crypto_material")) {
+ if (b_view_layer.use_pass_cryptomatte_material()) {
for (int i = 0; i < crypto_depth; i++) {
string passname = cryptomatte_prefix + string_printf("Material%02d", i);
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
@@ -686,7 +686,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
}
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_MATERIAL);
}
- if (get_boolean(crl, "use_pass_crypto_asset")) {
+ if (b_view_layer.use_pass_cryptomatte_asset()) {
for (int i = 0; i < crypto_depth; i++) {
string passname = cryptomatte_prefix + string_printf("Asset%02d", i);
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
@@ -694,7 +694,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
}
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_ASSET);
}
- if (get_boolean(crl, "pass_crypto_accurate") && cryptomatte_passes != CRYPT_NONE) {
+ if (b_view_layer.use_pass_cryptomatte_accurate() && cryptomatte_passes != CRYPT_NONE) {
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_ACCURATE);
}
scene->film->set_cryptomatte_passes(cryptomatte_passes);
diff --git a/intern/cycles/device/device_optix.cpp b/intern/cycles/device/device_optix.cpp
index 95234845f98..c6276c1e955 100644
--- a/intern/cycles/device/device_optix.cpp
+++ b/intern/cycles/device/device_optix.cpp
@@ -141,7 +141,8 @@ class OptiXDevice : public CUDADevice {
PG_BAKE, // kernel_bake_evaluate
PG_DISP, // kernel_displace_evaluate
PG_BACK, // kernel_background_evaluate
- NUM_PROGRAM_GROUPS
+ PG_CALL,
+ NUM_PROGRAM_GROUPS = PG_CALL + 3
};
// List of OptiX pipelines
@@ -296,6 +297,10 @@ class OptiXDevice : public CUDADevice {
BVHLayoutMask get_bvh_layout_mask() const override
{
+ // CUDA kernels are used when doing baking, so need to build a BVH those can understand too!
+ if (optix_module == NULL)
+ return CUDADevice::get_bvh_layout_mask();
+
// OptiX has its own internal acceleration structure format
return BVH_LAYOUT_OPTIX;
}
@@ -329,15 +334,9 @@ class OptiXDevice : public CUDADevice {
return false;
}
- // Disable baking for now, since its kernel is not well-suited for inlining and is very slow
+ // Baking is currently performed using CUDA, so no need to load OptiX kernels
if (requested_features.use_baking) {
- set_error("OptiX backend does not support baking yet");
- return false;
- }
- // Disable shader raytracing support for now, since continuation callables are slow
- if (requested_features.use_shader_raytrace) {
- set_error("OptiX backend does not support 'Ambient Occlusion' and 'Bevel' shader nodes yet");
- return false;
+ return true;
}
const CUDAContextScope scope(cuContext);
@@ -410,7 +409,9 @@ class OptiXDevice : public CUDADevice {
}
{ // Load and compile PTX module with OptiX kernels
- string ptx_data, ptx_filename = path_get("lib/kernel_optix.ptx");
+ string ptx_data, ptx_filename = path_get(requested_features.use_shader_raytrace ?
+ "lib/kernel_optix_shader_raytrace.ptx" :
+ "lib/kernel_optix.ptx");
if (use_adaptive_compilation() || path_file_size(ptx_filename) == -1) {
if (!getenv("OPTIX_ROOT_DIR")) {
set_error(
@@ -525,6 +526,21 @@ class OptiXDevice : public CUDADevice {
group_descs[PG_BACK].raygen.entryFunctionName = "__raygen__kernel_optix_background";
}
+ // Shader raytracing replaces some functions with direct callables
+ if (requested_features.use_shader_raytrace) {
+ group_descs[PG_CALL + 0].kind = OPTIX_PROGRAM_GROUP_KIND_CALLABLES;
+ group_descs[PG_CALL + 0].callables.moduleDC = optix_module;
+ group_descs[PG_CALL + 0].callables.entryFunctionNameDC = "__direct_callable__svm_eval_nodes";
+ group_descs[PG_CALL + 1].kind = OPTIX_PROGRAM_GROUP_KIND_CALLABLES;
+ group_descs[PG_CALL + 1].callables.moduleDC = optix_module;
+ group_descs[PG_CALL + 1].callables.entryFunctionNameDC =
+ "__direct_callable__kernel_volume_shadow";
+ group_descs[PG_CALL + 2].kind = OPTIX_PROGRAM_GROUP_KIND_CALLABLES;
+ group_descs[PG_CALL + 2].callables.moduleDC = optix_module;
+ group_descs[PG_CALL + 2].callables.entryFunctionNameDC =
+ "__direct_callable__subsurface_scatter_multi_setup";
+ }
+
check_result_optix_ret(optixProgramGroupCreate(
context, group_descs, NUM_PROGRAM_GROUPS, &group_options, nullptr, 0, groups));
@@ -564,33 +580,51 @@ class OptiXDevice : public CUDADevice {
# endif
{ // Create path tracing pipeline
- OptixProgramGroup pipeline_groups[] = {
- groups[PG_RGEN],
- groups[PG_MISS],
- groups[PG_HITD],
- groups[PG_HITS],
- groups[PG_HITL],
+ vector<OptixProgramGroup> pipeline_groups;
+ pipeline_groups.reserve(NUM_PROGRAM_GROUPS);
+ pipeline_groups.push_back(groups[PG_RGEN]);
+ pipeline_groups.push_back(groups[PG_MISS]);
+ pipeline_groups.push_back(groups[PG_HITD]);
+ pipeline_groups.push_back(groups[PG_HITS]);
+ pipeline_groups.push_back(groups[PG_HITL]);
# if OPTIX_ABI_VERSION >= 36
- groups[PG_HITD_MOTION],
- groups[PG_HITS_MOTION],
+ if (motion_blur) {
+ pipeline_groups.push_back(groups[PG_HITD_MOTION]);
+ pipeline_groups.push_back(groups[PG_HITS_MOTION]);
+ }
# endif
- };
- check_result_optix_ret(
- optixPipelineCreate(context,
- &pipeline_options,
- &link_options,
- pipeline_groups,
- (sizeof(pipeline_groups) / sizeof(pipeline_groups[0])),
- nullptr,
- 0,
- &pipelines[PIP_PATH_TRACE]));
+ if (requested_features.use_shader_raytrace) {
+ pipeline_groups.push_back(groups[PG_CALL + 0]);
+ pipeline_groups.push_back(groups[PG_CALL + 1]);
+ pipeline_groups.push_back(groups[PG_CALL + 2]);
+ }
+
+ check_result_optix_ret(optixPipelineCreate(context,
+ &pipeline_options,
+ &link_options,
+ pipeline_groups.data(),
+ pipeline_groups.size(),
+ nullptr,
+ 0,
+ &pipelines[PIP_PATH_TRACE]));
// Combine ray generation and trace continuation stack size
const unsigned int css = stack_size[PG_RGEN].cssRG + link_options.maxTraceDepth * trace_css;
+ // Max direct callable depth is one of the following, so combine accordingly
+ // - __raygen__ -> svm_eval_nodes
+ // - __raygen__ -> kernel_volume_shadow -> svm_eval_nodes
+ // - __raygen__ -> subsurface_scatter_multi_setup -> svm_eval_nodes
+ const unsigned int dss = stack_size[PG_CALL + 0].dssDC +
+ std::max(stack_size[PG_CALL + 1].dssDC,
+ stack_size[PG_CALL + 2].dssDC);
// Set stack size depending on pipeline options
check_result_optix_ret(
- optixPipelineSetStackSize(pipelines[PIP_PATH_TRACE], 0, 0, css, (motion_blur ? 3 : 2)));
+ optixPipelineSetStackSize(pipelines[PIP_PATH_TRACE],
+ 0,
+ requested_features.use_shader_raytrace ? dss : 0,
+ css,
+ motion_blur ? 3 : 2));
}
// Only need to create shader evaluation pipeline if one of these features is used:
@@ -599,37 +633,51 @@ class OptiXDevice : public CUDADevice {
requested_features.use_true_displacement;
if (use_shader_eval_pipeline) { // Create shader evaluation pipeline
- OptixProgramGroup pipeline_groups[] = {
- groups[PG_BAKE],
- groups[PG_DISP],
- groups[PG_BACK],
- groups[PG_MISS],
- groups[PG_HITD],
- groups[PG_HITS],
- groups[PG_HITL],
+ vector<OptixProgramGroup> pipeline_groups;
+ pipeline_groups.reserve(NUM_PROGRAM_GROUPS);
+ pipeline_groups.push_back(groups[PG_BAKE]);
+ pipeline_groups.push_back(groups[PG_DISP]);
+ pipeline_groups.push_back(groups[PG_BACK]);
+ pipeline_groups.push_back(groups[PG_MISS]);
+ pipeline_groups.push_back(groups[PG_HITD]);
+ pipeline_groups.push_back(groups[PG_HITS]);
+ pipeline_groups.push_back(groups[PG_HITL]);
# if OPTIX_ABI_VERSION >= 36
- groups[PG_HITD_MOTION],
- groups[PG_HITS_MOTION],
+ if (motion_blur) {
+ pipeline_groups.push_back(groups[PG_HITD_MOTION]);
+ pipeline_groups.push_back(groups[PG_HITS_MOTION]);
+ }
# endif
- };
- check_result_optix_ret(
- optixPipelineCreate(context,
- &pipeline_options,
- &link_options,
- pipeline_groups,
- (sizeof(pipeline_groups) / sizeof(pipeline_groups[0])),
- nullptr,
- 0,
- &pipelines[PIP_SHADER_EVAL]));
+ if (requested_features.use_shader_raytrace) {
+ pipeline_groups.push_back(groups[PG_CALL + 0]);
+ pipeline_groups.push_back(groups[PG_CALL + 1]);
+ pipeline_groups.push_back(groups[PG_CALL + 2]);
+ }
+
+ check_result_optix_ret(optixPipelineCreate(context,
+ &pipeline_options,
+ &link_options,
+ pipeline_groups.data(),
+ pipeline_groups.size(),
+ nullptr,
+ 0,
+ &pipelines[PIP_SHADER_EVAL]));
// Calculate continuation stack size based on the maximum of all ray generation stack sizes
const unsigned int css = std::max(stack_size[PG_BAKE].cssRG,
std::max(stack_size[PG_DISP].cssRG,
stack_size[PG_BACK].cssRG)) +
link_options.maxTraceDepth * trace_css;
+ const unsigned int dss = stack_size[PG_CALL + 0].dssDC +
+ std::max(stack_size[PG_CALL + 1].dssDC,
+ stack_size[PG_CALL + 2].dssDC);
- check_result_optix_ret(optixPipelineSetStackSize(
- pipelines[PIP_SHADER_EVAL], 0, 0, css, (pipeline_options.usesMotionBlur ? 3 : 2)));
+ check_result_optix_ret(
+ optixPipelineSetStackSize(pipelines[PIP_SHADER_EVAL],
+ 0,
+ requested_features.use_shader_raytrace ? dss : 0,
+ css,
+ motion_blur ? 3 : 2));
}
// Clean up program group objects
@@ -655,6 +703,11 @@ class OptiXDevice : public CUDADevice {
while (task.acquire_tile(this, tile, task.tile_types)) {
if (tile.task == RenderTile::PATH_TRACE)
launch_render(task, tile, thread_index);
+ else if (tile.task == RenderTile::BAKE) {
+ // Perform baking using CUDA, since it is not currently implemented in OptiX
+ device_vector<WorkTile> work_tiles(this, "work_tiles", MEM_READ_ONLY);
+ CUDADevice::render(task, tile, work_tiles);
+ }
else if (tile.task == RenderTile::DENOISE)
launch_denoise(task, tile);
task.release_tile(tile);
@@ -734,6 +787,9 @@ class OptiXDevice : public CUDADevice {
# else
sbt_params.hitgroupRecordCount = 3; // PG_HITD, PG_HITS, PG_HITL
# endif
+ sbt_params.callablesRecordBase = sbt_data.device_pointer + PG_CALL * sizeof(SbtRecord);
+ sbt_params.callablesRecordCount = 3;
+ sbt_params.callablesRecordStrideInBytes = sizeof(SbtRecord);
// Launch the ray generation program
check_result_optix(optixLaunch(pipelines[PIP_PATH_TRACE],
@@ -1061,6 +1117,9 @@ class OptiXDevice : public CUDADevice {
# else
sbt_params.hitgroupRecordCount = 3; // PG_HITD, PG_HITS, PG_HITL
# endif
+ sbt_params.callablesRecordBase = sbt_data.device_pointer + PG_CALL * sizeof(SbtRecord);
+ sbt_params.callablesRecordCount = 3;
+ sbt_params.callablesRecordStrideInBytes = sizeof(SbtRecord);
check_result_optix(optixLaunch(pipelines[PIP_SHADER_EVAL],
cuda_stream[thread_index],
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index c39c67afb5a..f6b4b963a7a 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -423,7 +423,7 @@ if(WITH_CYCLES_CUDA_BINARIES)
set(cuda_kernel_src "/kernels/cuda/${name}.cu")
- set(cuda_flags
+ set(cuda_flags ${flags}
-D CCL_NAMESPACE_BEGIN=
-D CCL_NAMESPACE_END=
-D NVCC
@@ -545,11 +545,11 @@ endif()
# OptiX PTX modules
if(WITH_CYCLES_DEVICE_OPTIX AND WITH_CYCLES_CUDA_BINARIES)
- foreach(input ${SRC_OPTIX_KERNELS})
- get_filename_component(input_we ${input} NAME_WE)
+ macro(CYCLES_OPTIX_KERNEL_ADD name flags)
+ set(input "kernels/optix/kernel_optix.cu")
+ set(output "${CMAKE_CURRENT_BINARY_DIR}/${name}.ptx")
- set(output "${CMAKE_CURRENT_BINARY_DIR}/${input_we}.ptx")
- set(cuda_flags
+ set(cuda_flags ${flags}
-I "${OPTIX_INCLUDE_DIR}"
-I "${CMAKE_CURRENT_SOURCE_DIR}/.."
-I "${CMAKE_CURRENT_SOURCE_DIR}/kernels/cuda"
@@ -625,7 +625,10 @@ if(WITH_CYCLES_DEVICE_OPTIX AND WITH_CYCLES_CUDA_BINARIES)
list(APPEND optix_ptx ${output})
delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${output}" ${CYCLES_INSTALL_PATH}/lib)
- endforeach()
+ endmacro()
+
+ CYCLES_OPTIX_KERNEL_ADD(kernel_optix "-D __NO_SHADER_RAYTRACE__")
+ CYCLES_OPTIX_KERNEL_ADD(kernel_optix_shader_raytrace "--keep-device-functions")
add_custom_target(cycles_kernel_optix ALL DEPENDS ${optix_ptx})
cycles_set_solution_folder(cycles_kernel_optix)
diff --git a/intern/cycles/kernel/kernel_subsurface.h b/intern/cycles/kernel/kernel_subsurface.h
index ed8572467ea..917f35d37dc 100644
--- a/intern/cycles/kernel/kernel_subsurface.h
+++ b/intern/cycles/kernel/kernel_subsurface.h
@@ -281,13 +281,28 @@ ccl_device_inline int subsurface_scatter_disk(KernelGlobals *kg,
return num_eval_hits;
}
-ccl_device_noinline void subsurface_scatter_multi_setup(KernelGlobals *kg,
- LocalIntersection *ss_isect,
- int hit,
- ShaderData *sd,
- ccl_addr_space PathState *state,
- ClosureType type,
- float roughness)
+#if defined(__KERNEL_OPTIX__) && defined(__SHADER_RAYTRACE__)
+ccl_device_inline void subsurface_scatter_multi_setup(KernelGlobals *kg,
+ LocalIntersection *ss_isect,
+ int hit,
+ ShaderData *sd,
+ ccl_addr_space PathState *state,
+ ClosureType type,
+ float roughness)
+{
+ optixDirectCall<void>(2, kg, ss_isect, hit, sd, state, type, roughness);
+}
+extern "C" __device__ void __direct_callable__subsurface_scatter_multi_setup(
+#else
+ccl_device_noinline void subsurface_scatter_multi_setup(
+#endif
+ KernelGlobals *kg,
+ LocalIntersection *ss_isect,
+ int hit,
+ ShaderData *sd,
+ ccl_addr_space PathState *state,
+ ClosureType type,
+ float roughness)
{
#ifdef __SPLIT_KERNEL__
Ray ray_object = ss_isect->ray;
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 8e2b0e46a66..6beabebb92f 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -139,8 +139,6 @@ CCL_NAMESPACE_BEGIN
#ifdef __KERNEL_OPTIX__
# undef __BAKING__
# undef __BRANCHED_PATH__
-/* TODO(pmours): Cannot use optixTrace in non-inlined functions */
-# undef __SHADER_RAYTRACE__
#endif /* __KERNEL_OPTIX__ */
#ifdef __KERNEL_OPENCL__
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index f5d10c0ca8a..fdf712293e7 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -274,11 +274,24 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg,
/* get the volume attenuation over line segment defined by ray, with the
* assumption that there are no surfaces blocking light between the endpoints */
-ccl_device_noinline void kernel_volume_shadow(KernelGlobals *kg,
- ShaderData *shadow_sd,
- ccl_addr_space PathState *state,
- Ray *ray,
- float3 *throughput)
+# if defined(__KERNEL_OPTIX__) && defined(__SHADER_RAYTRACE__)
+ccl_device_inline void kernel_volume_shadow(KernelGlobals *kg,
+ ShaderData *shadow_sd,
+ ccl_addr_space PathState *state,
+ Ray *ray,
+ float3 *throughput)
+{
+ optixDirectCall<void>(1, kg, shadow_sd, state, ray, throughput);
+}
+extern "C" __device__ void __direct_callable__kernel_volume_shadow(
+# else
+ccl_device_noinline void kernel_volume_shadow(
+# endif
+ KernelGlobals *kg,
+ ShaderData *shadow_sd,
+ ccl_addr_space PathState *state,
+ Ray *ray,
+ float3 *throughput)
{
shader_setup_from_volume(kg, shadow_sd, ray);
diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h
index 44c658d4cab..59b96c86c50 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h
+++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h
@@ -18,6 +18,7 @@
#define __KERNEL_CPU_IMAGE_H__
#ifdef WITH_NANOVDB
+# define NANOVDB_USE_INTRINSICS
# include <nanovdb/NanoVDB.h>
# include <nanovdb/util/SampleFromVoxels.h>
#endif
diff --git a/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h b/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h
index 001bc652810..82ad9225fc3 100644
--- a/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h
+++ b/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h
@@ -15,6 +15,8 @@
*/
#ifdef WITH_NANOVDB
+# define NDEBUG /* Disable "assert" in device code */
+# define NANOVDB_USE_INTRINSICS
# include "nanovdb/NanoVDB.h"
# include "nanovdb/util/SampleFromVoxels.h"
#endif
diff --git a/intern/cycles/kernel/kernels/optix/kernel_optix.cu b/intern/cycles/kernel/kernels/optix/kernel_optix.cu
index fd9065098dd..8ccd2555091 100644
--- a/intern/cycles/kernel/kernels/optix/kernel_optix.cu
+++ b/intern/cycles/kernel/kernels/optix/kernel_optix.cu
@@ -118,12 +118,18 @@ extern "C" __global__ void __anyhit__kernel_optix_local_hit()
return optixIgnoreIntersection();
}
+ const uint max_hits = optixGetPayload_5();
+ if (max_hits == 0) {
+ // Special case for when no hit information is requested, just report that something was hit
+ optixSetPayload_5(true);
+ return optixTerminateRay();
+ }
+
int hit = 0;
uint *const lcg_state = get_payload_ptr_0<uint>();
LocalIntersection *const local_isect = get_payload_ptr_2<LocalIntersection>();
if (lcg_state) {
- const uint max_hits = optixGetPayload_5();
for (int i = min(max_hits, local_isect->num_hits) - 1; i >= 0; --i) {
if (optixGetRayTmax() == local_isect->hits[i].t) {
return optixIgnoreIntersection();
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 6c849f5b2fc..000da1fa615 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -217,12 +217,26 @@ CCL_NAMESPACE_END
CCL_NAMESPACE_BEGIN
/* Main Interpreter Loop */
-ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg,
- ShaderData *sd,
- ccl_addr_space PathState *state,
- ccl_global float *buffer,
- ShaderType type,
- int path_flag)
+#if defined(__KERNEL_OPTIX__) && defined(__SHADER_RAYTRACE__)
+ccl_device_inline void svm_eval_nodes(KernelGlobals *kg,
+ ShaderData *sd,
+ ccl_addr_space PathState *state,
+ ccl_global float *buffer,
+ ShaderType type,
+ int path_flag)
+{
+ optixDirectCall<void>(0, kg, sd, state, buffer, type, path_flag);
+}
+extern "C" __device__ void __direct_callable__svm_eval_nodes(
+#else
+ccl_device_noinline void svm_eval_nodes(
+#endif
+ KernelGlobals *kg,
+ ShaderData *sd,
+ ccl_addr_space PathState *state,
+ ccl_global float *buffer,
+ ShaderType type,
+ int path_flag)
{
float stack[SVM_STACK_SIZE];
int offset = sd->shader & SHADER_MASK;
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 11c8e240afd..43e664a686f 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -277,6 +277,20 @@ void Mesh::reserve_subd_creases(size_t num_creases)
subd_creases_weight.reserve(num_creases);
}
+void Mesh::clear_non_sockets()
+{
+ Geometry::clear(true);
+
+ num_subd_verts = 0;
+ num_subd_faces = 0;
+
+ vert_to_stitching_key_map.clear();
+ vert_stitching_map.clear();
+
+ delete patch_table;
+ patch_table = NULL;
+}
+
void Mesh::clear(bool preserve_shaders, bool preserve_voxel_data)
{
Geometry::clear(preserve_shaders);
@@ -297,22 +311,15 @@ void Mesh::clear(bool preserve_shaders, bool preserve_voxel_data)
subd_ptex_offset.clear();
subd_face_corners.clear();
- num_subd_verts = 0;
- num_subd_faces = 0;
-
subd_creases_edge.clear();
subd_creases_weight.clear();
subd_attributes.clear();
attributes.clear(preserve_voxel_data);
- vert_to_stitching_key_map.clear();
- vert_stitching_map.clear();
-
subdivision_type = SubdivisionType::SUBDIVISION_NONE;
- delete patch_table;
- patch_table = NULL;
+ clear_non_sockets();
}
void Mesh::clear(bool preserve_shaders)
@@ -662,7 +669,7 @@ void Mesh::add_undisplaced()
float3 *data = attr->data_float3();
/* copy verts */
- size_t size = attr->buffer_size(this, attrs.prim);
+ size_t size = attr->buffer_size(this, ATTR_PRIM_GEOMETRY);
/* Center points for ngons aren't stored in Mesh::verts but are included in size since they will
* be calculated later, we subtract them from size here so we don't have an overflow while
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index 6630dcd8a35..e2746e560da 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -205,6 +205,7 @@ class Mesh : public Geometry {
void resize_subd_faces(int numfaces, int num_ngons, int numcorners);
void reserve_subd_faces(int numfaces, int num_ngons, int numcorners);
void reserve_subd_creases(size_t num_creases);
+ void clear_non_sockets();
void clear(bool preserve_shaders = false) override;
void add_vertex(float3 P);
void add_vertex_slow(float3 P);
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index 4a2a12932fe..e8611839aea 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -142,7 +142,11 @@ if(WITH_HEADLESS OR WITH_GHOST_SDL)
list(APPEND INC_SYS
${SDL_INCLUDE_DIR}
)
- if(NOT WITH_SDL_DYNLOAD)
+ if(WITH_SDL_DYNLOAD)
+ list(APPEND LIB
+ extern_sdlew
+ )
+ else()
list(APPEND LIB
${SDL_LIBRARY}
)
diff --git a/release/datafiles/blender_logo.png b/release/datafiles/blender_logo.png
new file mode 100644
index 00000000000..17ffef7df5d
--- /dev/null
+++ b/release/datafiles/blender_logo.png
Binary files differ
diff --git a/release/datafiles/locale b/release/datafiles/locale
-Subproject ae7e6c215c9fc715cdedbc1c1e33e946fc90b49
+Subproject 9e40c01dffd3f720b23b906d20df8e999d34a4a
diff --git a/release/license/ISC.txt b/release/license/ISC.txt
deleted file mode 100644
index 5923726e458..00000000000
--- a/release/license/ISC.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-ISC License (ISC)
------------------
-
-Permission to use, copy, modify, and/or distribute this software for any purpose
-with or without fee is hereby granted, provided that the above copyright notice
-and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
diff --git a/release/lts/README.md b/release/lts/README.md
new file mode 100644
index 00000000000..8f7b6f0b87a
--- /dev/null
+++ b/release/lts/README.md
@@ -0,0 +1,41 @@
+This folder contains several scripts to smoothen the Blender LTS releases.
+
+create_download_urls.py
+=======================
+
+This python script is used to generate the download urls which we can
+copy-paste directly into the CMS of www.blender.org.
+
+Usage: create_download_urls.py --version 2.83.7
+
+Arguments:
+ --version VERSION Version string in the form of {major}.{minor}.{build}
+ (eg 2.83.7)
+
+The resulting html will be printed to the console.
+
+create_release_notes.py
+=======================
+
+This python script is used to generate the release notes which we can
+copy-paste directly into the CMS of www.blender.org and stores.
+
+Usage: ./create_release_notes.py --task=T77348 --version=2.83.7
+
+Arguments:
+ --version VERSION Version string in the form of {major}.{minor}.{build}
+ (e.g. 2.83.7)
+ --task TASK Phabricator ticket that is contains the release notes
+ information (e.g. T77348)
+ --format FORMAT Format the result in `text`, `steam`, `wiki` or `html`
+
+Requirements
+============
+
+* Python 3.8 or later
+* Python phabricator client version 0.7.0
+ https://pypi.org/project/phabricator/
+
+For convenience the python modules can be installed using pip
+
+ pip3 install -r ./requirements.txt \ No newline at end of file
diff --git a/release/lts/create_download_urls.py b/release/lts/create_download_urls.py
new file mode 100755
index 00000000000..0d0b2554d2a
--- /dev/null
+++ b/release/lts/create_download_urls.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python3
+
+import argparse
+import datetime
+
+
+DESCRIPTION = ("This python script is used to generate the download urls "
+ "which we can copy-paste directly into the CMS of "
+ "www.blender.org")
+USAGE = "create_download_urls --version=2.83.7"
+# Used date format: "September 30, 2020"
+DATE_FORMAT = "%B %d, %Y"
+
+
+class Version:
+ """
+ Version class that extracts the major, minor and build from
+ a version string
+ """
+ def __init__(self, version: str):
+ self.version = version
+ v = version.split(".")
+ self.major = v[0]
+ self.minor = v[1]
+ self.build = v[2]
+
+ def __str__(self) -> str:
+ return self.version
+
+
+def get_download_file_names(version: Version):
+ yield f"blender-{version}-linux64.tar.xz"
+ yield f"blender-{version}-macOS.dmg"
+ yield f"blender-{version}-windows64.msi"
+ yield f"blender-{version}-windows64.zip"
+
+
+def get_download_url(version: Version, file_name: str) -> str:
+ """
+ Get the download url for the given version and file_name
+ """
+ return (f"https://www.blender.org/download/Blender{version.major}"
+ f".{version.minor}/{file_name}")
+
+
+def generate_html(version: Version) -> str:
+ """
+ Generate download urls and format them into an HTML string
+ """
+ today = datetime.date.today()
+ lines = []
+ lines.append(f"Released on {today.strftime(DATE_FORMAT)}.")
+ lines.append("")
+ lines.append("<ul>")
+ for file_name in get_download_file_names(version):
+ download_url = get_download_url(version, file_name)
+ lines.append(f" <li><a href=\"{download_url}\">{file_name}</a></li>")
+ lines.append("</ul>")
+
+ return "\n".join(lines)
+
+
+def print_download_urls(version: Version):
+ """
+ Generate the download urls and print them to the console.
+ """
+ print(generate_html(version))
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(description=DESCRIPTION, usage=USAGE)
+ parser.add_argument("--version",
+ required=True,
+ help=("Version string in the form of {major}.{minor}."
+ "{build} (eg 2.83.7)"))
+ args = parser.parse_args()
+
+ print_download_urls(version=Version(args.version))
diff --git a/release/lts/create_release_notes.py b/release/lts/create_release_notes.py
new file mode 100755
index 00000000000..2a396dca6b0
--- /dev/null
+++ b/release/lts/create_release_notes.py
@@ -0,0 +1,166 @@
+#!/usr/bin/env python3
+
+import argparse
+import phabricator
+
+
+DESCRIPTION = ("This python script is used to generate the release notes "
+ "which we can copy-paste directly into the CMS of "
+ "www.blender.org and stores.")
+USAGE = "./create_release_notes.py --task=T77348 --version=2.83.7"
+
+
+class ReleaseLogLine:
+ """
+ Class containing the information of a single line of the release log
+
+ Instance attributes:
+
+ * line: (str) the original line used to create this log line
+ * task_id: (int or None) the extracted task id associated with this log
+ line. Can be None if the log line isn't associated with a task.
+ * commit_id: (str or None) the extracted commit id associated with this log
+ line. Only filled when no `task_id` could be found.
+ * ref: (str) `task_id` or `commit_id` of this line, including `T` for tasks
+ or `D` for diffs.
+ * title: (str) title of this log line. When constructed this attribute is
+ an empty string. The called needs to retrieve the title from the
+ backend.
+ * url: (str) url of the ticket task or commit.
+ """
+ def __init__(self, line: str):
+ self.line=line
+ items = line.split("|")
+ self.task_id = None
+ self.commit_id = None
+ try:
+ task_id = int(items[1].strip()[1:])
+ self.task_id = task_id
+ self.ref = f"T{self.task_id}"
+ except ValueError:
+ # no task
+ commit_string = items[3].strip()
+ commits = commit_string.split(",")
+ commit_id = commits[0]
+ commit_id = commit_id.replace("{", "").replace("}", "")
+ if not commit_id.startswith("rB"):
+ commit_id = f"rB{commit_id}"
+ self.commit_id = commit_id
+
+ self.ref = f"{self.commit_id}"
+
+ self.title = ""
+ self.url = f"https://developer.blender.org/{self.ref}"
+
+ def __format_as_html(self)-> str:
+ return f" <li>{self.title} [<a href=\"{self.url}\">{self.ref}</a>]</li>"
+
+ def __format_as_text(self) ->str:
+ return f"* {self.title} [{self.ref}]"
+
+ def __format_as_steam(self) -> str:
+ return f"* {self.title} ([url={self.url}]{self.ref}[/url])"
+
+ def __format_as_wiki(self) -> str:
+ if self.task_id:
+ return f"* {self.title} [{{{{BugReport|{self.task_id}}}}}]"
+ else:
+ return f"* {self.title} [{{{{GitCommit|{self.commit_id[2:]}}}}}]"
+
+ def format(self, format: str) -> str:
+ """
+ Format this line
+
+ :attr format: the desired format. Possible values are 'text', 'steam' or 'html'
+ :type string:
+ """
+ if format == 'html':
+ return self.__format_as_html()
+ elif format == 'steam':
+ return self.__format_as_steam()
+ elif format == 'wiki':
+ return self.__format_as_wiki()
+ else:
+ return self.__format_as_text()
+
+
+def format_title(title: str) -> str:
+ title = title.strip()
+ if not title.endswith("."):
+ title = title + "."
+ return title
+
+
+def extract_release_notes(version: str, task_id: int):
+ """
+ Extract all release notes logs
+
+ # Process
+
+ 1. Retrieval of description of the gived `task_id`.
+ 2. Find rows for the given `version` and convert to `ReleaseLogLine`.
+ 3. based on the associated task or commit retrieves the title of the log
+ line.
+ """
+ phab = phabricator.Phabricator()
+ phab.update_interfaces()
+ task = phab.maniphest.info(task_id=task_id)
+ description = task["description"]
+ lines = description.split("\n")
+ start_index = lines.index(f"## Blender {version} ##")
+ lines = lines[start_index+1:]
+ for line in lines:
+ if not line.strip():
+ continue
+ if line.startswith("| **Report**"):
+ continue
+ if line.startswith("## Blender"):
+ break
+
+ log_line = ReleaseLogLine(line)
+ if log_line.task_id:
+ issue_task = phab.maniphest.info(task_id=log_line.task_id)
+ log_line.title = format_title(issue_task.title)
+ yield log_line
+ elif log_line.commit_id:
+ commits = phab.diffusion.commit.search(constraints={"identifiers":[log_line.commit_id]})
+ commit = commits.data[0]
+ commit_message = commit['fields']['message']
+ commit_title = commit_message.split("\n")[0]
+ log_line.title = format_title(commit_title)
+ yield log_line
+
+
+def print_release_notes(version: str, format: str, task_id: int):
+ """
+ Generate and print the release notes to the console.
+ """
+ if format == 'html':
+ print("<ul>")
+ if format == 'steam':
+ print("[ul]")
+ for log_item in extract_release_notes(version=version, task_id=task_id):
+ print(log_item.format(format=format))
+ if format == 'html':
+ print("</ul>")
+ if format == 'steam':
+ print("[/ul]")
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(description=DESCRIPTION, usage=USAGE)
+ parser.add_argument(
+ "--version",
+ required=True,
+ help="Version string in the form of {major}.{minor}.{build} (e.g. 2.83.7)")
+ parser.add_argument(
+ "--task",
+ required=True,
+ help="Phabricator ticket that is contains the release notes information (e.g. T77348)")
+ parser.add_argument(
+ "--format",
+ help="Format the result in `text`, `steam`, `wiki` or `html`",
+ default="text")
+ args = parser.parse_args()
+
+ print_release_notes(version=args.version, format=args.format, task_id=int(args.task[1:]))
diff --git a/release/lts/requirements.txt b/release/lts/requirements.txt
new file mode 100644
index 00000000000..dc91ba85b01
--- /dev/null
+++ b/release/lts/requirements.txt
@@ -0,0 +1 @@
+phabricator==0.7.0 \ No newline at end of file
diff --git a/release/scripts/addons b/release/scripts/addons
-Subproject ca74197440127e56c9f6f2a277c30957f34fd07
+Subproject 1191a172ac389e3d068a8ef7d16f36457e67e3b
diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py
index e304ef5ea17..cfa4fcac17f 100644
--- a/release/scripts/modules/bl_i18n_utils/settings.py
+++ b/release/scripts/modules/bl_i18n_utils/settings.py
@@ -30,7 +30,11 @@ import os
import sys
import types
-import bpy
+try:
+ import bpy
+except ModuleNotFoundError:
+ print("Could not import bpy, some features are not available when not run from Blender.")
+ bpy = None
###############################################################################
# MISC
@@ -98,8 +102,10 @@ LANGUAGES = (
(47, "Slovak (Slovenčina)", "sk_SK"),
)
-# Default context, in py!
-DEFAULT_CONTEXT = bpy.app.translations.contexts.default
+# Default context, in py (keep in sync with `BLT_translation.h`)!
+if bpy is not None:
+ assert(bpy.app.translations.contexts.default == "*")
+DEFAULT_CONTEXT = "*"
# Name of language file used by Blender to generate translations' menu.
LANGUAGES_FILE = "languages"
diff --git a/release/scripts/modules/bl_i18n_utils/utils.py b/release/scripts/modules/bl_i18n_utils/utils.py
index 4cb25816a34..40b76b617b3 100644
--- a/release/scripts/modules/bl_i18n_utils/utils.py
+++ b/release/scripts/modules/bl_i18n_utils/utils.py
@@ -35,13 +35,8 @@ from bl_i18n_utils import (
utils_rtl,
)
-import bpy
-
##### Misc Utils #####
-from bpy.app.translations import locale_explode
-
-
_valid_po_path_re = re.compile(r"^\S+:[0-9]+$")
@@ -79,6 +74,28 @@ def get_best_similar(data):
return key, tmp
+_locale_explode_re = re.compile(r"^([a-z]{2,})(?:_([A-Z]{2,}))?(?:@([a-z]{2,}))?$")
+
+
+def locale_explode(locale):
+ """Copies behavior of `BLT_lang_locale_explode`, keep them in sync."""
+ ret = (None, None, None, None, None)
+ m = _locale_explode_re.match(locale)
+ if m:
+ lang, country, variant = m.groups()
+ return (lang, country, variant,
+ "%s_%s" % (lang, country) if country else None,
+ "%s@%s" % (lang, variant) if variant else None)
+
+ try:
+ import bpy.app.translations as bpy_translations
+ assert(ret == bpy_translations.locale_explode(locale))
+ except ModuleNotFoundError:
+ pass
+
+ return ret
+
+
def locale_match(loc1, loc2):
"""
Return:
@@ -164,6 +181,36 @@ def get_po_files_from_dir(root_dir, langs=set()):
yield uid, po_file
+def list_po_dir(root_path, settings):
+ """
+ Generator. List given directory (expecting one sub-directory per languages)
+ and return all files matching languages listed in settings.
+
+ Yield tuples (can_use, uid, num_id, name, isocode, po_path)
+
+ Note that po_path may not actually exists.
+ """
+ isocodes = ((e, os.path.join(root_path, e, e + ".po")) for e in os.listdir(root_path))
+ isocodes = dict(e for e in isocodes if os.path.isfile(e[1]))
+ for num_id, name, uid in settings.LANGUAGES[2:]: # Skip "default" and "en" languages!
+ best_po = find_best_isocode_matches(uid, isocodes)
+ #print(uid, "->", best_po)
+ if best_po:
+ isocode = best_po[0]
+ yield (True, uid, num_id, name, isocode, isocodes[isocode])
+ else:
+ yielded = False
+ language, _1, _2, language_country, language_variant = locale_explode(uid)
+ for isocode in (language, language_variant, language_country, uid):
+ p = os.path.join(root_path, isocode, isocode + ".po")
+ if not os.path.exists(p):
+ yield (True, uid, num_id, name, isocode, p)
+ yielded = True
+ break
+ if not yielded:
+ yield (False, uid, num_id, name, None, None)
+
+
def enable_addons(addons=None, support=None, disable=False, check_only=False):
"""
Enable (or disable) addons based either on a set of names, or a set of 'support' types.
@@ -172,6 +219,12 @@ def enable_addons(addons=None, support=None, disable=False, check_only=False):
"""
import addon_utils
+ try:
+ import bpy
+ except ModuleNotFoundError:
+ print("Could not import bpy, enable_addons must be run from whithin Blender.")
+ return
+
if addons is None:
addons = {}
if support is None:
@@ -725,6 +778,13 @@ class I18nMessages:
rna_ctxt: the labels' i18n context.
rna_struct_name, rna_prop_name, rna_enum_name: should be self-explanatory!
"""
+ try:
+ import bpy
+ except ModuleNotFoundError:
+ print("Could not import bpy, find_best_messages_matches must be run from whithin Blender.")
+ return
+
+
# Build helper mappings.
# Note it's user responsibility to know when to invalidate (and hence force rebuild) this cache!
if self._reverse_cache is None:
@@ -1275,7 +1335,7 @@ class I18n:
msgs.print_stats(prefix=msgs_prefix)
print(prefix)
- nbr_contexts = len(self.contexts - {bpy.app.translations.contexts.default})
+ nbr_contexts = len(self.contexts - {self.settings.DEFAULT_CONTEXT})
if nbr_contexts != 1:
if nbr_contexts == 0:
nbr_contexts = "No"
@@ -1293,7 +1353,7 @@ class I18n:
" The org msgids are currently made of {} signs.\n".format(self.nbr_signs),
" All processed translations are currently made of {} signs.\n".format(self.nbr_trans_signs),
" {} specific context{} present:\n".format(self.nbr_contexts, _ctx_txt)) +
- tuple(" " + c + "\n" for c in self.contexts - {bpy.app.translations.contexts.default}) +
+ tuple(" " + c + "\n" for c in self.contexts - {self.settings.DEFAULT_CONTEXT}) +
("\n",)
)
print(prefix.join(lines))
diff --git a/release/scripts/modules/bl_i18n_utils/utils_cli.py b/release/scripts/modules/bl_i18n_utils/utils_cli.py
new file mode 100644
index 00000000000..d38911c122d
--- /dev/null
+++ b/release/scripts/modules/bl_i18n_utils/utils_cli.py
@@ -0,0 +1,145 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+# <pep8 compliant>
+
+# Some useful operations from utils' I18nMessages class exposed as a CLI.
+
+import os
+
+if __package__ is None:
+ import settings as settings_i18n
+ import utils as utils_i18n
+ import utils_languages_menu
+else:
+ from . import settings as settings_i18n
+ from . import utils as utils_i18n
+ from . import utils_languages_menu
+
+
+def update_po(args, settings):
+ pot = utils_i18n.I18nMessages(uid=None, kind='PO', src=args.template, settings=settings)
+ if os.path.isfile(args.dst):
+ uid = os.path.splitext(os.path.basename(args.dst))[0]
+ po = utils_i18n.I18nMessages(uid=uid, kind='PO', src=args.dst, settings=settings)
+ po.update(pot)
+ else:
+ po = pot
+ po.write(kind="PO", dest=args.dst)
+
+
+def cleanup_po(args, settings):
+ uid = os.path.splitext(os.path.basename(args.src))[0]
+ if not args.dst:
+ args.dst = args.src
+ po = utils_i18n.I18nMessages(uid=uid, kind='PO', src=args.src, settings=settings)
+ po.check(fix=True)
+ po.clean_commented()
+ po.write(kind="PO", dest=args.dst)
+
+
+def strip_po(args, settings):
+ uid = os.path.splitext(os.path.basename(args.src))[0]
+ if not args.dst:
+ args.dst = args.src
+ po = utils_i18n.I18nMessages(uid=uid, kind='PO', src=args.src, settings=settings)
+ po.clean_commented()
+ po.write(kind="PO_COMPACT", dest=args.dst)
+
+
+def rtl_process_po(args, settings):
+ uid = os.path.splitext(os.path.basename(args.src))[0]
+ if not args.dst:
+ args.dst = args.src
+ po = utils_i18n.I18nMessages(uid=uid, kind='PO', src=args.src, settings=settings)
+ po.rtl_process()
+ po.write(kind="PO", dest=args.dst)
+
+
+def language_menu(args, settings):
+ # 'DEFAULT' and en_US are always valid, fully-translated "languages"!
+ stats = {"DEFAULT": 1.0, "en_US": 1.0}
+
+ po_to_uid = {os.path.basename(po_path_branch): uid
+ for can_use, uid, _num_id, _name, _isocode, po_path_branch
+ in utils_i18n.list_po_dir(settings.BRANCHES_DIR, settings)
+ if can_use}
+ for po_dir in os.listdir(settings.BRANCHES_DIR):
+ po_dir = os.path.join(settings.BRANCHES_DIR, po_dir)
+ if not os.path.isdir(po_dir):
+ continue
+ for po_path in os.listdir(po_dir):
+ uid = po_to_uid.get(po_path, None)
+ #print("Checking %s, found uid %s" % (po_path, uid))
+ po_path = os.path.join(settings.TRUNK_PO_DIR, po_path)
+ if uid is not None:
+ po = utils_i18n.I18nMessages(uid=uid, kind='PO', src=po_path, settings=settings)
+ stats[uid] = po.nbr_trans_msgs / po.nbr_msgs if po.nbr_msgs > 0 else 0
+ utils_languages_menu.gen_menu_file(stats, settings)
+
+
+def main():
+ import sys
+ import argparse
+
+ parser = argparse.ArgumentParser(description="Tool to perform common actions over PO/MO files.")
+ parser.add_argument('-s', '--settings', default=None,
+ help="Override (some) default settings. Either a JSon file name, or a JSon string.")
+ sub_parsers = parser.add_subparsers()
+
+ sub_parser = sub_parsers.add_parser('update_po', help="Update a PO file from a given POT template file")
+ sub_parser.add_argument('--template', metavar='template.pot', required=True,
+ help="The source pot file to use as template for the update.")
+ sub_parser.add_argument('--dst', metavar='dst.po', required=True, help="The destination po to update.")
+ sub_parser.set_defaults(func=update_po)
+
+ sub_parser = sub_parsers.add_parser('cleanup_po',
+ help="Cleanup a PO file (check for and fix some common errors, remove commented messages).")
+ sub_parser.add_argument('--src', metavar='src.po', required=True, help="The source po file to clean up.")
+ sub_parser.add_argument('--dst', metavar='dst.po', help="The destination po to write to.")
+ sub_parser.set_defaults(func=cleanup_po)
+
+ sub_parser = sub_parsers.add_parser('strip_po',
+ help="Reduce all non-essential data from given PO file (reduce its size).")
+ sub_parser.add_argument('--src', metavar='src.po', required=True, help="The source po file to strip.")
+ sub_parser.add_argument('--dst', metavar='dst.po', help="The destination po to write to.")
+ sub_parser.set_defaults(func=strip_po)
+
+ sub_parser = sub_parsers.add_parser('rtl_process_po',
+ help="Pre-process PO files for RTL languages.")
+ sub_parser.add_argument('--src', metavar='src.po', required=True, help="The source po file to process.")
+ sub_parser.add_argument('--dst', metavar='dst.po', help="The destination po to write to.")
+ sub_parser.set_defaults(func=rtl_process_po)
+
+ sub_parser = sub_parsers.add_parser('language_menu',
+ help="Generate the text file used by Blender to create its language menu.")
+ sub_parser.set_defaults(func=language_menu)
+
+ args = parser.parse_args(sys.argv[1:])
+
+ settings = settings_i18n.I18nSettings()
+ settings.load(args.settings)
+
+ if getattr(args, 'template', None) is not None:
+ settings.FILE_NAME_POT = args.template
+
+ args.func(args=args, settings=settings)
+
+if __name__ == "__main__":
+ print("\n\n *** Running {} *** \n".format(__file__))
+ main()
diff --git a/release/scripts/modules/bl_i18n_utils/utils_languages_menu.py b/release/scripts/modules/bl_i18n_utils/utils_languages_menu.py
index 7c98faebe9d..63981310839 100755
--- a/release/scripts/modules/bl_i18n_utils/utils_languages_menu.py
+++ b/release/scripts/modules/bl_i18n_utils/utils_languages_menu.py
@@ -40,7 +40,7 @@ def gen_menu_file(stats, settings):
# Generate languages file used by Blender's i18n system.
# First, match all entries in LANGUAGES to a lang in stats, if possible!
tmp = []
- for uid_num, label, uid, in settings.LANGUAGES:
+ for uid_num, label, uid in settings.LANGUAGES:
if uid in stats:
if uid in settings.IMPORT_LANGUAGES_SKIP:
tmp.append((stats[uid], uid_num, label, uid, FORBIDDEN))
diff --git a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
index 05985cac868..b1f72408a45 100644
--- a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
+++ b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
@@ -80,7 +80,8 @@ class SpellChecker:
"autoexecution",
"autogenerated",
"autolock",
- "automasking",
+ "automask", "automasking",
+ "automerge",
"autoname",
"autopack",
"autosave",
@@ -143,6 +144,7 @@ class SpellChecker:
"midlevel",
"midground",
"mixdown",
+ "monospaced",
"multi",
"multifractal",
"multiframe",
@@ -464,6 +466,7 @@ class SpellChecker:
"eigenvectors",
"emissive",
"equirectangular",
+ "filmlike",
"fisheye",
"framerate",
"gimbal",
@@ -642,6 +645,7 @@ class SpellChecker:
"aa", "msaa",
"ao",
"api",
+ "apic", # Affine Particle-In-Cell
"asc", "cdl",
"ascii",
"atrac",
diff --git a/release/scripts/modules/bpy/utils/__init__.py b/release/scripts/modules/bpy/utils/__init__.py
index 3ff259e0e3e..897010e80cf 100644
--- a/release/scripts/modules/bpy/utils/__init__.py
+++ b/release/scripts/modules/bpy/utils/__init__.py
@@ -26,6 +26,7 @@ not associated with blenders internal data.
__all__ = (
"blend_paths",
"escape_identifier",
+ "unescape_identifier",
"keyconfig_init",
"keyconfig_set",
"load_scripts",
@@ -60,6 +61,7 @@ from _bpy import (
_utils_units as units,
blend_paths,
escape_identifier,
+ unescape_identifier,
register_class,
resource_path,
script_paths as _bpy_script_paths,
diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py
index 8fdd66dff9f..e3158118146 100644
--- a/release/scripts/modules/rna_prop_ui.py
+++ b/release/scripts/modules/rna_prop_ui.py
@@ -49,7 +49,7 @@ def rna_idprop_ui_del(item):
def rna_idprop_quote_path(prop):
- return "[\"%s\"]" % prop.replace("\"", "\\\"")
+ return "[\"%s\"]" % bpy.utils.escape_identifier(prop)
def rna_idprop_ui_prop_update(item, prop):
diff --git a/release/scripts/presets/keyconfig/blender.py b/release/scripts/presets/keyconfig/blender.py
index d24735ba8b7..113e99fed42 100644
--- a/release/scripts/presets/keyconfig/blender.py
+++ b/release/scripts/presets/keyconfig/blender.py
@@ -168,6 +168,7 @@ class Prefs(bpy.types.KeyConfigPreferences):
def draw(self, layout):
layout.use_property_split = True
+ layout.use_property_decorate = False
is_select_left = (self.select_mouse == 'LEFT')
diff --git a/release/scripts/presets/keyconfig/blender_27x.py b/release/scripts/presets/keyconfig/blender_27x.py
index a02ac895efb..efb013b9216 100644
--- a/release/scripts/presets/keyconfig/blender_27x.py
+++ b/release/scripts/presets/keyconfig/blender_27x.py
@@ -33,11 +33,11 @@ class Prefs(bpy.types.KeyConfigPreferences):
)
def draw(self, layout):
- split = layout.split()
- col = split.column()
- col.label(text="Select With:")
- col.row().prop(self, "select_mouse", expand=True)
- split.column()
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ col = layout.column()
+ col.row().prop(self, "select_mouse", text="Select with Mouse Button", expand=True)
blender_default = bpy.utils.execfile(os.path.join(DIRNAME, "keymap_data", "blender_default.py"))
diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
index d1a595f04c8..54731c7139f 100644
--- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
+++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
@@ -447,6 +447,13 @@ def km_property_editor(params):
{"properties": [("direction", 'PREV'), ], },),
("screen.space_context_cycle", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "ctrl": True},
{"properties": [("direction", 'NEXT'), ], },),
+ ("buttons.start_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
+ ("buttons.clear_filter", {"type": 'ESC', "value": 'PRESS'}, None),
+ # Modifier panels
+ ("object.modifier_set_active", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
+ ("object.modifier_remove", {"type": 'BACK_SPACE', "value": 'PRESS'}, {"properties": [("report", True)]}),
+ ("object.modifier_remove", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("report", True)]}),
+ ("object.modifier_copy", {"type": 'D', "value": 'PRESS', "ctrl": True}, None),
])
return keymap
diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py
index ab79ebe3957..bb414b5ff89 100644
--- a/release/scripts/startup/bl_operators/anim.py
+++ b/release/scripts/startup/bl_operators/anim.py
@@ -429,9 +429,22 @@ class UpdateAnimatedTransformConstraint(Operator):
return {'FINISHED'}
+class ANIM_OT_show_group_colors_deprecated(Operator):
+ """This option moved to Preferences > Animation"""
+
+ bl_idname = "anim.show_group_colors_deprecated"
+ bl_label = "Show Group Colors"
+ bl_options = {'REGISTER'}
+
+ @classmethod
+ def poll(cls, context) -> bool:
+ return False
+
+
classes = (
ANIM_OT_keying_set_export,
NLA_OT_bake,
ClearUselessActions,
UpdateAnimatedTransformConstraint,
+ ANIM_OT_show_group_colors_deprecated,
)
diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py
index a3c54a7b069..51a9695e44a 100644
--- a/release/scripts/startup/bl_operators/clip.py
+++ b/release/scripts/startup/bl_operators/clip.py
@@ -414,8 +414,8 @@ class CLIP_OT_delete_proxy(Operator):
class CLIP_OT_set_viewport_background(Operator):
- """Set current movie clip as a camera background in 3D view-port """ \
- """(works only when a 3D view-port is visible)"""
+ """Set current movie clip as a camera background in 3D Viewport """ \
+ """(works only when a 3D Viewport is visible)"""
bl_idname = "clip.set_viewport_background"
bl_label = "Set as Background"
diff --git a/release/scripts/startup/bl_operators/image.py b/release/scripts/startup/bl_operators/image.py
index 8d543daeac7..f2cd0ad7478 100644
--- a/release/scripts/startup/bl_operators/image.py
+++ b/release/scripts/startup/bl_operators/image.py
@@ -116,7 +116,7 @@ class EditExternally(Operator):
class ProjectEdit(Operator):
- """Edit a snapshot of the view-port in an external image editor"""
+ """Edit a snapshot of the 3D Viewport in an external image editor"""
bl_idname = "image.project_edit"
bl_label = "Project Edit"
bl_options = {'REGISTER'}
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index bd1ae2ca8e1..bd1c99fdeb3 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -31,6 +31,7 @@ from bpy.props import (
IntProperty,
StringProperty,
)
+from bpy.app.translations import pgettext_iface as iface_
# FIXME, we need a way to detect key repeat events.
# unfortunately checking event previous values isn't reliable.
@@ -1146,10 +1147,11 @@ rna_default = StringProperty(
maxlen=1024,
)
-rna_property = StringProperty(
+rna_custom_property = StringProperty(
name="Property Name",
description="Property name edit",
- maxlen=1024,
+ # Match `MAX_IDPROP_NAME - 1` in Blender's source.
+ maxlen=63,
)
rna_min = FloatProperty(
@@ -1195,7 +1197,7 @@ class WM_OT_properties_edit(Operator):
bl_options = {'REGISTER', 'INTERNAL'}
data_path: rna_path
- property: rna_property
+ property: rna_custom_property
value: rna_value
default: rna_default
min: rna_min
@@ -1264,6 +1266,7 @@ class WM_OT_properties_edit(Operator):
data_path = self.data_path
prop = self.property
+ prop_escape = bpy.utils.escape_identifier(prop)
prop_old = getattr(self, "_last_prop", [None])[0]
@@ -1288,7 +1291,7 @@ class WM_OT_properties_edit(Operator):
# Reassign
item[prop] = value_eval
- item.property_overridable_library_set('["%s"]' % prop, self.is_overridable_library)
+ item.property_overridable_library_set('["%s"]' % prop_escape, self.is_overridable_library)
rna_idprop_ui_prop_update(item, prop)
self._last_prop[:] = [prop]
@@ -1321,7 +1324,7 @@ class WM_OT_properties_edit(Operator):
# If we have changed the type of the property, update its potential anim curves!
if prop_type_old != prop_type_new:
- data_path = '["%s"]' % bpy.utils.escape_identifier(prop)
+ data_path = '["%s"]' % prop_escape
done = set()
def _update(fcurves):
@@ -1363,13 +1366,16 @@ class WM_OT_properties_edit(Operator):
rna_idprop_value_item_type
)
+ prop = self.property
+ prop_escape = bpy.utils.escape_identifier(prop)
+
data_path = self.data_path
if not data_path:
self.report({'ERROR'}, "Data path not set")
return {'CANCELLED'}
- self._last_prop = [self.property]
+ self._last_prop = [prop]
item = eval("context.%s" % data_path)
@@ -1378,7 +1384,7 @@ class WM_OT_properties_edit(Operator):
return {'CANCELLED'}
# retrieve overridable static
- is_overridable = item.is_property_overridable_library('["%s"]' % self.property)
+ is_overridable = item.is_property_overridable_library('["%s"]' % prop_escape)
self.is_overridable_library = bool(is_overridable)
# default default value
@@ -1389,7 +1395,7 @@ class WM_OT_properties_edit(Operator):
self.default = ""
# setup defaults
- prop_ui = rna_idprop_ui_prop_get(item, self.property, False) # don't create
+ prop_ui = rna_idprop_ui_prop_get(item, prop, False) # don't create
if prop_ui:
self.min = prop_ui.get("min", -1000000000)
self.max = prop_ui.get("max", 1000000000)
@@ -1547,7 +1553,7 @@ class WM_OT_properties_remove(Operator):
bl_options = {'UNDO', 'INTERNAL'}
data_path: rna_path
- property: rna_property
+ property: rna_custom_property
def execute(self, context):
from rna_prop_ui import (
@@ -2642,26 +2648,28 @@ class WM_MT_splash_about(Menu):
layout = self.layout
layout.operator_context = 'EXEC_DEFAULT'
- layout.label(text="Blender is free software")
- layout.label(text="Licensed under the GNU General Public License")
- layout.separator()
- layout.separator()
-
- split = layout.split()
- split.emboss = 'PULLDOWN_MENU'
- split.scale_y = 1.3
-
- col1 = split.column()
-
- col1.operator("wm.url_open_preset", text="Release Notes", icon='URL').type = 'RELEASE_NOTES'
- col1.operator("wm.url_open_preset", text="Credits", icon='URL').type = 'CREDITS'
- col1.operator("wm.url_open", text="License", icon='URL').url = "https://www.blender.org/about/license/"
-
- col2 = split.column()
-
- col2.operator("wm.url_open_preset", text="Blender Website", icon='URL').type = 'BLENDER'
- col2.operator("wm.url_open", text="Blender Store", icon='URL').url = "https://store.blender.org"
- col2.operator("wm.url_open_preset", text="Development Fund", icon='FUND').type = 'FUND'
+ split = layout.split(factor=0.65)
+
+ col = split.column(align=True)
+ col.scale_y = 0.8
+ col.label(text=bpy.app.version_string, translate=False)
+ col.separator(factor=2.5)
+ col.label(text=iface_("Date: %s %s") % (bpy.app.build_commit_date.decode('utf-8', 'replace'),
+ bpy.app.build_commit_time.decode('utf-8', 'replace')), translate=False)
+ col.label(text=iface_("Hash: %s") % bpy.app.build_hash.decode('ascii'), translate=False)
+ col.label(text=iface_("Branch: %s") % bpy.app.build_branch.decode('utf-8', 'replace'), translate=False)
+ col.separator(factor=2.0)
+ col.label(text="Blender is free software")
+ col.label(text="Licensed under the GNU General Public License")
+
+ col = split.column(align=True)
+ col.emboss = 'PULLDOWN_MENU'
+ col.operator("wm.url_open_preset", text="Release Notes", icon='URL').type = 'RELEASE_NOTES'
+ col.operator("wm.url_open_preset", text="Credits", icon='URL').type = 'CREDITS'
+ col.operator("wm.url_open", text="License", icon='URL').url = "https://www.blender.org/about/license/"
+ col.operator("wm.url_open_preset", text="Blender Website", icon='URL').type = 'BLENDER'
+ col.operator("wm.url_open", text="Blender Store", icon='URL').url = "https://store.blender.org"
+ col.operator("wm.url_open_preset", text="Development Fund", icon='FUND').type = 'FUND'
class WM_OT_drop_blend_file(Operator):
diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py
index f46e9f9727f..71a7b056d07 100644
--- a/release/scripts/startup/bl_ui/properties_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_constraint.py
@@ -85,14 +85,23 @@ class ConstraintButtonsPanel(Panel):
row.operator("constraint.disable_keep_transform", text="", icon='CANCEL')
@staticmethod
- def space_template(layout, con, target=True, owner=True):
+ def space_template(layout, con, target=True, owner=True, separator=True):
if target or owner:
- layout.separator()
+ if separator:
+ layout.separator()
if target:
layout.prop(con, "target_space", text="Target")
if owner:
layout.prop(con, "owner_space", text="Owner")
+ if con.target_space == 'CUSTOM' or con.owner_space == 'CUSTOM':
+ col = layout.column()
+ col.prop(con, "space_object")
+ if con.space_object and con.space_object.type == 'ARMATURE':
+ col.prop_search(con, "space_subtarget", con.space_object.data, "bones", text="Bone")
+ elif con.space_object and con.space_object.type in {'MESH', 'LATTICE'}:
+ col.prop_search(con, "space_subtarget", con.space_object, "vertex_groups", text="Vertex Group")
+
@staticmethod
def target_template(layout, con, subtargets=True):
col = layout.column()
@@ -237,7 +246,7 @@ class ConstraintButtonsPanel(Panel):
row.label(icon="BLANK1")
layout.prop(con, "use_transform_limit")
- layout.prop(con, "owner_space")
+ self.space_template(layout, con, target=False, owner=True)
self.draw_influence(layout, con)
@@ -306,7 +315,7 @@ class ConstraintButtonsPanel(Panel):
row.prop_decorator(con, "max_z")
layout.prop(con, "use_transform_limit")
- layout.prop(con, "owner_space")
+ self.space_template(layout, con, target=False, owner=True)
self.draw_influence(layout, con)
@@ -375,7 +384,7 @@ class ConstraintButtonsPanel(Panel):
row.prop_decorator(con, "max_z")
layout.prop(con, "use_transform_limit")
- layout.prop(con, "owner_space")
+ self.space_template(layout, con, target=False, owner=True)
self.draw_influence(layout, con)
@@ -483,7 +492,7 @@ class ConstraintButtonsPanel(Panel):
layout.prop(con, "volume")
- layout.prop(con, "owner_space")
+ self.space_template(layout, con, target=False, owner=True)
self.draw_influence(layout, con)
@@ -1117,7 +1126,7 @@ class ConstraintButtonsSubPanel(Panel):
col = layout.column()
col.active = not con.use_eval_time
col.prop(con, "transform_channel", text="Channel")
- col.prop(con, "target_space")
+ ConstraintButtonsPanel.space_template(col, con, target=True, owner=False, separator=False)
sub = col.column(align=True)
sub.prop(con, "min", text="Range Min")
diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py
index 9ae7f8f8e6c..394e2270227 100644
--- a/release/scripts/startup/bl_ui/properties_data_curve.py
+++ b/release/scripts/startup/bl_ui/properties_data_curve.py
@@ -126,7 +126,7 @@ class DATA_PT_shape_curve(CurveButtonsPanel, Panel):
col = layout.column()
col.separator()
- sub = col.column()
+ sub = col.column(heading="Curve Deform", align=True)
sub.prop(curve, "use_radius")
sub.prop(curve, "use_stretch")
sub.prop(curve, "use_deform_bounds")
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 63ccbd2ae05..1ae1826b609 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -643,6 +643,11 @@ def brush_settings(layout, context, brush, popover=False):
layout.prop(brush, "elastic_deform_volume_preservation", slider=True)
layout.separator()
+ elif sculpt_tool == 'SNAKE_HOOK':
+ layout.separator()
+ layout.prop(brush, "snake_hook_deform_type")
+ layout.separator()
+
elif sculpt_tool == 'POSE':
layout.separator()
layout.prop(brush, "deform_target")
@@ -717,6 +722,9 @@ def brush_settings(layout, context, brush, popover=False):
row.prop(brush, "use_wet_persistence_pressure", text="")
row = layout.row(align=True)
+ row.prop(brush, "wet_paint_radius_factor")
+
+ row = layout.row(align=True)
row.prop(brush, "density")
row.prop(brush, "invert_density_pressure", text="")
row.prop(brush, "use_density_pressure", text="")
diff --git a/release/scripts/startup/bl_ui/properties_view_layer.py b/release/scripts/startup/bl_ui/properties_view_layer.py
index afa00bb50c2..27df3b10853 100644
--- a/release/scripts/startup/bl_ui/properties_view_layer.py
+++ b/release/scripts/startup/bl_ui/properties_view_layer.py
@@ -17,7 +17,16 @@
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
-from bpy.types import Panel
+from bpy.types import Panel, UIList
+
+
+class VIEWLAYER_UL_aov(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
+ row = layout.row()
+ split = row.split(factor=0.65)
+ icon = 'NONE' if item.is_valid else 'ERROR'
+ split.row().prop(item, "name", text="", icon=icon, emboss=False)
+ split.row().prop(item, "type", text="", emboss=False)
class ViewLayerButtonsPanel:
@@ -49,7 +58,7 @@ class VIEWLAYER_PT_layer(ViewLayerButtonsPanel, Panel):
col.prop(rd, "use_single_layer", text="Render Single Layer")
-class VIEWLAYER_PT_eevee_layer_passes(ViewLayerButtonsPanel, Panel):
+class VIEWLAYER_PT_layer_passes(ViewLayerButtonsPanel, Panel):
bl_label = "Passes"
COMPAT_ENGINES = {'BLENDER_EEVEE'}
@@ -59,7 +68,7 @@ class VIEWLAYER_PT_eevee_layer_passes(ViewLayerButtonsPanel, Panel):
class VIEWLAYER_PT_eevee_layer_passes_data(ViewLayerButtonsPanel, Panel):
bl_label = "Data"
- bl_parent_id = "VIEWLAYER_PT_eevee_layer_passes"
+ bl_parent_id = "VIEWLAYER_PT_layer_passes"
COMPAT_ENGINES = {'BLENDER_EEVEE'}
@@ -81,7 +90,7 @@ class VIEWLAYER_PT_eevee_layer_passes_data(ViewLayerButtonsPanel, Panel):
class VIEWLAYER_PT_eevee_layer_passes_light(ViewLayerButtonsPanel, Panel):
bl_label = "Light"
- bl_parent_id = "VIEWLAYER_PT_eevee_layer_passes"
+ bl_parent_id = "VIEWLAYER_PT_layer_passes"
COMPAT_ENGINES = {'BLENDER_EEVEE'}
def draw(self, context):
@@ -116,7 +125,7 @@ class VIEWLAYER_PT_eevee_layer_passes_light(ViewLayerButtonsPanel, Panel):
class VIEWLAYER_PT_eevee_layer_passes_effects(ViewLayerButtonsPanel, Panel):
bl_label = "Effects"
- bl_parent_id = "VIEWLAYER_PT_eevee_layer_passes"
+ bl_parent_id = "VIEWLAYER_PT_layer_passes"
COMPAT_ENGINES = {'BLENDER_EEVEE'}
def draw(self, context):
@@ -135,12 +144,70 @@ class VIEWLAYER_PT_eevee_layer_passes_effects(ViewLayerButtonsPanel, Panel):
col.active = scene_eevee.use_bloom
+class VIEWLAYER_PT_layer_passes_aov(ViewLayerButtonsPanel, Panel):
+ bl_label = "Shader AOV"
+ bl_parent_id = "VIEWLAYER_PT_layer_passes"
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ view_layer = context.view_layer
+
+ row = layout.row()
+ col = row.column()
+ col.template_list("VIEWLAYER_UL_aov", "aovs", view_layer, "aovs", view_layer, "active_aov_index", rows=2)
+
+ col = row.column()
+ sub = col.column(align=True)
+ sub.operator("scene.view_layer_add_aov", icon='ADD', text="")
+ sub.operator("scene.view_layer_remove_aov", icon='REMOVE', text="")
+
+ aov = view_layer.active_aov
+ if aov and not aov.is_valid:
+ layout.label(text="Conflicts with another render pass with the same name", icon='ERROR')
+
+
+class ViewLayerCryptomattePanel(ViewLayerButtonsPanel, Panel):
+ bl_label = "Cryptomatte"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ view_layer = context.view_layer
+
+ col = layout.column()
+ col.prop(view_layer, "use_pass_cryptomatte_object", text="Object")
+ col.prop(view_layer, "use_pass_cryptomatte_material", text="Material")
+ col.prop(view_layer, "use_pass_cryptomatte_asset", text="Asset")
+ col = layout.column()
+ col.active = any((view_layer.use_pass_cryptomatte_object,
+ view_layer.use_pass_cryptomatte_material,
+ view_layer.use_pass_cryptomatte_asset))
+ col.prop(view_layer, "pass_cryptomatte_depth", text="Levels")
+ col.prop(view_layer, "use_pass_cryptomatte_accurate", text="Accurate Mode")
+
+
+class VIEWLAYER_PT_layer_passes_cryptomatte(ViewLayerCryptomattePanel):
+ bl_parent_id = "VIEWLAYER_PT_layer_passes"
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+
classes = (
VIEWLAYER_PT_layer,
- VIEWLAYER_PT_eevee_layer_passes,
+ VIEWLAYER_PT_layer_passes,
VIEWLAYER_PT_eevee_layer_passes_data,
VIEWLAYER_PT_eevee_layer_passes_light,
VIEWLAYER_PT_eevee_layer_passes_effects,
+ VIEWLAYER_PT_layer_passes_cryptomatte,
+ VIEWLAYER_PT_layer_passes_aov,
+ VIEWLAYER_UL_aov,
)
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index 676e93f4ce9..0c222e8c023 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -347,6 +347,8 @@ class DOPESHEET_MT_view(Menu):
col.active = context.space_data.mode != 'SHAPEKEY'
col.prop(st, "show_sliders")
+ if bpy.app.version < (2, 93):
+ layout.operator("anim.show_group_colors_deprecated", icon='CHECKBOX_HLT')
layout.prop(st, "show_interpolation")
layout.prop(st, "show_extremes")
layout.prop(st, "use_auto_merge_keyframes")
diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py
index 3fee0ae9d47..6ece6a4c841 100644
--- a/release/scripts/startup/bl_ui/space_graph.py
+++ b/release/scripts/startup/bl_ui/space_graph.py
@@ -18,6 +18,7 @@
# <pep8 compliant>
+import bpy
from bpy.types import Header, Menu, Panel
from bl_ui.space_dopesheet import (
DopesheetFilterPopoverBase,
@@ -119,7 +120,10 @@ class GRAPH_MT_view(Menu):
layout.prop(st, "use_realtime_update")
layout.prop(st, "show_cursor")
layout.prop(st, "show_sliders")
- layout.prop(st, "show_group_colors")
+
+ if bpy.app.version < (2, 93):
+ layout.operator("anim.show_group_colors_deprecated", icon='CHECKBOX_HLT')
+
layout.prop(st, "use_auto_merge_keyframes")
if st.mode != 'DRIVERS':
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 53c1a136dec..761e60aef30 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -207,10 +207,14 @@ class USERPREF_PT_interface_display(InterfacePanel, CenterAlignMixIn, Panel):
col.prop(view, "ui_line_width", text="Line Width")
col.prop(view, "show_splash", text="Splash Screen")
col.prop(view, "show_developer_ui")
+
+ col.separator()
- col = layout.column(heading="Tooltips")
- col.prop(view, "show_tooltips")
- col.prop(view, "show_tooltips_python")
+ col = layout.column(heading="Tooltips", align=True)
+ col.prop(view, "show_tooltips", text = "User Tooltips")
+ sub = col.column()
+ sub.active = view.show_tooltips
+ sub.prop(view, "show_tooltips_python")
class USERPREF_PT_interface_text(InterfacePanel, CenterAlignMixIn, Panel):
@@ -2187,7 +2191,7 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel):
context, (
({"property": "use_sculpt_vertex_colors"}, "T71947"),
({"property": "use_switch_object_operator"}, "T80402"),
- ({"property": "use_sculpt_tools_tilt"}, "T00000"),
+ ({"property": "use_sculpt_tools_tilt"}, "T82877"),
({"property": "use_object_add_tool"}, "T57210"),
),
)
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 5af88e15111..10c9f25b92a 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -1828,7 +1828,13 @@ class VIEW3D_MT_paint_gpencil(Menu):
def draw(self, context):
layout = self.layout
+ layout.operator("gpencil.vertex_color_set", text="Set Vertex Colors")
layout.operator("gpencil.stroke_reset_vertex_color")
+ layout.separator()
+ layout.operator("gpencil.vertex_color_invert", text="Invert")
+ layout.operator("gpencil.vertex_color_levels", text="Levels")
+ layout.operator("gpencil.vertex_color_hsv", text="Hue Saturation Value")
+ layout.operator("gpencil.vertex_color_brightness_contrast", text="Bright/Contrast")
class VIEW3D_MT_select_gpencil(Menu):
@@ -5044,22 +5050,6 @@ class VIEW3D_MT_weight_gpencil(Menu):
layout.menu("VIEW3D_MT_gpencil_autoweights")
-class VIEW3D_MT_vertex_gpencil(Menu):
- bl_label = "Paint"
-
- def draw(self, _context):
- layout = self.layout
- layout.operator("gpencil.vertex_color_set", text="Set Vertex Colors")
- layout.separator()
- layout.operator("gpencil.vertex_color_invert", text="Invert")
- layout.operator("gpencil.vertex_color_levels", text="Levels")
- layout.operator("gpencil.vertex_color_hsv", text="Hue Saturation Value")
- layout.operator("gpencil.vertex_color_brightness_contrast", text="Bright/Contrast")
-
- layout.separator()
- layout.menu("VIEW3D_MT_join_palette")
-
-
class VIEW3D_MT_gpencil_animation(Menu):
bl_label = "Animation"
@@ -7606,7 +7596,6 @@ classes = (
VIEW3D_MT_edit_gpencil_delete,
VIEW3D_MT_edit_gpencil_showhide,
VIEW3D_MT_weight_gpencil,
- VIEW3D_MT_vertex_gpencil,
VIEW3D_MT_gpencil_animation,
VIEW3D_MT_gpencil_simplify,
VIEW3D_MT_gpencil_copy_layer,
diff --git a/release/scripts/startup/keyingsets_builtins.py b/release/scripts/startup/keyingsets_builtins.py
index 6dffeac35ce..012febc7cc7 100644
--- a/release/scripts/startup/keyingsets_builtins.py
+++ b/release/scripts/startup/keyingsets_builtins.py
@@ -520,7 +520,7 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo):
# for now, just add all of 'em
prop_rna = type(bone).bl_rna.properties.get(prop, None)
if prop_rna is None:
- prop_path = '["%s"]' % prop
+ prop_path = '["%s"]' % bpy.utils.escape_identifier(prop)
try:
rna_property = bone.path_resolve(prop_path, False)
except ValueError as ex:
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index b1789776728..abab50b95a2 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -165,11 +165,6 @@ def object_cycles_shader_nodes_poll(context):
cycles_shader_nodes_poll(context))
-def cycles_aov_node_poll(context):
- return (object_cycles_shader_nodes_poll(context) or
- world_shader_nodes_poll(context))
-
-
def object_eevee_shader_nodes_poll(context):
return (object_shader_nodes_poll(context) and
eevee_shader_nodes_poll(context))
@@ -210,7 +205,7 @@ shader_node_categories = [
ShaderNodeCategory("SH_NEW_OUTPUT", "Output", items=[
NodeItem("ShaderNodeOutputMaterial", poll=object_eevee_cycles_shader_nodes_poll),
NodeItem("ShaderNodeOutputLight", poll=object_cycles_shader_nodes_poll),
- NodeItem("ShaderNodeOutputAOV", poll=cycles_aov_node_poll),
+ NodeItem("ShaderNodeOutputAOV"),
NodeItem("ShaderNodeOutputWorld", poll=world_shader_nodes_poll),
NodeItem("ShaderNodeOutputLineStyle", poll=line_style_shader_nodes_poll),
NodeItem("NodeGroupOutput", poll=group_input_output_item_poll),
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
index 88c19355960..0ce2341fc2e 100644
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -22,7 +22,7 @@ if(WITH_LEGACY_OPENGL)
add_definitions(-DWITH_LEGACY_OPENGL)
endif()
-if(WITH_CLANG_TIDY)
+if(WITH_CLANG_TIDY AND NOT MSVC)
if(NOT CMAKE_C_COMPILER_ID MATCHES "Clang")
message(WARNING "Currently Clang-Tidy might fail with GCC toolchain, switch to Clang toolchain if that happens")
endif()
diff --git a/source/blender/blenkernel/BKE_appdir.h b/source/blender/blenkernel/BKE_appdir.h
index 3e52d7f3301..6da6079ea2a 100644
--- a/source/blender/blenkernel/BKE_appdir.h
+++ b/source/blender/blenkernel/BKE_appdir.h
@@ -26,6 +26,7 @@ extern "C" {
struct ListBase;
void BKE_appdir_init(void);
+void BKE_appdir_exit(void);
/* note on naming: typical _get() suffix is omitted here,
* since its the main purpose of the API. */
diff --git a/source/blender/blenkernel/BKE_attribute_access.hh b/source/blender/blenkernel/BKE_attribute_access.hh
index e58fba36342..c4a704ef385 100644
--- a/source/blender/blenkernel/BKE_attribute_access.hh
+++ b/source/blender/blenkernel/BKE_attribute_access.hh
@@ -23,6 +23,7 @@
#include "BKE_attribute.h"
+#include "BLI_color.hh"
#include "BLI_float3.hh"
struct Mesh;
@@ -31,6 +32,9 @@ namespace blender::bke {
using fn::CPPType;
+const CPPType *custom_data_type_to_cpp_type(const CustomDataType type);
+CustomDataType cpp_type_to_custom_data_type(const CPPType &type);
+
/**
* This class offers an indirection for reading an attribute.
* This is useful for the following reasons:
@@ -47,6 +51,7 @@ class ReadAttribute {
protected:
const AttributeDomain domain_;
const CPPType &cpp_type_;
+ const CustomDataType custom_data_type_;
const int64_t size_;
/* Protects the span below, so that no two threads initialize it at the same time. */
@@ -59,7 +64,10 @@ class ReadAttribute {
public:
ReadAttribute(AttributeDomain domain, const CPPType &cpp_type, const int64_t size)
- : domain_(domain), cpp_type_(cpp_type), size_(size)
+ : domain_(domain),
+ cpp_type_(cpp_type),
+ custom_data_type_(cpp_type_to_custom_data_type(cpp_type)),
+ size_(size)
{
}
@@ -75,6 +83,11 @@ class ReadAttribute {
return cpp_type_;
}
+ CustomDataType custom_data_type() const
+ {
+ return custom_data_type_;
+ }
+
int64_t size() const
{
return size_;
@@ -104,6 +117,7 @@ class WriteAttribute {
protected:
const AttributeDomain domain_;
const CPPType &cpp_type_;
+ const CustomDataType custom_data_type_;
const int64_t size_;
/* When not null, this points either to the attribute array or to a temporary array. */
@@ -115,7 +129,10 @@ class WriteAttribute {
public:
WriteAttribute(AttributeDomain domain, const CPPType &cpp_type, const int64_t size)
- : domain_(domain), cpp_type_(cpp_type), size_(size)
+ : domain_(domain),
+ cpp_type_(cpp_type),
+ custom_data_type_(cpp_type_to_custom_data_type(cpp_type)),
+ size_(size)
{
}
@@ -131,6 +148,11 @@ class WriteAttribute {
return cpp_type_;
}
+ CustomDataType custom_data_type() const
+ {
+ return custom_data_type_;
+ }
+
int64_t size() const
{
return size_;
@@ -246,10 +268,9 @@ template<typename T> class TypedWriteAttribute {
using FloatReadAttribute = TypedReadAttribute<float>;
using Float3ReadAttribute = TypedReadAttribute<float3>;
+using Color4fReadAttribute = TypedReadAttribute<Color4f>;
using FloatWriteAttribute = TypedWriteAttribute<float>;
using Float3WriteAttribute = TypedWriteAttribute<float3>;
-
-const CPPType *custom_data_type_to_cpp_type(const CustomDataType type);
-CustomDataType cpp_type_to_custom_data_type(const CPPType &type);
+using Color4fWriteAttribute = TypedWriteAttribute<Color4f>;
} // namespace blender::bke
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 9fa32013ba6..afb6112b954 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -39,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 4
+#define BLENDER_FILE_SUBVERSION 6
/* 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_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index e5c4535560d..7a14787c191 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -56,6 +56,8 @@ typedef struct bConstraintOb {
float matrix[4][4];
/** original matrix (before constraint solving) */
float startmat[4][4];
+ /** space matrix for custom object space */
+ float space_obj_world_matrix[4][4];
/** type of owner */
short type;
@@ -175,6 +177,9 @@ struct bConstraint *BKE_constraint_find_from_target(struct Object *ob,
struct bConstraintTarget *tgt,
struct bPoseChannel **r_pchan);
+bool BKE_constraint_is_nonlocal_in_liboverride(const struct Object *ob,
+ const struct bConstraint *con);
+
struct bConstraint *BKE_constraint_add_for_object(struct Object *ob, const char *name, short type);
struct bConstraint *BKE_constraint_add_for_pose(struct Object *ob,
struct bPoseChannel *pchan,
@@ -203,6 +208,7 @@ void BKE_constraints_clear_evalob(struct bConstraintOb *cob);
void BKE_constraint_mat_convertspace(struct Object *ob,
struct bPoseChannel *pchan,
+ struct bConstraintOb *cob,
float mat[4][4],
short from,
short to,
@@ -221,6 +227,7 @@ void BKE_constraint_targets_for_solving_get(struct Depsgraph *depsgraph,
struct bConstraintOb *ob,
struct ListBase *targets,
float ctime);
+void BKE_constraint_custom_object_space_get(float r_mat[4][4], struct bConstraint *con);
void BKE_constraints_solve(struct Depsgraph *depsgraph,
struct ListBase *conlist,
struct bConstraintOb *cob,
diff --git a/source/blender/blenkernel/BKE_cryptomatte.h b/source/blender/blenkernel/BKE_cryptomatte.h
new file mode 100644
index 00000000000..9ad4770c754
--- /dev/null
+++ b/source/blender/blenkernel/BKE_cryptomatte.h
@@ -0,0 +1,42 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#pragma once
+
+#include "BLI_sys_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Object;
+struct Material;
+
+uint32_t BKE_cryptomatte_object_hash(const struct Object *object);
+uint32_t BKE_cryptomatte_material_hash(const struct Material *material);
+uint32_t BKE_cryptomatte_asset_hash(const struct Object *object);
+float BKE_cryptomatte_hash_to_float(uint32_t cryptomatte_hash);
+
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index ef3ae3c381c..3398da9896b 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -157,6 +157,14 @@ class GeometryComponent {
const CustomDataType data_type,
const void *value) const;
+ /* Create a read-only dummy attribute that always returns the same value.
+ * The given value is converted to the correct type if necessary. */
+ blender::bke::ReadAttributePtr attribute_get_constant_for_read_converted(
+ const AttributeDomain domain,
+ const CustomDataType in_data_type,
+ const CustomDataType out_data_type,
+ const void *value) const;
+
/* Get a read-only dummy attribute that always returns the same value. */
template<typename T>
blender::bke::TypedReadAttribute<T> attribute_get_constant_for_read(const AttributeDomain domain,
diff --git a/source/blender/blenkernel/BKE_gpencil_modifier.h b/source/blender/blenkernel/BKE_gpencil_modifier.h
index 7729d2c53ab..ccf65a585ef 100644
--- a/source/blender/blenkernel/BKE_gpencil_modifier.h
+++ b/source/blender/blenkernel/BKE_gpencil_modifier.h
@@ -278,6 +278,9 @@ void BKE_gpencil_modifiers_foreach_tex_link(struct Object *ob,
GreasePencilTexWalkFunc walk,
void *userData);
+bool BKE_gpencil_modifier_is_nonlocal_in_liboverride(const struct Object *ob,
+ const struct GpencilModifierData *gmd);
+
typedef struct GpencilVirtualModifierData {
ArmatureGpencilModifierData amd;
LatticeGpencilModifierData lmd;
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 7091a060243..e5fab35891c 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -42,6 +42,7 @@ struct Depsgraph;
struct LayerCollection;
struct Main;
struct Object;
+struct RenderEngine;
struct Scene;
struct View3D;
struct ViewLayer;
@@ -444,6 +445,15 @@ bool BKE_view_layer_filter_edit_mesh_has_edges(struct Object *ob, void *user_dat
BKE_view_layer_array_from_objects_in_mode( \
view_layer, v3d, r_len, {.object_mode = mode, .no_dup_data = true})
+struct ViewLayerAOV *BKE_view_layer_add_aov(struct ViewLayer *view_layer);
+void BKE_view_layer_remove_aov(struct ViewLayer *view_layer, struct ViewLayerAOV *aov);
+void BKE_view_layer_set_active_aov(struct ViewLayer *view_layer, struct ViewLayerAOV *aov);
+void BKE_view_layer_verify_aov(struct RenderEngine *engine,
+ struct Scene *scene,
+ struct ViewLayer *view_layer);
+bool BKE_view_layer_has_valid_aov(struct ViewLayer *view_layer);
+ViewLayer *BKE_view_layer_find_with_aov(struct Scene *scene, struct ViewLayerAOV *view_layer_aov);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index b0a7d89e3d8..73e33124b43 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -431,6 +431,8 @@ bool BKE_modifier_is_non_geometrical(ModifierData *md);
bool BKE_modifier_is_enabled(const struct Scene *scene,
struct ModifierData *md,
int required_mode);
+bool BKE_modifier_is_nonlocal_in_liboverride(const struct Object *ob,
+ const struct ModifierData *md);
void BKE_modifier_set_error(const struct Object *ob,
struct ModifierData *md,
const char *format,
diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h
index 8671324fab1..16d48024d07 100644
--- a/source/blender/blenkernel/BKE_nla.h
+++ b/source/blender/blenkernel/BKE_nla.h
@@ -60,9 +60,13 @@ struct NlaTrack *BKE_nlatrack_copy(struct Main *bmain,
const int flag);
void BKE_nla_tracks_copy(struct Main *bmain, ListBase *dst, ListBase *src, const int flag);
-struct NlaTrack *BKE_nlatrack_add(struct AnimData *adt, struct NlaTrack *prev);
+struct NlaTrack *BKE_nlatrack_add(struct AnimData *adt,
+ struct NlaTrack *prev,
+ bool is_liboverride);
struct NlaStrip *BKE_nlastrip_new(struct bAction *act);
-struct NlaStrip *BKE_nlastack_add_strip(struct AnimData *adt, struct bAction *act);
+struct NlaStrip *BKE_nlastack_add_strip(struct AnimData *adt,
+ struct bAction *act,
+ const bool is_liboverride);
struct NlaStrip *BKE_nla_add_soundstrip(struct Main *bmain,
struct Scene *scene,
struct Speaker *speaker);
@@ -95,10 +99,14 @@ void BKE_nlatrack_solo_toggle(struct AnimData *adt, struct NlaTrack *nlt);
bool BKE_nlatrack_has_space(struct NlaTrack *nlt, float start, float end);
void BKE_nlatrack_sort_strips(struct NlaTrack *nlt);
-bool BKE_nlatrack_add_strip(struct NlaTrack *nlt, struct NlaStrip *strip);
+bool BKE_nlatrack_add_strip(struct NlaTrack *nlt,
+ struct NlaStrip *strip,
+ const bool is_liboverride);
bool BKE_nlatrack_get_bounds(struct NlaTrack *nlt, float bounds[2]);
+bool BKE_nlatrack_is_nonlocal_in_liboverride(const struct ID *id, const struct NlaTrack *nlt);
+
/* ............ */
struct NlaStrip *BKE_nlastrip_find_active(struct NlaTrack *nlt);
@@ -124,11 +132,11 @@ void BKE_nla_validate_state(struct AnimData *adt);
/* ............ */
bool BKE_nla_action_is_stashed(struct AnimData *adt, struct bAction *act);
-bool BKE_nla_action_stash(struct AnimData *adt);
+bool BKE_nla_action_stash(struct AnimData *adt, const bool is_liboverride);
/* ............ */
-void BKE_nla_action_pushdown(struct AnimData *adt);
+void BKE_nla_action_pushdown(struct AnimData *adt, const bool is_liboverride);
bool BKE_nla_tweakmode_enter(struct AnimData *adt);
void BKE_nla_tweakmode_exit(struct AnimData *adt);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 1a90d6fadd3..c962f0a6a8c 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -101,6 +101,7 @@ set(SRC
intern/constraint.c
intern/context.c
intern/crazyspace.c
+ intern/cryptomatte.c
intern/curve.c
intern/curve_bevel.c
intern/curve_decimate.c
@@ -726,6 +727,7 @@ if(WITH_GTESTS)
intern/fcurve_test.cc
intern/lattice_deform_test.cc
intern/tracking_test.cc
+ intern/layer_test.cc
)
set(TEST_INC
../editors/include
diff --git a/source/blender/blenkernel/intern/anim_data.c b/source/blender/blenkernel/intern/anim_data.c
index a85509b11db..13abfa92032 100644
--- a/source/blender/blenkernel/intern/anim_data.c
+++ b/source/blender/blenkernel/intern/anim_data.c
@@ -989,8 +989,8 @@ char *BKE_animsys_fix_rna_path_rename(ID *owner_id,
char *name_old_esc = BLI_array_alloca(name_old_esc, (name_old_len * 2) + 1);
char *name_new_esc = BLI_array_alloca(name_new_esc, (name_new_len * 2) + 1);
- BLI_strescape(name_old_esc, oldName, (name_old_len * 2) + 1);
- BLI_strescape(name_new_esc, newName, (name_new_len * 2) + 1);
+ BLI_str_escape(name_old_esc, oldName, (name_old_len * 2) + 1);
+ BLI_str_escape(name_new_esc, newName, (name_new_len * 2) + 1);
oldN = BLI_sprintfN("[\"%s\"]", name_old_esc);
newN = BLI_sprintfN("[\"%s\"]", name_new_esc);
}
@@ -1048,8 +1048,8 @@ void BKE_action_fix_paths_rename(ID *owner_id,
char *name_old_esc = BLI_array_alloca(name_old_esc, (name_old_len * 2) + 1);
char *name_new_esc = BLI_array_alloca(name_new_esc, (name_new_len * 2) + 1);
- BLI_strescape(name_old_esc, oldName, (name_old_len * 2) + 1);
- BLI_strescape(name_new_esc, newName, (name_new_len * 2) + 1);
+ BLI_str_escape(name_old_esc, oldName, (name_old_len * 2) + 1);
+ BLI_str_escape(name_new_esc, newName, (name_new_len * 2) + 1);
oldN = BLI_sprintfN("[\"%s\"]", name_old_esc);
newN = BLI_sprintfN("[\"%s\"]", name_new_esc);
}
@@ -1096,8 +1096,8 @@ void BKE_animdata_fix_paths_rename(ID *owner_id,
char *name_old_esc = BLI_array_alloca(name_old_esc, (name_old_len * 2) + 1);
char *name_new_esc = BLI_array_alloca(name_new_esc, (name_new_len * 2) + 1);
- BLI_strescape(name_old_esc, oldName, (name_old_len * 2) + 1);
- BLI_strescape(name_new_esc, newName, (name_new_len * 2) + 1);
+ BLI_str_escape(name_old_esc, oldName, (name_old_len * 2) + 1);
+ BLI_str_escape(name_new_esc, newName, (name_new_len * 2) + 1);
oldN = BLI_sprintfN("[\"%s\"]", name_old_esc);
newN = BLI_sprintfN("[\"%s\"]", name_new_esc);
}
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
index 2038079744d..b1462167edd 100644
--- a/source/blender/blenkernel/intern/appdir.c
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -114,6 +114,14 @@ void BKE_appdir_init(void)
#endif
}
+void BKE_appdir_exit(void)
+{
+#ifndef NDEBUG
+ BLI_assert(is_appdir_init == true);
+ is_appdir_init = false;
+#endif
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 2345c834be4..d79168d5443 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -325,7 +325,7 @@ class ConstantReadAttribute final : public ReadAttribute {
type.copy_to_uninitialized(value, value_);
}
- ~ConstantReadAttribute()
+ ~ConstantReadAttribute() override
{
this->cpp_type_.destruct(value_);
MEM_freeN(value_);
@@ -668,6 +668,39 @@ blender::bke::ReadAttributePtr GeometryComponent::attribute_get_constant_for_rea
domain, domain_size, *cpp_type, value);
}
+blender::bke::ReadAttributePtr GeometryComponent::attribute_get_constant_for_read_converted(
+ const AttributeDomain domain,
+ const CustomDataType in_data_type,
+ const CustomDataType out_data_type,
+ const void *value) const
+{
+ BLI_assert(this->attribute_domain_supported(domain));
+ if (value == nullptr || in_data_type == out_data_type) {
+ return this->attribute_get_constant_for_read(domain, out_data_type, value);
+ }
+
+ const blender::fn::CPPType *in_cpp_type = blender::bke::custom_data_type_to_cpp_type(
+ in_data_type);
+ const blender::fn::CPPType *out_cpp_type = blender::bke::custom_data_type_to_cpp_type(
+ out_data_type);
+ BLI_assert(in_cpp_type != nullptr);
+ BLI_assert(out_cpp_type != nullptr);
+
+ const blender::nodes::DataTypeConversions &conversions =
+ blender::nodes::get_implicit_type_conversions();
+ BLI_assert(conversions.is_convertible(*in_cpp_type, *out_cpp_type));
+
+ void *out_value = alloca(out_cpp_type->size());
+ conversions.convert(*in_cpp_type, *out_cpp_type, value, out_value);
+
+ const int domain_size = this->attribute_domain_size(domain);
+ blender::bke::ReadAttributePtr attribute = std::make_unique<blender::bke::ConstantReadAttribute>(
+ domain, domain_size, *out_cpp_type, out_value);
+
+ out_cpp_type->destruct(out_value);
+ return attribute;
+}
+
WriteAttributePtr GeometryComponent::attribute_try_ensure_for_write(const StringRef attribute_name,
const AttributeDomain domain,
const CustomDataType data_type)
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 1b77989c2b8..96791aed2c3 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -446,6 +446,7 @@ static void brush_defaults(Brush *brush)
FROM_DEFAULT(topology_rake_factor);
FROM_DEFAULT(crease_pinch_factor);
FROM_DEFAULT(normal_radius_factor);
+ FROM_DEFAULT(wet_paint_radius_factor);
FROM_DEFAULT(area_radius_factor);
FROM_DEFAULT(disconnected_distance_max);
FROM_DEFAULT(sculpt_plane);
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 5497065bb34..1c17692ac36 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -261,8 +261,13 @@ void BKE_constraints_clear_evalob(bConstraintOb *cob)
* of a matrix from one space to another for constraint evaluation.
* For now, this is only implemented for Objects and PoseChannels.
*/
-void BKE_constraint_mat_convertspace(
- Object *ob, bPoseChannel *pchan, float mat[4][4], short from, short to, const bool keep_scale)
+void BKE_constraint_mat_convertspace(Object *ob,
+ bPoseChannel *pchan,
+ bConstraintOb *cob,
+ float mat[4][4],
+ short from,
+ short to,
+ const bool keep_scale)
{
float diff_mat[4][4];
float imat[4][4];
@@ -282,25 +287,30 @@ void BKE_constraint_mat_convertspace(
switch (from) {
case CONSTRAINT_SPACE_WORLD: /* ---------- FROM WORLDSPACE ---------- */
{
- /* world to pose */
- invert_m4_m4(imat, ob->obmat);
- mul_m4_m4m4(mat, imat, mat);
-
- /* use pose-space as stepping stone for other spaces... */
- if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
- /* call self with slightly different values */
- BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
+ if (to == CONSTRAINT_SPACE_CUSTOM) {
+ /* World to custom. */
+ BLI_assert(cob);
+ invert_m4_m4(imat, cob->space_obj_world_matrix);
+ mul_m4_m4m4(mat, imat, mat);
+ }
+ else {
+ /* World to pose. */
+ invert_m4_m4(imat, ob->obmat);
+ mul_m4_m4m4(mat, imat, mat);
+
+ /* Use pose-space as stepping stone for other spaces. */
+ if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
+ /* Call self with slightly different values. */
+ BKE_constraint_mat_convertspace(
+ ob, pchan, cob, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
+ }
}
break;
}
case CONSTRAINT_SPACE_POSE: /* ---------- FROM POSESPACE ---------- */
{
- /* pose to world */
- if (to == CONSTRAINT_SPACE_WORLD) {
- mul_m4_m4m4(mat, ob->obmat, mat);
- }
/* pose to local */
- else if (to == CONSTRAINT_SPACE_LOCAL) {
+ if (to == CONSTRAINT_SPACE_LOCAL) {
if (pchan->bone) {
BKE_armature_mat_pose_to_bone(pchan, mat, mat);
}
@@ -312,6 +322,16 @@ void BKE_constraint_mat_convertspace(
mul_m4_m4m4(mat, imat, mat);
}
}
+ else {
+ /* Pose to world. */
+ mul_m4_m4m4(mat, ob->obmat, mat);
+ /* Use world-space as stepping stone for other spaces. */
+ if (to != CONSTRAINT_SPACE_WORLD) {
+ /* Call self with slightly different values. */
+ BKE_constraint_mat_convertspace(
+ ob, pchan, cob, mat, CONSTRAINT_SPACE_WORLD, to, keep_scale);
+ }
+ }
break;
}
case CONSTRAINT_SPACE_LOCAL: /* ------------ FROM LOCALSPACE --------- */
@@ -323,9 +343,10 @@ void BKE_constraint_mat_convertspace(
}
/* use pose-space as stepping stone for other spaces */
- if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL)) {
+ if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL, CONSTRAINT_SPACE_CUSTOM)) {
/* call self with slightly different values */
- BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
+ BKE_constraint_mat_convertspace(
+ ob, pchan, cob, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
}
break;
}
@@ -337,9 +358,24 @@ void BKE_constraint_mat_convertspace(
}
/* use pose-space as stepping stone for other spaces */
- if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL)) {
+ if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_CUSTOM)) {
/* call self with slightly different values */
- BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
+ BKE_constraint_mat_convertspace(
+ ob, pchan, cob, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
+ }
+ break;
+ }
+ case CONSTRAINT_SPACE_CUSTOM: /* -------------- FROM CUSTOM SPACE ---------- */
+ {
+ /* Custom to world. */
+ BLI_assert(cob);
+ mul_m4_m4m4(mat, cob->space_obj_world_matrix, mat);
+
+ /* Use world-space as stepping stone for other spaces. */
+ if (to != CONSTRAINT_SPACE_WORLD) {
+ /* Call self with slightly different values. */
+ BKE_constraint_mat_convertspace(
+ ob, pchan, cob, mat, CONSTRAINT_SPACE_WORLD, to, keep_scale);
}
break;
}
@@ -347,37 +383,44 @@ void BKE_constraint_mat_convertspace(
}
else {
/* objects */
- if (from == CONSTRAINT_SPACE_WORLD && to == CONSTRAINT_SPACE_LOCAL) {
- /* check if object has a parent */
- if (ob->parent) {
- /* 'subtract' parent's effects from owner */
- mul_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv);
- invert_m4_m4_safe(imat, diff_mat);
- mul_m4_m4m4(mat, imat, mat);
- }
- else {
- /* Local space in this case will have to be defined as local to the owner's
- * transform-property-rotated axes. So subtract this rotation component.
- */
- /* XXX This is actually an ugly hack, local space of a parent-less object *is* the same as
- * global space!
- * Think what we want actually here is some kind of 'Final Space', i.e
- * . once transformations are applied - users are often confused about this too,
- * this is not consistent with bones
- * local space either... Meh :|
- * --mont29
- */
- BKE_object_to_mat4(ob, diff_mat);
- if (!keep_scale) {
- normalize_m4(diff_mat);
+ if (from == CONSTRAINT_SPACE_WORLD) {
+ if (to == CONSTRAINT_SPACE_LOCAL) {
+ /* Check if object has a parent. */
+ if (ob->parent) {
+ /* 'subtract' parent's effects from owner. */
+ mul_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv);
+ invert_m4_m4_safe(imat, diff_mat);
+ mul_m4_m4m4(mat, imat, mat);
}
- zero_v3(diff_mat[3]);
+ else {
+ /* Local space in this case will have to be defined as local to the owner's
+ * transform-property-rotated axes. So subtract this rotation component.
+ */
+ /* XXX This is actually an ugly hack, local space of a parent-less object *is* the same
+ * as global space! Think what we want actually here is some kind of 'Final Space', i.e
+ * . once transformations are applied - users are often confused about this too,
+ * this is not consistent with bones
+ * local space either... Meh :|
+ * --mont29
+ */
+ BKE_object_to_mat4(ob, diff_mat);
+ if (!keep_scale) {
+ normalize_m4(diff_mat);
+ }
+ zero_v3(diff_mat[3]);
- invert_m4_m4_safe(imat, diff_mat);
+ invert_m4_m4_safe(imat, diff_mat);
+ mul_m4_m4m4(mat, imat, mat);
+ }
+ }
+ else if (to == CONSTRAINT_SPACE_CUSTOM) {
+ /* 'subtract' custom objects's effects from owner. */
+ BLI_assert(cob);
+ invert_m4_m4_safe(imat, cob->space_obj_world_matrix);
mul_m4_m4m4(mat, imat, mat);
}
}
- else if (from == CONSTRAINT_SPACE_LOCAL && to == CONSTRAINT_SPACE_WORLD) {
+ else if (from == CONSTRAINT_SPACE_LOCAL) {
/* check that object has a parent - otherwise this won't work */
if (ob->parent) {
/* 'add' parent's effect back to owner */
@@ -397,6 +440,24 @@ void BKE_constraint_mat_convertspace(
mul_m4_m4m4(mat, diff_mat, mat);
}
+ if (to == CONSTRAINT_SPACE_CUSTOM) {
+ /* 'subtract' objects's effects from owner. */
+ BLI_assert(cob);
+ invert_m4_m4_safe(imat, cob->space_obj_world_matrix);
+ mul_m4_m4m4(mat, imat, mat);
+ }
+ }
+ else if (from == CONSTRAINT_SPACE_CUSTOM) {
+ /* Custom to world. */
+ BLI_assert(cob);
+ mul_m4_m4m4(mat, cob->space_obj_world_matrix, mat);
+
+ /* Use world-space as stepping stone for other spaces. */
+ if (to != CONSTRAINT_SPACE_WORLD) {
+ /* Call self with slightly different values. */
+ BKE_constraint_mat_convertspace(
+ ob, pchan, cob, mat, CONSTRAINT_SPACE_WORLD, to, keep_scale);
+ }
}
}
}
@@ -573,6 +634,7 @@ static void contarget_get_lattice_mat(Object *ob, const char *substring, float m
/* The cases where the target can be object data have not been implemented */
static void constraint_target_to_mat4(Object *ob,
const char *substring,
+ bConstraintOb *cob,
float mat[4][4],
short from,
short to,
@@ -582,7 +644,7 @@ static void constraint_target_to_mat4(Object *ob,
/* Case OBJECT */
if (substring[0] == '\0') {
copy_m4_m4(mat, ob->obmat);
- BKE_constraint_mat_convertspace(ob, NULL, mat, from, to, false);
+ BKE_constraint_mat_convertspace(ob, NULL, cob, mat, from, to, false);
}
/* Case VERTEXGROUP */
/* Current method just takes the average location of all the points in the
@@ -595,11 +657,11 @@ static void constraint_target_to_mat4(Object *ob,
*/
else if (ob->type == OB_MESH) {
contarget_get_mesh_mat(ob, substring, mat);
- BKE_constraint_mat_convertspace(ob, NULL, mat, from, to, false);
+ BKE_constraint_mat_convertspace(ob, NULL, cob, mat, from, to, false);
}
else if (ob->type == OB_LATTICE) {
contarget_get_lattice_mat(ob, substring, mat);
- BKE_constraint_mat_convertspace(ob, NULL, mat, from, to, false);
+ BKE_constraint_mat_convertspace(ob, NULL, cob, mat, from, to, false);
}
/* Case BONE */
else {
@@ -662,7 +724,7 @@ static void constraint_target_to_mat4(Object *ob,
}
/* convert matrix space as required */
- BKE_constraint_mat_convertspace(ob, pchan, mat, from, to, false);
+ BKE_constraint_mat_convertspace(ob, pchan, cob, mat, from, to, false);
}
}
@@ -705,13 +767,14 @@ static bConstraintTypeInfo CTI_CONSTRNAME = {
*/
static void default_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
bConstraint *con,
- bConstraintOb *UNUSED(cob),
+ bConstraintOb *cob,
bConstraintTarget *ct,
float UNUSED(ctime))
{
if (VALID_CONS_TARGET(ct)) {
constraint_target_to_mat4(ct->tar,
ct->subtarget,
+ cob,
ct->matrix,
CONSTRAINT_SPACE_WORLD,
ct->space,
@@ -727,13 +790,14 @@ static void default_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
*/
static void default_get_tarmat_full_bbone(struct Depsgraph *UNUSED(depsgraph),
bConstraint *con,
- bConstraintOb *UNUSED(cob),
+ bConstraintOb *cob,
bConstraintTarget *ct,
float UNUSED(ctime))
{
if (VALID_CONS_TARGET(ct)) {
constraint_target_to_mat4(ct->tar,
ct->subtarget,
+ cob,
ct->matrix,
CONSTRAINT_SPACE_WORLD,
ct->space,
@@ -844,6 +908,32 @@ 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)
+{
+ 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);
+}
+
/* --------- ChildOf Constraint ------------ */
static void childof_new_data(void *cdata)
@@ -1030,6 +1120,8 @@ 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)
@@ -1041,7 +1133,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;
+ return 1 + get_space_tar(con, list);
}
return 0;
@@ -1055,6 +1147,7 @@ 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);
}
}
@@ -1262,6 +1355,7 @@ static void kinematic_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
if (VALID_CONS_TARGET(ct)) {
constraint_target_to_mat4(ct->tar,
ct->subtarget,
+ cob,
ct->matrix,
CONSTRAINT_SPACE_WORLD,
ct->space,
@@ -1533,11 +1627,11 @@ static bConstraintTypeInfo CTI_LOCLIMIT = {
"Limit Location", /* name */
"bLocLimitConstraint", /* struct name */
NULL, /* free data */
- NULL, /* id looper */
+ custom_space_id_looper, /* id looper */
NULL, /* copy data */
NULL, /* new data */
- NULL, /* get constraint targets */
- NULL, /* flush constraint targets */
+ get_space_tar, /* get constraint targets */
+ flush_space_tar, /* flush constraint targets */
NULL, /* get target matrix */
loclimit_evaluate, /* evaluate */
};
@@ -1596,11 +1690,11 @@ static bConstraintTypeInfo CTI_ROTLIMIT = {
"Limit Rotation", /* name */
"bRotLimitConstraint", /* struct name */
NULL, /* free data */
- NULL, /* id looper */
+ custom_space_id_looper, /* id looper */
NULL, /* copy data */
NULL, /* new data */
- NULL, /* get constraint targets */
- NULL, /* flush constraint targets */
+ get_space_tar, /* get constraint targets */
+ flush_space_tar, /* flush constraint targets */
NULL, /* get target matrix */
rotlimit_evaluate, /* evaluate */
};
@@ -1663,11 +1757,11 @@ static bConstraintTypeInfo CTI_SIZELIMIT = {
"Limit Scale", /* name */
"bSizeLimitConstraint", /* struct name */
NULL, /* free data */
- NULL, /* id looper */
+ custom_space_id_looper, /* id looper */
NULL, /* copy data */
NULL, /* new data */
- NULL, /* get constraint targets */
- NULL, /* flush constraint targets */
+ get_space_tar, /* get constraint targets */
+ flush_space_tar, /* flush constraint targets */
NULL, /* get target matrix */
sizelimit_evaluate, /* evaluate */
};
@@ -1687,6 +1781,8 @@ 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)
@@ -1698,7 +1794,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;
+ return 1 + get_space_tar(con, list);
}
return 0;
@@ -1712,6 +1808,7 @@ 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);
}
}
@@ -1784,6 +1881,8 @@ 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)
@@ -1795,7 +1894,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;
+ return 1 + get_space_tar(con, list);
}
return 0;
@@ -1809,6 +1908,7 @@ 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);
}
}
@@ -1962,6 +2062,8 @@ 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)
@@ -1973,7 +2075,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;
+ return 1 + get_space_tar(con, list);
}
return 0;
@@ -1987,6 +2089,7 @@ 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);
}
}
@@ -2084,6 +2187,8 @@ 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)
@@ -2095,7 +2200,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;
+ return 1 + get_space_tar(con, list);
}
return 0;
@@ -2109,6 +2214,7 @@ 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);
}
}
@@ -2212,11 +2318,11 @@ static bConstraintTypeInfo CTI_SAMEVOL = {
"Maintain Volume", /* name */
"bSameVolumeConstraint", /* struct name */
NULL, /* free data */
- NULL, /* id looper */
+ custom_space_id_looper, /* id looper */
NULL, /* copy data */
samevolume_new_data, /* new data */
- NULL, /* get constraint targets */
- NULL, /* flush constraint targets */
+ get_space_tar, /* get constraint targets */
+ flush_space_tar, /* flush constraint targets */
NULL, /* get target matrix */
samevolume_evaluate, /* evaluate */
};
@@ -2282,7 +2388,7 @@ static void pycon_id_looper(bConstraint *con, ConstraintIDFunc func, void *userd
/* Whether this approach is maintained remains to be seen (aligorith) */
static void pycon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
bConstraint *con,
- bConstraintOb *UNUSED(cob),
+ bConstraintOb *cob,
bConstraintTarget *ct,
float UNUSED(ctime))
{
@@ -2301,6 +2407,7 @@ static void pycon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
*/
constraint_target_to_mat4(ct->tar,
ct->subtarget,
+ cob,
ct->matrix,
CONSTRAINT_SPACE_WORLD,
ct->space,
@@ -2608,6 +2715,8 @@ 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)
@@ -2619,7 +2728,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;
+ return 1 + get_space_tar(con, list);
}
return 0;
@@ -2633,6 +2742,7 @@ 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);
}
}
@@ -2660,6 +2770,7 @@ static void actcon_get_tarmat(struct Depsgraph *depsgraph,
/* get the transform matrix of the target */
constraint_target_to_mat4(ct->tar,
ct->subtarget,
+ cob,
tempmat,
CONSTRAINT_SPACE_WORLD,
ct->space,
@@ -3117,6 +3228,8 @@ 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)
@@ -3128,7 +3241,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;
+ return 1 + get_space_tar(con, list);
}
return 0;
@@ -3142,6 +3255,7 @@ 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);
}
}
@@ -3470,6 +3584,8 @@ 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)
@@ -3481,7 +3597,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;
+ return 1 + get_space_tar(con, list);
}
return 0;
@@ -3495,6 +3611,7 @@ 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);
}
}
@@ -3789,6 +3906,8 @@ 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)
@@ -3800,7 +3919,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;
+ return 1 + get_space_tar(con, list);
}
return 0;
@@ -3814,6 +3933,7 @@ 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);
}
}
@@ -4122,7 +4242,7 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
* See T42447. */
unit_m4(mat);
BKE_constraint_mat_convertspace(
- cob->ob, cob->pchan, mat, CONSTRAINT_SPACE_LOCAL, scon->projAxisSpace, true);
+ cob->ob, cob->pchan, cob, mat, CONSTRAINT_SPACE_LOCAL, scon->projAxisSpace, true);
invert_m4(mat);
mul_mat3_m4_v3(mat, no);
@@ -5634,6 +5754,7 @@ bConstraint *BKE_constraint_duplicate_ex(bConstraint *src, const int flag, const
bConstraint *dst = MEM_dupallocN(src);
constraint_copy_data_ex(dst, src, flag, do_extern);
dst->next = dst->prev = NULL;
+ dst->flag |= CONSTRAINT_OVERRIDE_LIBRARY_LOCAL;
return dst;
}
@@ -5668,6 +5789,7 @@ void BKE_constraints_copy_ex(ListBase *dst, const ListBase *src, const int flag,
for (con = dst->first, srccon = src->first; con && srccon;
srccon = srccon->next, con = con->next) {
constraint_copy_data_ex(con, srccon, flag, do_extern);
+ con->flag |= CONSTRAINT_OVERRIDE_LIBRARY_LOCAL;
}
}
@@ -5834,6 +5956,18 @@ static bConstraint *constraint_find_original_for_update(bConstraintOb *cob, bCon
return orig_con;
}
+/**
+ * Check whether given constraint is not local (i.e. from linked data) when the object is a library
+ * override.
+ *
+ * \param con May be NULL, in which case we consider it as a non-local constraint case.
+ */
+bool BKE_constraint_is_nonlocal_in_liboverride(const Object *ob, const bConstraint *con)
+{
+ return (ID_IS_OVERRIDE_LIBRARY(ob) &&
+ (con == NULL || (con->flag & CONSTRAINT_OVERRIDE_LIBRARY_LOCAL) == 0));
+}
+
/* -------- Constraints and Proxies ------- */
/* Rescue all constraints tagged as being CONSTRAINT_PROXY_LOCAL
@@ -6000,6 +6134,35 @@ void BKE_constraint_targets_for_solving_get(struct Depsgraph *depsgraph,
}
}
+void BKE_constraint_custom_object_space_get(float r_mat[4][4], bConstraint *con)
+{
+ if (!con ||
+ (con->ownspace != CONSTRAINT_SPACE_CUSTOM && con->tarspace != CONSTRAINT_SPACE_CUSTOM)) {
+ return;
+ }
+ bConstraintTarget *ct;
+ ListBase target = {NULL, NULL};
+ SINGLETARGET_GET_TARS(con, con->space_object, con->space_subtarget, ct, &target);
+
+ /* Basically default_get_tarmat but without the unused parameters. */
+ if (VALID_CONS_TARGET(ct)) {
+ constraint_target_to_mat4(ct->tar,
+ ct->subtarget,
+ NULL,
+ ct->matrix,
+ CONSTRAINT_SPACE_WORLD,
+ CONSTRAINT_SPACE_WORLD,
+ 0,
+ 0);
+ copy_m4_m4(r_mat, ct->matrix);
+ }
+ else {
+ unit_m4(r_mat);
+ }
+
+ SINGLETARGET_FLUSH_TARS(con, con->space_object, con->space_subtarget, ct, &target, true);
+}
+
/* ---------- Evaluation ----------- */
/* This function is called whenever constraints need to be evaluated. Currently, all
@@ -6048,12 +6211,15 @@ void BKE_constraints_solve(struct Depsgraph *depsgraph,
*/
enf = con->enforce;
+ /* Get custom space matrix. */
+ BKE_constraint_custom_object_space_get(cob->space_obj_world_matrix, con);
+
/* make copy of world-space matrix pre-constraint for use with blending later */
copy_m4_m4(oldmat, cob->matrix);
/* move owner matrix into right space */
BKE_constraint_mat_convertspace(
- cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace, false);
+ cob->ob, cob->pchan, cob, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace, false);
/* prepare targets for constraint solving */
BKE_constraint_targets_for_solving_get(depsgraph, con, cob, &targets, ctime);
@@ -6072,7 +6238,7 @@ void BKE_constraints_solve(struct Depsgraph *depsgraph,
/* move owner back into world-space for next constraint/other business */
if ((con->flag & CONSTRAINT_SPACEONCE) == 0) {
BKE_constraint_mat_convertspace(
- cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD, false);
+ cob->ob, cob->pchan, cob, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD, false);
}
/* Interpolate the enforcement, to blend result of constraint into final owner transform
diff --git a/source/blender/blenkernel/intern/cryptomatte.c b/source/blender/blenkernel/intern/cryptomatte.c
new file mode 100644
index 00000000000..6570ffce920
--- /dev/null
+++ b/source/blender/blenkernel/intern/cryptomatte.c
@@ -0,0 +1,87 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "BKE_cryptomatte.h"
+
+#include "DNA_material_types.h"
+#include "DNA_object_types.h"
+
+#include "BLI_compiler_attrs.h"
+#include "BLI_hash_mm3.h"
+#include "BLI_string.h"
+#include <string.h>
+
+static uint32_t cryptomatte_hash(const ID *id)
+{
+ const char *name = &id->name[2];
+ const int len = BLI_strnlen(name, MAX_NAME - 2);
+ uint32_t cryptohash_int = BLI_hash_mm3((const unsigned char *)name, len, 0);
+ return cryptohash_int;
+}
+
+uint32_t BKE_cryptomatte_object_hash(const Object *object)
+{
+ return cryptomatte_hash(&object->id);
+}
+
+uint32_t BKE_cryptomatte_material_hash(const Material *material)
+{
+ if (material == NULL) {
+ return 0.0f;
+ }
+ return cryptomatte_hash(&material->id);
+}
+
+uint32_t BKE_cryptomatte_asset_hash(const Object *object)
+{
+ const Object *asset_object = object;
+ while (asset_object->parent != NULL) {
+ asset_object = asset_object->parent;
+ }
+ return cryptomatte_hash(&asset_object->id);
+}
+
+/* Convert a cryptomatte hash to a float.
+ *
+ * Cryptomatte hashes are stored in float textures and images. The conversion is taken from the
+ * cryptomatte specification. See Floating point conversion section in
+ * https://github.com/Psyop/Cryptomatte/blob/master/specification/cryptomatte_specification.pdf.
+ *
+ * The conversion uses as many 32 bit floating point values as possible to minimize hash
+ * collisions. Unfortunately not all 32 bits can be as NaN and Inf can be problematic.
+ *
+ * Note that this conversion assumes to be running on a L-endian system. */
+float BKE_cryptomatte_hash_to_float(uint32_t cryptomatte_hash)
+{
+ uint32_t mantissa = cryptomatte_hash & ((1 << 23) - 1);
+ uint32_t exponent = (cryptomatte_hash >> 23) & ((1 << 8) - 1);
+ exponent = MAX2(exponent, (uint32_t)1);
+ exponent = MIN2(exponent, (uint32_t)254);
+ exponent = exponent << 23;
+ uint32_t sign = (cryptomatte_hash >> 31);
+ sign = sign << 31;
+ uint32_t float_bits = sign | exponent | mantissa;
+ float f;
+ memcpy(&f, &float_bits, sizeof(uint32_t));
+ return f;
+}
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 2df9f362b9c..ebce28c4e23 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -2185,19 +2185,28 @@ static void bevel_list_calc_bisect(BevList *bl)
bevp2++;
}
+ /* In the unlikely situation that handles define a zeroed direction,
+ * calculate it from the adjacent points, see T80742.
+ *
+ * Only do this as a fallback since we typically want the end-point directions
+ * to be exactly aligned with the handles at the end-point, see T83117. */
if (is_cyclic == false) {
bevp0 = &bl->bevpoints[0];
bevp1 = &bl->bevpoints[1];
- sub_v3_v3v3(bevp0->dir, bevp1->vec, bevp0->vec);
- if (normalize_v3(bevp0->dir) == 0.0f) {
- copy_v3_v3(bevp0->dir, bevp1->dir);
+ if (UNLIKELY(is_zero_v3(bevp0->dir))) {
+ sub_v3_v3v3(bevp0->dir, bevp1->vec, bevp0->vec);
+ if (normalize_v3(bevp0->dir) == 0.0f) {
+ copy_v3_v3(bevp0->dir, bevp1->dir);
+ }
}
bevp0 = &bl->bevpoints[bl->nr - 2];
bevp1 = &bl->bevpoints[bl->nr - 1];
- sub_v3_v3v3(bevp1->dir, bevp1->vec, bevp0->vec);
- if (normalize_v3(bevp1->dir) == 0.0f) {
- copy_v3_v3(bevp1->dir, bevp0->dir);
+ if (UNLIKELY(is_zero_v3(bevp1->dir))) {
+ sub_v3_v3v3(bevp1->dir, bevp1->vec, bevp0->vec);
+ if (normalize_v3(bevp1->dir) == 0.0f) {
+ copy_v3_v3(bevp1->dir, bevp0->dir);
+ }
}
}
}
diff --git a/source/blender/blenkernel/intern/fcurve_driver.c b/source/blender/blenkernel/intern/fcurve_driver.c
index b11a3cb9457..1bce9ad8e35 100644
--- a/source/blender/blenkernel/intern/fcurve_driver.c
+++ b/source/blender/blenkernel/intern/fcurve_driver.c
@@ -411,7 +411,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
/* Extract transform just like how the constraints do it! */
copy_m4_m4(mat, pchan->pose_mat);
BKE_constraint_mat_convertspace(
- ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
+ ob, pchan, NULL, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
/* ... and from that, we get our transform. */
copy_v3_v3(tmp_loc, mat[3]);
@@ -437,7 +437,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
/* Extract transform just like how the constraints do it! */
copy_m4_m4(mat, ob->obmat);
BKE_constraint_mat_convertspace(
- ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
+ ob, NULL, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
/* ... and from that, we get our transform. */
copy_v3_v3(tmp_loc, mat[3]);
@@ -514,7 +514,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
/* Just like how the constraints do it! */
copy_m4_m4(mat, pchan->pose_mat);
BKE_constraint_mat_convertspace(
- ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
+ ob, pchan, NULL, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
}
else {
/* Specially calculate local matrix, since chan_mat is not valid
@@ -541,7 +541,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
/* Just like how the constraints do it! */
copy_m4_m4(mat, ob->obmat);
BKE_constraint_mat_convertspace(
- ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
+ ob, NULL, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
}
else {
/* Transforms to matrix. */
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 98e83bfb789..f68a390db64 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -671,6 +671,8 @@ bGPDlayer *BKE_gpencil_layer_addnew(bGPdata *gpd, const char *name, bool setacti
ARRAY_SET_ITEMS(gpl->color, 0.2f, 0.2f, 0.2f);
/* Default vertex mix. */
gpl->vertex_paint_opacity = 1.0f;
+ /* Enable onion skin. */
+ gpl->onion_flag |= GP_LAYER_ONIONSKIN;
}
/* auto-name */
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index 09f9e9e891c..ac81e4a5470 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -531,6 +531,19 @@ void BKE_gpencil_modifier_set_error(GpencilModifierData *md, const char *_format
}
/**
+ * Check whether given modifier is not local (i.e. from linked data) when the object is a library
+ * override.
+ *
+ * \param gmd May be NULL, in which case we consider it as a non-local modifier case.
+ */
+bool BKE_gpencil_modifier_is_nonlocal_in_liboverride(const Object *ob,
+ const GpencilModifierData *gmd)
+{
+ return (ID_IS_OVERRIDE_LIBRARY(ob) &&
+ (gmd == NULL || (gmd->flag & eGpencilModifierFlag_OverrideLibrary_Local) == 0));
+}
+
+/**
* Link grease pencil modifier related IDs.
* \param ob: Grease pencil object
* \param walk: Walk option
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 9696d920640..6a852df95c6 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -1999,12 +1999,12 @@ static void nlastrips_to_animdata(ID *id, ListBase *strips)
}
/* try to add this strip to the current NLA-Track (i.e. the 'last' one on the stack atm) */
- if (BKE_nlatrack_add_strip(nlt, strip) == 0) {
+ if (BKE_nlatrack_add_strip(nlt, strip, false) == 0) {
/* trying to add to the current failed (no space),
* so add a new track to the stack, and add to that...
*/
- nlt = BKE_nlatrack_add(adt, NULL);
- BKE_nlatrack_add_strip(nlt, strip);
+ nlt = BKE_nlatrack_add(adt, NULL, false);
+ BKE_nlatrack_add_strip(nlt, strip, false);
}
/* ensure that strip has a name */
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 0757cf791b7..8a699e31f37 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -57,6 +57,8 @@
#include "DRW_engine.h"
+#include "RE_engine.h"
+
#include "MEM_guardedalloc.h"
#include "BLO_read_write.h"
@@ -175,6 +177,8 @@ static ViewLayer *view_layer_add(const char *name)
view_layer->layflag = 0x7FFF; /* solid ztra halo edge strand */
view_layer->passflag = SCE_PASS_COMBINED | SCE_PASS_Z;
view_layer->pass_alpha_threshold = 0.5f;
+ view_layer->cryptomatte_levels = 6;
+ view_layer->cryptomatte_flag = VIEW_LAYER_CRYPTOMATTE_ACCURATE;
BKE_freestyle_config_init(&view_layer->freestyle_config);
return view_layer;
@@ -279,6 +283,8 @@ void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user)
}
}
BLI_freelistN(&view_layer->drawdata);
+ BLI_freelistN(&view_layer->aovs);
+ view_layer->active_aov = NULL;
MEM_SAFE_FREE(view_layer->stats);
@@ -412,6 +418,28 @@ void BKE_view_layer_base_select_and_set_active(struct ViewLayer *view_layer, Bas
}
/**************************** Copy View Layer and Layer Collections ***********************/
+static void layer_aov_copy_data(ViewLayer *view_layer_dst,
+ const ViewLayer *view_layer_src,
+ ListBase *aovs_dst,
+ const ListBase *aovs_src)
+{
+ if (aovs_src != NULL) {
+ BLI_duplicatelist(aovs_dst, aovs_src);
+ }
+
+ ViewLayerAOV *aov_dst = aovs_dst->first;
+ const ViewLayerAOV *aov_src = aovs_src->first;
+
+ while (aov_dst != NULL) {
+ BLI_assert(aov_src);
+ if (aov_src == view_layer_src->active_aov) {
+ view_layer_dst->active_aov = aov_dst;
+ }
+
+ aov_dst = aov_dst->next;
+ aov_src = aov_src->next;
+ }
+}
static void layer_collections_copy_data(ViewLayer *view_layer_dst,
const ViewLayer *view_layer_src,
@@ -482,6 +510,10 @@ void BKE_view_layer_copy_data(Scene *scene_dst,
LayerCollection *lc_scene_dst = view_layer_dst->layer_collections.first;
lc_scene_dst->collection = scene_dst->master_collection;
+ BLI_listbase_clear(&view_layer_dst->aovs);
+ layer_aov_copy_data(
+ view_layer_dst, view_layer_src, &view_layer_dst->aovs, &view_layer_src->aovs);
+
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
id_us_plus((ID *)view_layer_dst->mat_override);
}
@@ -1261,7 +1293,7 @@ void BKE_layer_collection_local_sync(ViewLayer *view_layer, const View3D *v3d)
}
/**
- * Sync the local collection for all the view-ports.
+ * Sync the local collection for all the 3D Viewports.
*/
void BKE_layer_collection_local_sync_all(const Main *bmain)
{
@@ -1864,6 +1896,9 @@ void BKE_view_layer_blend_write(BlendWriter *writer, ViewLayer *view_layer)
LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) {
BLO_write_struct(writer, FreestyleLineSet, fls);
}
+ LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
+ BLO_write_struct(writer, ViewLayerAOV, aov);
+ }
write_layer_collections(writer, &view_layer->layer_collections);
}
@@ -1899,6 +1934,9 @@ void BKE_view_layer_blend_read_data(BlendDataReader *reader, ViewLayer *view_lay
BLO_read_list(reader, &(view_layer->freestyle_config.modules));
BLO_read_list(reader, &(view_layer->freestyle_config.linesets));
+ BLO_read_list(reader, &view_layer->aovs);
+ BLO_read_data_address(reader, &view_layer->active_aov);
+
BLI_listbase_clear(&view_layer->drawdata);
view_layer->object_bases_array = NULL;
view_layer->object_bases_hash = NULL;
@@ -1952,3 +1990,129 @@ void BKE_view_layer_blend_read_lib(BlendLibReader *reader, Library *lib, ViewLay
IDP_BlendReadLib(reader, view_layer->id_properties);
}
+
+/* -------------------------------------------------------------------- */
+/** \name Shader AOV
+ * \{ */
+
+static void viewlayer_aov_make_name_unique(ViewLayer *view_layer)
+{
+ ViewLayerAOV *aov = view_layer->active_aov;
+ if (aov == NULL) {
+ return;
+ }
+ BLI_uniquename(
+ &view_layer->aovs, aov, DATA_("AOV"), '.', offsetof(ViewLayerAOV, name), sizeof(aov->name));
+}
+
+static void viewlayer_aov_active_set(ViewLayer *view_layer, ViewLayerAOV *aov)
+{
+ if (aov != NULL) {
+ BLI_assert(BLI_findindex(&view_layer->aovs, aov) != -1);
+ view_layer->active_aov = aov;
+ }
+ else {
+ view_layer->active_aov = NULL;
+ }
+}
+
+struct ViewLayerAOV *BKE_view_layer_add_aov(struct ViewLayer *view_layer)
+{
+ ViewLayerAOV *aov;
+ aov = MEM_callocN(sizeof(ViewLayerAOV), __func__);
+ aov->type = AOV_TYPE_COLOR;
+ BLI_strncpy(aov->name, DATA_("AOV"), sizeof(aov->name));
+ BLI_addtail(&view_layer->aovs, aov);
+ viewlayer_aov_active_set(view_layer, aov);
+ viewlayer_aov_make_name_unique(view_layer);
+ return aov;
+}
+
+void BKE_view_layer_remove_aov(ViewLayer *view_layer, ViewLayerAOV *aov)
+{
+ BLI_assert(BLI_findindex(&view_layer->aovs, aov) != -1);
+ BLI_assert(aov != NULL);
+ if (view_layer->active_aov == aov) {
+ if (aov->next) {
+ viewlayer_aov_active_set(view_layer, aov->next);
+ }
+ else {
+ viewlayer_aov_active_set(view_layer, aov->prev);
+ }
+ }
+ BLI_freelinkN(&view_layer->aovs, aov);
+}
+
+void BKE_view_layer_set_active_aov(ViewLayer *view_layer, ViewLayerAOV *aov)
+{
+ viewlayer_aov_active_set(view_layer, aov);
+}
+
+static void bke_view_layer_verify_aov_cb(void *userdata,
+ Scene *UNUSED(scene),
+ ViewLayer *UNUSED(view_layer),
+ const char *name,
+ int UNUSED(channels),
+ const char *UNUSED(chanid),
+ int UNUSED(type))
+{
+ GHash *name_count = userdata;
+ void **value_p;
+ void *key = BLI_strdup(name);
+
+ if (!BLI_ghash_ensure_p(name_count, key, &value_p)) {
+ *value_p = POINTER_FROM_INT(1);
+ }
+ else {
+ int value = POINTER_AS_INT(*value_p);
+ value++;
+ *value_p = POINTER_FROM_INT(value);
+ MEM_freeN(key);
+ }
+}
+
+/* Update the naming and conflicts of the AOVs.
+ *
+ * Name must be unique between all AOVs.
+ * Conflicts with render passes will show a conflict icon. Reason is that switching a render
+ * engine or activating a render pass could lead to other conflicts that wouldn't be that clear
+ * for the user. */
+void BKE_view_layer_verify_aov(struct RenderEngine *engine,
+ struct Scene *scene,
+ struct ViewLayer *view_layer)
+{
+ viewlayer_aov_make_name_unique(view_layer);
+
+ GHash *name_count = BLI_ghash_str_new(__func__);
+ RE_engine_update_render_passes(
+ engine, scene, view_layer, bke_view_layer_verify_aov_cb, name_count);
+ LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
+ void **value_p = BLI_ghash_lookup(name_count, aov->name);
+ int count = POINTER_AS_INT(value_p);
+ SET_FLAG_FROM_TEST(aov->flag, count > 1, AOV_CONFLICT);
+ }
+ BLI_ghash_free(name_count, MEM_freeN, NULL);
+}
+
+/* Check if the given view layer has at least one valid AOV. */
+bool BKE_view_layer_has_valid_aov(ViewLayer *view_layer)
+{
+ LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
+ if ((aov->flag & AOV_CONFLICT) == 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+ViewLayer *BKE_view_layer_find_with_aov(struct Scene *scene, struct ViewLayerAOV *aov)
+{
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ if (BLI_findindex(&view_layer->aovs, aov) != -1) {
+ return view_layer;
+ }
+ }
+ return NULL;
+}
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/layer_test.cc b/source/blender/blenkernel/intern/layer_test.cc
new file mode 100644
index 00000000000..e241c12d714
--- /dev/null
+++ b/source/blender/blenkernel/intern/layer_test.cc
@@ -0,0 +1,177 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 by Blender Foundation.
+ */
+#include "testing/testing.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_appdir.h"
+#include "BKE_idtype.h"
+#include "BKE_layer.h"
+
+#include "BLI_string.h"
+
+#include "RE_engine.h"
+
+#include "IMB_imbuf.h"
+
+#include "CLG_log.h"
+
+#include "RNA_access.h"
+
+namespace blender::bke::tests {
+
+TEST(view_layer, aov_unique_names)
+{
+ /* Set Up */
+ CLG_init();
+ BKE_appdir_init();
+ IMB_init();
+ RE_engines_init();
+
+ Scene scene = {{nullptr}};
+ IDType_ID_SCE.init_data(&scene.id);
+ ViewLayer *view_layer = static_cast<ViewLayer *>(scene.view_layers.first);
+
+ RenderEngineType *engine_type = RE_engines_find(scene.r.engine);
+ RenderEngine *engine = RE_engine_create(engine_type);
+
+ EXPECT_FALSE(BKE_view_layer_has_valid_aov(view_layer));
+ EXPECT_EQ(view_layer->active_aov, nullptr);
+
+ /* Add an AOV */
+ ViewLayerAOV *aov1 = BKE_view_layer_add_aov(view_layer);
+ BKE_view_layer_verify_aov(engine, &scene, view_layer);
+ EXPECT_EQ(view_layer->active_aov, aov1);
+ EXPECT_TRUE(BKE_view_layer_has_valid_aov(view_layer));
+ EXPECT_FALSE((aov1->flag & AOV_CONFLICT) != 0);
+
+ /* Add a second AOV */
+ ViewLayerAOV *aov2 = BKE_view_layer_add_aov(view_layer);
+ BKE_view_layer_verify_aov(engine, &scene, view_layer);
+ EXPECT_EQ(view_layer->active_aov, aov2);
+ EXPECT_TRUE(BKE_view_layer_has_valid_aov(view_layer));
+ EXPECT_FALSE((aov1->flag & AOV_CONFLICT) != 0);
+ EXPECT_FALSE((aov2->flag & AOV_CONFLICT) != 0);
+ EXPECT_TRUE(STREQ(aov1->name, "AOV"));
+ EXPECT_TRUE(STREQ(aov2->name, "AOV.001"));
+
+ /* Revert previous resolution */
+ BLI_strncpy(aov2->name, "AOV", MAX_NAME);
+ BKE_view_layer_verify_aov(engine, &scene, view_layer);
+ EXPECT_TRUE(BKE_view_layer_has_valid_aov(view_layer));
+ EXPECT_FALSE((aov1->flag & AOV_CONFLICT) != 0);
+ EXPECT_FALSE((aov2->flag & AOV_CONFLICT) != 0);
+ EXPECT_TRUE(STREQ(aov1->name, "AOV"));
+ EXPECT_TRUE(STREQ(aov2->name, "AOV.001"));
+
+ /* Resolve by removing AOV resolution */
+ BKE_view_layer_remove_aov(view_layer, aov2);
+ aov2 = nullptr;
+ BKE_view_layer_verify_aov(engine, &scene, view_layer);
+ EXPECT_TRUE(BKE_view_layer_has_valid_aov(view_layer));
+ EXPECT_FALSE((aov1->flag & AOV_CONFLICT) != 0);
+
+ /* Tear down */
+ RE_engine_free(engine);
+ RE_engines_exit();
+ IDType_ID_SCE.free_data(&scene.id);
+ IMB_exit();
+ BKE_appdir_exit();
+ CLG_exit();
+}
+
+static void test_render_pass_conflict(Scene *scene,
+ RenderEngine *engine,
+ ViewLayer *view_layer,
+ ViewLayerAOV *aov,
+ const char *render_pass_name,
+ const char *rna_prop_name)
+{
+ PointerRNA ptr;
+ RNA_pointer_create(&scene->id, &RNA_ViewLayer, view_layer, &ptr);
+ RNA_boolean_set(&ptr, rna_prop_name, false);
+
+ /* Rename to Conflicting name */
+ BLI_strncpy(aov->name, render_pass_name, MAX_NAME);
+ BKE_view_layer_verify_aov(engine, scene, view_layer);
+ EXPECT_TRUE(BKE_view_layer_has_valid_aov(view_layer));
+ EXPECT_FALSE((aov->flag & AOV_CONFLICT) != 0);
+ EXPECT_TRUE(STREQ(aov->name, render_pass_name));
+
+ /* Activate render pass */
+ RNA_boolean_set(&ptr, rna_prop_name, true);
+ BKE_view_layer_verify_aov(engine, scene, view_layer);
+ EXPECT_FALSE(BKE_view_layer_has_valid_aov(view_layer));
+ EXPECT_TRUE((aov->flag & AOV_CONFLICT) != 0);
+ EXPECT_TRUE(STREQ(aov->name, render_pass_name));
+
+ /* Deactivate render pass */
+ RNA_boolean_set(&ptr, rna_prop_name, false);
+ BKE_view_layer_verify_aov(engine, scene, view_layer);
+ EXPECT_TRUE(BKE_view_layer_has_valid_aov(view_layer));
+ EXPECT_FALSE((aov->flag & AOV_CONFLICT) != 0);
+ EXPECT_TRUE(STREQ(aov->name, render_pass_name));
+}
+
+TEST(view_layer, aov_conflict)
+{
+ /* Set Up */
+ CLG_init();
+ BKE_appdir_init();
+ IMB_init();
+ RE_engines_init();
+
+ Scene scene = {{nullptr}};
+ IDType_ID_SCE.init_data(&scene.id);
+ ViewLayer *view_layer = static_cast<ViewLayer *>(scene.view_layers.first);
+
+ RenderEngineType *engine_type = RE_engines_find(scene.r.engine);
+ RenderEngine *engine = RE_engine_create(engine_type);
+
+ EXPECT_FALSE(BKE_view_layer_has_valid_aov(view_layer));
+ EXPECT_EQ(view_layer->active_aov, nullptr);
+
+ /* Add an AOV */
+ ViewLayerAOV *aov = BKE_view_layer_add_aov(view_layer);
+ BKE_view_layer_verify_aov(engine, &scene, view_layer);
+ EXPECT_EQ(view_layer->active_aov, aov);
+ EXPECT_TRUE(BKE_view_layer_has_valid_aov(view_layer));
+ EXPECT_FALSE((aov->flag & AOV_CONFLICT) != 0);
+
+ test_render_pass_conflict(&scene, engine, view_layer, aov, "Depth", "use_pass_z");
+ test_render_pass_conflict(&scene, engine, view_layer, aov, "Normal", "use_pass_normal");
+ test_render_pass_conflict(&scene, engine, view_layer, aov, "Mist", "use_pass_mist");
+ test_render_pass_conflict(&scene, engine, view_layer, aov, "Shadow", "use_pass_shadow");
+ test_render_pass_conflict(&scene, engine, view_layer, aov, "AO", "use_pass_ambient_occlusion");
+ test_render_pass_conflict(&scene, engine, view_layer, aov, "Emit", "use_pass_emit");
+ test_render_pass_conflict(&scene, engine, view_layer, aov, "Env", "use_pass_environment");
+ test_render_pass_conflict(&scene, engine, view_layer, aov, "DiffDir", "use_pass_diffuse_direct");
+ test_render_pass_conflict(&scene, engine, view_layer, aov, "DiffCol", "use_pass_diffuse_color");
+ test_render_pass_conflict(&scene, engine, view_layer, aov, "GlossDir", "use_pass_glossy_direct");
+ test_render_pass_conflict(&scene, engine, view_layer, aov, "GlossCol", "use_pass_glossy_color");
+
+ /* Tear down */
+ RE_engine_free(engine);
+ RE_engines_exit();
+ IDType_ID_SCE.free_data(&scene.id);
+ IMB_exit();
+ BKE_appdir_exit();
+ CLG_exit();
+}
+
+} // namespace blender::bke::tests
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index 69e6535a59f..8542959d4b0 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -2017,7 +2017,7 @@ char *BKE_linestyle_path_to_color_ramp(FreestyleLineStyle *linestyle, ColorBand
if (found) {
char name_esc[sizeof(m->name) * 2];
- BLI_strescape(name_esc, m->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, m->name, sizeof(name_esc));
return BLI_sprintfN("color_modifiers[\"%s\"].color_ramp", name_esc);
}
}
diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc
index 16733729be0..0aaca33124a 100644
--- a/source/blender/blenkernel/intern/mesh_validate.cc
+++ b/source/blender/blenkernel/intern/mesh_validate.cc
@@ -76,10 +76,10 @@ struct OrderedEdge {
};
/* The map first contains an edge pointer and later an index. */
-typedef union OrigEdgeOrIndex {
+union OrigEdgeOrIndex {
const MEdge *original_edge;
int index;
-} OrigEdgeOrIndex;
+};
using EdgeMap = Map<OrderedEdge, OrigEdgeOrIndex>;
static void reserve_hash_maps(const Mesh *mesh,
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index c9bdaecfa2a..3496e05c6e5 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -574,6 +574,18 @@ bool BKE_modifier_is_enabled(const struct Scene *scene, ModifierData *md, int re
return true;
}
+/**
+ * Check whether given modifier is not local (i.e. from linked data) when the object is a library
+ * override.
+ *
+ * \param md May be NULL, in which case we consider it as a non-local modifier case.
+ */
+bool BKE_modifier_is_nonlocal_in_liboverride(const Object *ob, const ModifierData *md)
+{
+ return (ID_IS_OVERRIDE_LIBRARY(ob) &&
+ (md == NULL || (md->flag & eModifierFlag_OverrideLibrary_Local) == 0));
+}
+
CDMaskLink *BKE_modifier_calc_data_masks(struct Scene *scene,
Object *ob,
ModifierData *md,
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 56bd83140bf..ebd9317fcf1 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -280,7 +280,7 @@ void BKE_nla_tracks_copy(Main *bmain, ListBase *dst, ListBase *src, const int fl
/* Add a NLA Track to the given AnimData
* - prev: NLA-Track to add the new one after
*/
-NlaTrack *BKE_nlatrack_add(AnimData *adt, NlaTrack *prev)
+NlaTrack *BKE_nlatrack_add(AnimData *adt, NlaTrack *prev, const bool is_liboverride)
{
NlaTrack *nlt;
@@ -293,11 +293,15 @@ NlaTrack *BKE_nlatrack_add(AnimData *adt, NlaTrack *prev)
nlt = MEM_callocN(sizeof(NlaTrack), "NlaTrack");
/* set settings requiring the track to not be part of the stack yet */
- nlt->flag = NLATRACK_SELECTED;
+ nlt->flag = NLATRACK_SELECTED | NLATRACK_OVERRIDELIBRARY_LOCAL;
nlt->index = BLI_listbase_count(&adt->nla_tracks);
/* add track to stack, and make it the active one */
- if (prev) {
+ if (is_liboverride) {
+ for (; prev != NULL && (prev->flag & NLATRACK_OVERRIDELIBRARY_LOCAL) == 0; prev = prev->next) {
+ }
+ }
+ if (prev != NULL) {
BLI_insertlinkafter(&adt->nla_tracks, prev, nlt);
}
else {
@@ -359,7 +363,7 @@ NlaStrip *BKE_nlastrip_new(bAction *act)
/* Add new NLA-strip to the top of the NLA stack - i.e.
* into the last track if space, or a new one otherwise. */
-NlaStrip *BKE_nlastack_add_strip(AnimData *adt, bAction *act)
+NlaStrip *BKE_nlastack_add_strip(AnimData *adt, bAction *act, const bool is_liboverride)
{
NlaStrip *strip;
NlaTrack *nlt;
@@ -376,12 +380,12 @@ NlaStrip *BKE_nlastack_add_strip(AnimData *adt, bAction *act)
}
/* firstly try adding strip to last track, but if that fails, add to a new track */
- if (BKE_nlatrack_add_strip(adt->nla_tracks.last, strip) == 0) {
+ if (BKE_nlatrack_add_strip(adt->nla_tracks.last, strip, is_liboverride) == 0) {
/* trying to add to the last track failed (no track or no space),
* so add a new track to the stack, and add to that...
*/
- nlt = BKE_nlatrack_add(adt, NULL);
- BKE_nlatrack_add_strip(nlt, strip);
+ nlt = BKE_nlatrack_add(adt, NULL, is_liboverride);
+ BKE_nlatrack_add_strip(nlt, strip, is_liboverride);
}
/* automatically name it too */
@@ -1138,15 +1142,16 @@ void BKE_nlatrack_sort_strips(NlaTrack *nlt)
/* Add the given NLA-Strip to the given NLA-Track, assuming that it
* isn't currently attached to another one
*/
-bool BKE_nlatrack_add_strip(NlaTrack *nlt, NlaStrip *strip)
+bool BKE_nlatrack_add_strip(NlaTrack *nlt, NlaStrip *strip, const bool is_liboverride)
{
/* sanity checks */
if (ELEM(NULL, nlt, strip)) {
return false;
}
- /* do not allow adding strips if this track is locked */
- if (nlt->flag & NLATRACK_PROTECTED) {
+ /* Do not allow adding strips if this track is locked, or not a local one in liboverride case. */
+ if (nlt->flag & NLATRACK_PROTECTED ||
+ (is_liboverride && (nlt->flag & NLATRACK_OVERRIDELIBRARY_LOCAL) == 0)) {
return false;
}
@@ -1186,6 +1191,18 @@ bool BKE_nlatrack_get_bounds(NlaTrack *nlt, float bounds[2])
return true;
}
+/**
+ * Check whether given NLA track is not local (i.e. from linked data) when the object is a library
+ * override.
+ *
+ * \param nlt May be NULL, in which case we consider it as a non-local track case.
+ */
+bool BKE_nlatrack_is_nonlocal_in_liboverride(const ID *id, const NlaTrack *nlt)
+{
+ return (ID_IS_OVERRIDE_LIBRARY(id) &&
+ (nlt == NULL || (nlt->flag & NLATRACK_OVERRIDELIBRARY_LOCAL) == 0));
+}
+
/* NLA Strips -------------------------------------- */
/* Find the active NLA-strip within the given track */
@@ -1857,7 +1874,7 @@ bool BKE_nla_action_is_stashed(AnimData *adt, bAction *act)
/* "Stash" an action (i.e. store it as a track/layer in the NLA, but non-contributing)
* to retain it in the file for future uses
*/
-bool BKE_nla_action_stash(AnimData *adt)
+bool BKE_nla_action_stash(AnimData *adt, const bool is_liboverride)
{
NlaTrack *prev_track = NULL;
NlaTrack *nlt;
@@ -1881,7 +1898,7 @@ bool BKE_nla_action_stash(AnimData *adt)
}
}
- nlt = BKE_nlatrack_add(adt, prev_track);
+ nlt = BKE_nlatrack_add(adt, prev_track, is_liboverride);
BLI_assert(nlt != NULL);
/* We need to ensure that if there wasn't any previous instance,
@@ -1901,7 +1918,7 @@ bool BKE_nla_action_stash(AnimData *adt)
strip = BKE_nlastrip_new(adt->action);
BLI_assert(strip != NULL);
- BKE_nlatrack_add_strip(nlt, strip);
+ BKE_nlatrack_add_strip(nlt, strip, is_liboverride);
BKE_nlastrip_validate_name(adt, strip);
/* mark the stash track and strip so that they doesn't disturb the stack animation,
@@ -1931,7 +1948,7 @@ bool BKE_nla_action_stash(AnimData *adt)
* so no checks for this are performed.
*/
/* TODO: maybe we should have checks for this too... */
-void BKE_nla_action_pushdown(AnimData *adt)
+void BKE_nla_action_pushdown(AnimData *adt, const bool is_liboverride)
{
NlaStrip *strip;
const bool is_first = (adt) && (adt->nla_tracks.first == NULL);
@@ -1952,7 +1969,7 @@ void BKE_nla_action_pushdown(AnimData *adt)
}
/* add a new NLA strip to the track, which references the active action */
- strip = BKE_nlastack_add_strip(adt, adt->action);
+ strip = BKE_nlastack_add_strip(adt, adt->action, is_liboverride);
if (strip == NULL) {
return;
}
@@ -2273,6 +2290,11 @@ void BKE_nla_blend_read_lib(BlendLibReader *reader, ID *id, ListBase *tracks)
{
/* we only care about the NLA strips inside the tracks */
LISTBASE_FOREACH (NlaTrack *, nlt, tracks) {
+ /* If linking from a library, clear 'local' library override flag. */
+ if (id->lib != NULL) {
+ nlt->flag &= ~NLATRACK_OVERRIDELIBRARY_LOCAL;
+ }
+
blend_lib_read_nla_strips(reader, id, &nlt->strips);
}
}
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index b564a4c468b..31de95817fd 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -2708,7 +2708,7 @@ void nodeRemoveNode(Main *bmain, bNodeTree *ntree, bNode *node, bool do_id_user)
char propname_esc[MAX_IDPROP_NAME * 2];
char prefix[MAX_IDPROP_NAME * 2];
- BLI_strescape(propname_esc, node->name, sizeof(propname_esc));
+ BLI_str_escape(propname_esc, node->name, sizeof(propname_esc));
BLI_snprintf(prefix, sizeof(prefix), "nodes[\"%s\"]", propname_esc);
if (BKE_animdata_fix_paths_remove((ID *)ntree, prefix)) {
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 9a8c560f116..d5434710e23 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -829,13 +829,18 @@ static void make_duplis_instances_component(const DupliContext *ctx)
size_to_mat4(scale_matrix, scales[i]);
float rotation_matrix[4][4];
eul_to_mat4(rotation_matrix, rotations[i]);
- float matrix[4][4];
- mul_m4_m4m4(matrix, rotation_matrix, scale_matrix);
- copy_v3_v3(matrix[3], positions[i]);
- mul_m4_m4_pre(matrix, ctx->object->obmat);
+ float instance_offset_matrix[4][4];
+ mul_m4_m4m4(instance_offset_matrix, rotation_matrix, scale_matrix);
+ copy_v3_v3(instance_offset_matrix[3], positions[i]);
+ float matrix[4][4];
+ mul_m4_m4m4(matrix, ctx->object->obmat, instance_offset_matrix);
make_dupli(ctx, object, matrix, i);
- make_recursive_duplis(ctx, object, matrix, i);
+
+ float space_matrix[4][4];
+ mul_m4_m4m4(space_matrix, instance_offset_matrix, object->imat);
+ mul_m4_m4_pre(space_matrix, ctx->object->obmat);
+ make_recursive_duplis(ctx, object, space_matrix, i);
}
}
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 97bef99944a..355db8f0d60 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -1561,7 +1561,6 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
/* we only saved what was used */
space_outliner->storeflag |= SO_TREESTORE_CLEANUP; /* at first draw */
}
- space_outliner->treehash = NULL;
space_outliner->tree.first = space_outliner->tree.last = NULL;
space_outliner->runtime = NULL;
}
@@ -1825,10 +1824,8 @@ void BKE_screen_area_blend_read_lib(BlendLibReader *reader, ID *parent_id, ScrAr
while ((tselem = BLI_mempool_iterstep(&iter))) {
BLO_read_id_address(reader, NULL, &tselem->id);
}
- if (space_outliner->treehash) {
- /* rebuild hash table, because it depends on ids too */
- space_outliner->storeflag |= SO_TREESTORE_REBUILD;
- }
+ /* rebuild hash table, because it depends on ids too */
+ space_outliner->storeflag |= SO_TREESTORE_REBUILD;
}
break;
}
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index e083f7ceec0..e5f9d59270e 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -3138,13 +3138,13 @@ void BKE_tracking_get_rna_path_for_track(const struct MovieTracking *tracking,
{
MovieTrackingObject *object = BKE_tracking_find_object_for_track(tracking, track);
char track_name_esc[MAX_NAME * 2];
- BLI_strescape(track_name_esc, track->name, sizeof(track_name_esc));
+ BLI_str_escape(track_name_esc, track->name, sizeof(track_name_esc));
if (object == NULL) {
BLI_snprintf(rna_path, rna_path_len, "tracking.tracks[\"%s\"]", track_name_esc);
}
else {
char object_name_esc[MAX_NAME * 2];
- BLI_strescape(object_name_esc, object->name, sizeof(object_name_esc));
+ BLI_str_escape(object_name_esc, object->name, sizeof(object_name_esc));
BLI_snprintf(rna_path,
rna_path_len,
"tracking.objects[\"%s\"].tracks[\"%s\"]",
@@ -3164,7 +3164,7 @@ void BKE_tracking_get_rna_path_prefix_for_track(const struct MovieTracking *trac
}
else {
char object_name_esc[MAX_NAME * 2];
- BLI_strescape(object_name_esc, object->name, sizeof(object_name_esc));
+ BLI_str_escape(object_name_esc, object->name, sizeof(object_name_esc));
BLI_snprintf(rna_path, rna_path_len, "tracking.objects[\"%s\"]", object_name_esc);
}
}
@@ -3176,13 +3176,13 @@ void BKE_tracking_get_rna_path_for_plane_track(const struct MovieTracking *track
{
MovieTrackingObject *object = BKE_tracking_find_object_for_plane_track(tracking, plane_track);
char track_name_esc[MAX_NAME * 2];
- BLI_strescape(track_name_esc, plane_track->name, sizeof(track_name_esc));
+ BLI_str_escape(track_name_esc, plane_track->name, sizeof(track_name_esc));
if (object == NULL) {
BLI_snprintf(rna_path, rna_path_len, "tracking.plane_tracks[\"%s\"]", track_name_esc);
}
else {
char object_name_esc[MAX_NAME * 2];
- BLI_strescape(object_name_esc, object->name, sizeof(object_name_esc));
+ BLI_str_escape(object_name_esc, object->name, sizeof(object_name_esc));
BLI_snprintf(rna_path,
rna_path_len,
"tracking.objects[\"%s\"].plane_tracks[\"%s\"]",
@@ -3203,7 +3203,7 @@ void BKE_tracking_get_rna_path_prefix_for_plane_track(
}
else {
char object_name_esc[MAX_NAME * 2];
- BLI_strescape(object_name_esc, object->name, sizeof(object_name_esc));
+ BLI_str_escape(object_name_esc, object->name, sizeof(object_name_esc));
BLI_snprintf(rna_path, rna_path_len, "tracking.objects[\"%s\"].plane_tracks", object_name_esc);
}
}
diff --git a/source/blender/blenkernel/intern/tracking_auto.c b/source/blender/blenkernel/intern/tracking_auto.c
index 05d1e427c14..d5e878a9a75 100644
--- a/source/blender/blenkernel/intern/tracking_auto.c
+++ b/source/blender/blenkernel/intern/tracking_auto.c
@@ -34,7 +34,9 @@
#include "BLI_task.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "PIL_time.h"
+#include "BKE_global.h"
#include "BKE_movieclip.h"
#include "BKE_tracking.h"
@@ -97,7 +99,7 @@ typedef struct AutoTrackContext {
/* True when tracking backwards (from higher frame number to lower frame number.) */
bool is_backwards;
- /* Movie clips used during the trackign process. */
+ /* Movie clips used during the tracking process. */
int num_clips;
AutoTrackClip autotrack_clips[MAX_ACCESSOR_CLIP];
@@ -180,7 +182,7 @@ static void libmv_frame_to_normalized_relative(const float frame_coord[2],
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Coversion of markers between Blender's DNA and Libmv.
+/** \name Conversion of markers between Blender's DNA and Libmv.
* \{ */
static void dna_marker_to_libmv_marker(/*const*/ MovieTrackingTrack *track,
@@ -702,7 +704,7 @@ bool BKE_autotrack_context_step(AutoTrackContext *context)
/* -------------------------------------------------------------------- */
/** \name Context data synchronization.
*
- * Used to copy trackign result to Blender side, while the trackign is still happening in its
+ * Used to copy tracking result to Blender side, while the tracking is still happening in its
* thread.
*
* \{ */
@@ -738,7 +740,7 @@ void BKE_autotrack_context_sync(AutoTrackContext *context)
}
BKE_tracking_marker_insert(track, &marker);
- /* Insetr disabled marker at the end of tracked segment.
+ /* Insert disabled marker at the end of tracked segment.
* When tracking forward the disabled marker is added at the next frame from the result,
* when tracking backwards the marker is added at the previous frame. */
tracking_marker_insert_disabled(track, &marker, context->is_backwards, false);
diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c
index eb57c28de09..ad2713b9977 100644
--- a/source/blender/blenkernel/intern/tracking_util.c
+++ b/source/blender/blenkernel/intern/tracking_util.c
@@ -615,88 +615,6 @@ MovieTrackingMarker *tracking_get_keyframed_marker(MovieTrackingTrack *track,
/*********************** Frame accessr *************************/
-typedef struct AccessCacheKey {
- int clip_index;
- int frame;
- int downscale;
- libmv_InputMode input_mode;
- bool has_region;
- float region_min[2], region_max[2];
- int64_t transform_key;
-} AccessCacheKey;
-
-static unsigned int accesscache_hashhash(const void *key_v)
-{
- const AccessCacheKey *key = (const AccessCacheKey *)key_v;
- /* TODP(sergey): Need better hashing here for faster frame access. */
- return key->clip_index << 16 | key->frame;
-}
-
-static bool accesscache_hashcmp(const void *a_v, const void *b_v)
-{
- const AccessCacheKey *a = (const AccessCacheKey *)a_v;
- const AccessCacheKey *b = (const AccessCacheKey *)b_v;
- if (a->clip_index != b->clip_index || a->frame != b->frame || a->downscale != b->downscale ||
- a->input_mode != b->input_mode || a->has_region != b->has_region ||
- a->transform_key != b->transform_key) {
- return true;
- }
- /* If there is region applied, compare it. */
- if (a->has_region) {
- if (!equals_v2v2(a->region_min, b->region_min) || !equals_v2v2(a->region_max, b->region_max)) {
- return true;
- }
- }
- return false;
-}
-
-static void accesscache_construct_key(AccessCacheKey *key,
- int clip_index,
- int frame,
- libmv_InputMode input_mode,
- int downscale,
- const libmv_Region *region,
- int64_t transform_key)
-{
- key->clip_index = clip_index;
- key->frame = frame;
- key->input_mode = input_mode;
- key->downscale = downscale;
- key->has_region = (region != NULL);
- if (key->has_region) {
- copy_v2_v2(key->region_min, region->min);
- copy_v2_v2(key->region_max, region->max);
- }
- key->transform_key = transform_key;
-}
-
-static void accesscache_put(TrackingImageAccessor *accessor,
- int clip_index,
- int frame,
- libmv_InputMode input_mode,
- int downscale,
- const libmv_Region *region,
- int64_t transform_key,
- ImBuf *ibuf)
-{
- AccessCacheKey key;
- accesscache_construct_key(&key, clip_index, frame, input_mode, downscale, region, transform_key);
- IMB_moviecache_put(accessor->cache, &key, ibuf);
-}
-
-static ImBuf *accesscache_get(TrackingImageAccessor *accessor,
- int clip_index,
- int frame,
- libmv_InputMode input_mode,
- int downscale,
- const libmv_Region *region,
- int64_t transform_key)
-{
- AccessCacheKey key;
- accesscache_construct_key(&key, clip_index, frame, input_mode, downscale, region, transform_key);
- return IMB_moviecache_get(accessor->cache, &key);
-}
-
static ImBuf *accessor_get_preprocessed_ibuf(TrackingImageAccessor *accessor,
int clip_index,
int frame)
@@ -776,33 +694,14 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
const libmv_Region *region,
const libmv_FrameTransform *transform)
{
- ImBuf *ibuf, *orig_ibuf, *final_ibuf;
- int64_t transform_key = 0;
- if (transform != NULL) {
- transform_key = libmv_frameAccessorgetTransformKey(transform);
- }
/* First try to get fully processed image from the cache. */
- BLI_spin_lock(&accessor->cache_lock);
- ibuf = accesscache_get(
- accessor, clip_index, frame, input_mode, downscale, region, transform_key);
- BLI_spin_unlock(&accessor->cache_lock);
- if (ibuf != NULL) {
- CACHE_PRINTF("Used cached buffer for frame %d\n", frame);
- /* This is a little heuristic here: if we re-used image once, this is
- * a high probability of the image to be related to a keyframe matched
- * reference image. Those images we don't want to be thrown away because
- * if we toss them out we'll be re-calculating them at the next
- * iteration.
- */
- ibuf->userflags |= IB_PERSISTENT;
- return ibuf;
- }
CACHE_PRINTF("Calculate new buffer for frame %d\n", frame);
/* And now we do postprocessing of the original frame. */
- orig_ibuf = accessor_get_preprocessed_ibuf(accessor, clip_index, frame);
+ ImBuf *orig_ibuf = accessor_get_preprocessed_ibuf(accessor, clip_index, frame);
if (orig_ibuf == NULL) {
return NULL;
}
+ ImBuf *final_ibuf;
/* Cut a region if requested. */
if (region != NULL) {
int width = region->max[0] - region->min[0], height = region->max[1] - region->min[1];
@@ -902,11 +801,6 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
final_ibuf = IMB_dupImBuf(orig_ibuf);
}
IMB_freeImBuf(orig_ibuf);
- BLI_spin_lock(&accessor->cache_lock);
- /* Put final buffer to cache. */
- accesscache_put(
- accessor, clip_index, frame, input_mode, downscale, region, transform_key, final_ibuf);
- BLI_spin_unlock(&accessor->cache_lock);
return final_ibuf;
}
@@ -1016,9 +910,6 @@ TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR
BLI_assert(num_clips <= MAX_ACCESSOR_CLIP);
- accessor->cache = IMB_moviecache_create(
- "frame access cache", sizeof(AccessCacheKey), accesscache_hashhash, accesscache_hashcmp);
-
memcpy(accessor->clips, clips, num_clips * sizeof(MovieClip *));
accessor->num_clips = num_clips;
@@ -1040,7 +931,6 @@ TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR
void tracking_image_accessor_destroy(TrackingImageAccessor *accessor)
{
- IMB_moviecache_free(accessor->cache);
libmv_FrameAccessorDestroy(accessor->libmv_accessor);
BLI_spin_end(&accessor->cache_lock);
MEM_freeN(accessor->tracks);
diff --git a/source/blender/blenkernel/tracking_private.h b/source/blender/blenkernel/tracking_private.h
index 64db84d5ac3..c8e7fea6601 100644
--- a/source/blender/blenkernel/tracking_private.h
+++ b/source/blender/blenkernel/tracking_private.h
@@ -131,8 +131,6 @@ struct libmv_FrameAccessor;
#define MAX_ACCESSOR_CLIP 64
typedef struct TrackingImageAccessor {
- struct MovieCache *cache;
-
struct MovieClip *clips[MAX_ACCESSOR_CLIP];
int num_clips;
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index 2d745e63764..096e7818013 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -85,8 +85,11 @@ size_t BLI_vsnprintf_rlen(char *__restrict buffer,
char *BLI_sprintfN(const char *__restrict format, ...) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1, 2);
-size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
+size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const size_t dst_maxncpy)
ATTR_NONNULL();
+size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, const size_t src_maxncpy)
+ ATTR_NONNULL();
+const char *BLI_str_escape_find_quote(const char *str) ATTR_NONNULL();
size_t BLI_str_format_int_grouped(char dst[16], int num) ATTR_NONNULL();
size_t BLI_str_format_uint64_grouped(char dst[16], uint64_t num) ATTR_NONNULL();
diff --git a/source/blender/blenlib/intern/mesh_intersect.cc b/source/blender/blenlib/intern/mesh_intersect.cc
index 64ea25ccc90..85a6ab42013 100644
--- a/source/blender/blenlib/intern/mesh_intersect.cc
+++ b/source/blender/blenlib/intern/mesh_intersect.cc
@@ -1055,36 +1055,36 @@ static std::ostream &operator<<(std::ostream &os, const CoplanarClusterInfo &cli
enum ITT_value_kind { INONE, IPOINT, ISEGMENT, ICOPLANAR };
struct ITT_value {
- enum ITT_value_kind kind;
mpq3 p1; /* Only relevant for IPOINT and ISEGMENT kind. */
mpq3 p2; /* Only relevant for ISEGMENT kind. */
int t_source; /* Index of the source triangle that intersected the target one. */
+ enum ITT_value_kind kind;
- ITT_value() : kind(INONE), t_source(-1)
+ ITT_value() : t_source(-1), kind(INONE)
{
}
- ITT_value(ITT_value_kind k) : kind(k), t_source(-1)
+ ITT_value(ITT_value_kind k) : t_source(-1), kind(k)
{
}
- ITT_value(ITT_value_kind k, int tsrc) : kind(k), t_source(tsrc)
+ ITT_value(ITT_value_kind k, int tsrc) : t_source(tsrc), kind(k)
{
}
- ITT_value(ITT_value_kind k, const mpq3 &p1) : kind(k), p1(p1), t_source(-1)
+ ITT_value(ITT_value_kind k, const mpq3 &p1) : p1(p1), t_source(-1), kind(k)
{
}
ITT_value(ITT_value_kind k, const mpq3 &p1, const mpq3 &p2)
- : kind(k), p1(p1), p2(p2), t_source(-1)
+ : p1(p1), p2(p2), t_source(-1), kind(k)
{
}
ITT_value(const ITT_value &other)
- : kind(other.kind), p1(other.p1), p2(other.p2), t_source(other.t_source)
+ : p1(other.p1), p2(other.p2), t_source(other.t_source), kind(other.kind)
{
}
ITT_value(ITT_value &&other) noexcept
- : kind(other.kind),
- p1(std::move(other.p1)),
+ : p1(std::move(other.p1)),
p2(std::move(other.p2)),
- t_source(other.t_source)
+ t_source(other.t_source),
+ kind(other.kind)
{
}
~ITT_value()
@@ -2178,8 +2178,8 @@ static void calc_overlap_itts_range_func(void *__restrict userdata,
}
/**
- * Fill in itt_map with the vector of ITT_values that result from intersecting the triangles in ov.
- * Use a canonical order for triangles: (a,b) where a < b.
+ * Fill in itt_map with the vector of ITT_values that result from intersecting the triangles in
+ * ov. Use a canonical order for triangles: (a,b) where a < b.
*/
static void calc_overlap_itts(Map<std::pair<int, int>, ITT_value> &itt_map,
const IMesh &tm,
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 758feef6093..74bbe59bc04 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -264,6 +264,11 @@ void BLI_path_normalize(const char *relabase, char *path)
*/
void BLI_path_normalize_dir(const char *relabase, char *dir)
{
+ /* Would just create an unexpected "/" path, just early exit entirely. */
+ if (dir[0] == '\0') {
+ return;
+ }
+
BLI_path_normalize(relabase, dir);
BLI_path_slash_ensure(dir);
}
diff --git a/source/blender/blenlib/intern/rand.cc b/source/blender/blenlib/intern/rand.cc
index c61e17e6627..8dbfffbad20 100644
--- a/source/blender/blenlib/intern/rand.cc
+++ b/source/blender/blenlib/intern/rand.cc
@@ -21,10 +21,10 @@
* \ingroup bli
*/
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
#include "MEM_guardedalloc.h"
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index 02d12d2df9b..b0d87838d06 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -317,92 +317,135 @@ char *BLI_sprintfN(const char *__restrict format, ...)
return n;
}
-/* match pythons string escaping, assume double quotes - (")
- * TODO: should be used to create RNA animation paths.
- * TODO: support more fancy string escaping. current code is primitive
- * this basically is an ascii version of PyUnicode_EncodeUnicodeEscape()
- * which is a useful reference. */
-size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
+/**
+ * This roughly matches C and Python's string escaping with double quotes - `"`.
+ *
+ * Since every character may need escaping,
+ * it's common to create a buffer twice as large as the input.
+ *
+ * \param dst: The destination string, at least \a dst_maxncpy, typically `(strlen(src) * 2) + 1`.
+ * \param src: The un-escaped source string.
+ * \param dst_maxncpy: The maximum number of bytes allowable to copy.
+ *
+ * \note This is used for creating animation paths in blend files.
+ */
+size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const size_t dst_maxncpy)
{
- size_t len = 0;
- BLI_assert(maxncpy != 0);
+ BLI_assert(dst_maxncpy != 0);
- while (len < maxncpy) {
- switch (*src) {
- case '\0':
- goto escape_finish;
- case '\\':
- case '"':
- ATTR_FALLTHROUGH;
-
- /* less common but should also be support */
- case '\t':
- case '\n':
- case '\r':
- if (len + 1 < maxncpy) {
- *dst++ = '\\';
- len++;
- }
- else {
- /* not enough space to escape */
- break;
- }
- ATTR_FALLTHROUGH;
- default:
- *dst = *src;
+ size_t len = 0;
+ for (; (len < dst_maxncpy) && (*src != '\0'); dst++, src++, len++) {
+ char c = *src;
+ if (ELEM(c, '\\', '"') || /* Use as-is. */
+ ((c == '\t') && ((void)(c = 't'), true)) || /* Tab. */
+ ((c == '\n') && ((void)(c = 'n'), true)) || /* Newline. */
+ ((c == '\r') && ((void)(c = 'r'), true)) || /* Carriage return. */
+ ((c == '\a') && ((void)(c = 'a'), true)) || /* Bell. */
+ ((c == '\b') && ((void)(c = 'b'), true)) || /* Backspace. */
+ ((c == '\f') && ((void)(c = 'f'), true))) /* Form-feed. */
+ {
+ if (UNLIKELY(len + 1 >= dst_maxncpy)) {
+ /* Not enough space to escape. */
break;
+ }
+ *dst++ = '\\';
+ len++;
}
- dst++;
- src++;
- len++;
+ *dst = c;
}
-
-escape_finish:
-
*dst = '\0';
return len;
}
/**
- * Makes a copy of the text within the "" that appear after some text 'blahblah'
- * i.e. for string 'pose["apples"]' with prefix 'pose[', it should grab "apples"
+ * This roughly matches C and Python's string escaping with double quotes - `"`.
+ *
+ * The destination will never be larger than the source, it will either be the same
+ * or up to half when all characters are escaped.
+ *
+ * \param dst: The destination string, at least the size of `strlen(src) + 1`.
+ * \param src: The escaped source string.
+ * \param dst_maxncpy: The maximum number of bytes allowable to copy.
*
- * - str: is the entire string to chop
- * - prefix: is the part of the string to leave out
+ * \note This is used for for parsing animation paths in blend files.
+ */
+size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, const size_t src_maxncpy)
+{
+ size_t len = 0;
+ for (size_t i = 0; i < src_maxncpy && (*src != '\0'); i++, src++) {
+ char c = *src;
+ if (c == '\\') {
+ char c_next = *(src + 1);
+ if (((c_next == '"') && ((void)(c = '"'), true)) || /* Quote. */
+ ((c_next == '\\') && ((void)(c = '\\'), true)) || /* Backslash. */
+ ((c_next == 't') && ((void)(c = '\t'), true)) || /* Tab. */
+ ((c_next == 'n') && ((void)(c = '\n'), true)) || /* Newline. */
+ ((c_next == 'r') && ((void)(c = '\r'), true)) || /* Carriage return. */
+ ((c_next == 'a') && ((void)(c = '\a'), true)) || /* Bell. */
+ ((c_next == 'b') && ((void)(c = '\b'), true)) || /* Backspace. */
+ ((c_next == 'f') && ((void)(c = '\f'), true))) /* Form-feed. */
+ {
+ i++;
+ src++;
+ }
+ }
+
+ dst[len++] = c;
+ }
+ dst[len] = 0;
+ return len;
+}
+
+/**
+ * Find the first un-escaped quote in the string (to find the end of the string).
+ */
+const char *BLI_str_escape_find_quote(const char *str)
+{
+ bool escape = false;
+ while (*str && (*str != '"' || escape)) {
+ /* A pair of back-slashes represents a single back-slash,
+ * only use a single back-slash for escaping. */
+ escape = (escape == false) && (*str == '\\');
+ str++;
+ }
+ return (*str == '"') ? str : NULL;
+}
+
+/**
+ * Makes a copy of the text within the "" that appear after some text `blahblah`.
+ * i.e. for string `pose["apples"]` with prefix `pose[`, it will return `apples`.
*
- * Assume that the strings returned must be freed afterwards, and that the inputs will contain
- * data we want...
+ * \param str: is the entire string to chop.
+ * \param prefix: is the part of the string to step over.
*
- * \return the offset and a length so as to avoid doing an allocation.
+ * Assume that the strings returned must be freed afterwards,
+ * and that the inputs will contain data we want.
*/
char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix)
{
- const char *startMatch, *endMatch;
+ const char *start_match, *end_match;
- /* get the starting point (i.e. where prefix starts, and add prefixLen+1
+ /* get the starting point (i.e. where prefix starts, and add prefix_len+1
* to it to get be after the first " */
- startMatch = strstr(str, prefix);
- if (startMatch) {
- const size_t prefixLen = strlen(prefix);
- startMatch += prefixLen + 1;
+ start_match = strstr(str, prefix);
+ if (start_match) {
+ const size_t prefix_len = strlen(prefix);
+ start_match += prefix_len + 1;
/* get the end point (i.e. where the next occurrence of " is after the starting point) */
-
- endMatch = startMatch;
- while ((endMatch = strchr(endMatch, '"'))) {
- if (LIKELY(*(endMatch - 1) != '\\')) {
- break;
+ end_match = BLI_str_escape_find_quote(start_match);
+ if (end_match) {
+ const size_t unescaped_len = (size_t)(end_match - start_match);
+ char *result = MEM_mallocN(sizeof(char) * (unescaped_len + 1), __func__);
+ const size_t escaped_len = BLI_str_unescape(result, start_match, unescaped_len);
+ if (escaped_len != unescaped_len) {
+ result = MEM_reallocN(result, sizeof(char) * (escaped_len + 1));
}
- endMatch++;
- }
-
- if (endMatch) {
- /* return the slice indicated */
- return BLI_strdupn(startMatch, (size_t)(endMatch - startMatch));
+ return result;
}
}
- return BLI_strdupn("", 0);
+ return NULL;
}
/**
diff --git a/source/blender/blenlib/intern/task_pool.cc b/source/blender/blenlib/intern/task_pool.cc
index 1a119e135d5..dfed24da2d9 100644
--- a/source/blender/blenlib/intern/task_pool.cc
+++ b/source/blender/blenlib/intern/task_pool.cc
@@ -20,8 +20,8 @@
* Task pool to run tasks in parallel.
*/
+#include <cstdlib>
#include <memory>
-#include <stdlib.h>
#include <utility>
#include "MEM_guardedalloc.h"
@@ -149,13 +149,13 @@ class TBBTaskGroup : public tbb::task_group {
/* Task Pool */
-typedef enum TaskPoolType {
+enum TaskPoolType {
TASK_POOL_TBB,
TASK_POOL_TBB_SUSPENDED,
TASK_POOL_NO_THREADS,
TASK_POOL_BACKGROUND,
TASK_POOL_BACKGROUND_SERIAL,
-} TaskPoolType;
+};
struct TaskPool {
TaskPoolType type;
diff --git a/source/blender/blenlib/intern/task_range.cc b/source/blender/blenlib/intern/task_range.cc
index 229129bd088..c2498de1af8 100644
--- a/source/blender/blenlib/intern/task_range.cc
+++ b/source/blender/blenlib/intern/task_range.cc
@@ -20,7 +20,7 @@
* Task parallel range functions.
*/
-#include <stdlib.h>
+#include <cstdlib>
#include "MEM_guardedalloc.h"
diff --git a/source/blender/blenlib/intern/threads.cc b/source/blender/blenlib/intern/threads.cc
index a2b1a12c783..0b88cf53442 100644
--- a/source/blender/blenlib/intern/threads.cc
+++ b/source/blender/blenlib/intern/threads.cc
@@ -21,9 +21,9 @@
* \ingroup bli
*/
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -132,13 +132,13 @@ static int num_threads_override = 0;
/* just a max for security reasons */
#define RE_MAX_THREAD BLENDER_MAX_THREADS
-typedef struct ThreadSlot {
+struct ThreadSlot {
struct ThreadSlot *next, *prev;
void *(*do_thread)(void *);
void *callerdata;
pthread_t pthread;
int avail;
-} ThreadSlot;
+};
void BLI_threadapi_init(void)
{
diff --git a/source/blender/blenlib/tests/BLI_array_store_test.cc b/source/blender/blenlib/tests/BLI_array_store_test.cc
index ff050ce24db..8bbd109fb81 100644
--- a/source/blender/blenlib/tests/BLI_array_store_test.cc
+++ b/source/blender/blenlib/tests/BLI_array_store_test.cc
@@ -32,11 +32,11 @@ static void print_mem_saved(const char *id, const BArrayStore *bs)
/* -------------------------------------------------------------------- */
/* Test Chunks (building data from list of chunks) */
-typedef struct TestChunk {
+struct TestChunk {
struct TestChunk *next, *prev;
const void *data;
size_t data_len;
-} TestChunk;
+};
static TestChunk *testchunk_list_add(ListBase *lb, const void *data, size_t data_len)
{
@@ -111,14 +111,14 @@ static char *testchunk_as_data_array(TestChunk **tc_array, int tc_array_len, siz
/* Test Buffer */
/* API to handle local allocation of data so we can compare it with the data in the array_store */
-typedef struct TestBuffer {
+struct TestBuffer {
struct TestBuffer *next, *prev;
const void *data;
size_t data_len;
/* for reference */
BArrayState *state;
-} TestBuffer;
+};
static TestBuffer *testbuffer_list_add(ListBase *lb, const void *data, size_t data_len)
{
diff --git a/source/blender/blenlib/tests/BLI_expr_pylike_eval_test.cc b/source/blender/blenlib/tests/BLI_expr_pylike_eval_test.cc
index 390f687dbd1..e9ca3c68a71 100644
--- a/source/blender/blenlib/tests/BLI_expr_pylike_eval_test.cc
+++ b/source/blender/blenlib/tests/BLI_expr_pylike_eval_test.cc
@@ -2,7 +2,7 @@
#include "testing/testing.h"
-#include <string.h>
+#include <cstring>
#include "BLI_expr_pylike_eval.h"
#include "BLI_math.h"
diff --git a/source/blender/blenlib/tests/BLI_heap_simple_test.cc b/source/blender/blenlib/tests/BLI_heap_simple_test.cc
index f3a65125eeb..97644fc26ab 100644
--- a/source/blender/blenlib/tests/BLI_heap_simple_test.cc
+++ b/source/blender/blenlib/tests/BLI_heap_simple_test.cc
@@ -1,7 +1,7 @@
/* Apache License, Version 2.0 */
#include "testing/testing.h"
-#include <string.h>
+#include <cstring>
#include "MEM_guardedalloc.h"
diff --git a/source/blender/blenlib/tests/BLI_heap_test.cc b/source/blender/blenlib/tests/BLI_heap_test.cc
index 8b207c17c84..b8fc62e46ca 100644
--- a/source/blender/blenlib/tests/BLI_heap_test.cc
+++ b/source/blender/blenlib/tests/BLI_heap_test.cc
@@ -1,7 +1,7 @@
/* Apache License, Version 2.0 */
#include "testing/testing.h"
-#include <string.h>
+#include <cstring>
#include "MEM_guardedalloc.h"
diff --git a/source/blender/blenlib/tests/BLI_linklist_lockfree_test.cc b/source/blender/blenlib/tests/BLI_linklist_lockfree_test.cc
index f2ae121e8ae..e9810aed179 100644
--- a/source/blender/blenlib/tests/BLI_linklist_lockfree_test.cc
+++ b/source/blender/blenlib/tests/BLI_linklist_lockfree_test.cc
@@ -37,8 +37,8 @@ TEST(LockfreeLinkList, InsertMultiple)
LockfreeLinkNode nodes[num_nodes];
BLI_linklist_lockfree_init(&list);
/* Insert all the nodes. */
- for (int i = 0; i < num_nodes; ++i) {
- BLI_linklist_lockfree_insert(&list, &nodes[i]);
+ for (LockfreeLinkNode &node : nodes) {
+ BLI_linklist_lockfree_insert(&list, &node);
}
/* Check head and tail. */
EXPECT_EQ(list.head, &list.dummy_node);
diff --git a/source/blender/blenlib/tests/BLI_math_rotation_test.cc b/source/blender/blenlib/tests/BLI_math_rotation_test.cc
index 1b1c4ef24a1..02257ba83dd 100644
--- a/source/blender/blenlib/tests/BLI_math_rotation_test.cc
+++ b/source/blender/blenlib/tests/BLI_math_rotation_test.cc
@@ -4,7 +4,7 @@
#include "BLI_math_rotation.h"
-#include <math.h>
+#include <cmath>
/* Test that quaternion converts to itself via matrix. */
static void test_quat_to_mat_to_quat(float w, float x, float y, float z)
diff --git a/source/blender/blenlib/tests/BLI_stack_test.cc b/source/blender/blenlib/tests/BLI_stack_test.cc
index 211916e3193..1fef5998b99 100644
--- a/source/blender/blenlib/tests/BLI_stack_test.cc
+++ b/source/blender/blenlib/tests/BLI_stack_test.cc
@@ -1,7 +1,7 @@
/* Apache License, Version 2.0 */
#include "testing/testing.h"
-#include <string.h>
+#include <cstring>
#include "BLI_array.h"
#include "BLI_stack.h"
diff --git a/source/blender/blenlib/tests/BLI_string_test.cc b/source/blender/blenlib/tests/BLI_string_test.cc
index 58135adbcca..88cecaa5fee 100644
--- a/source/blender/blenlib/tests/BLI_string_test.cc
+++ b/source/blender/blenlib/tests/BLI_string_test.cc
@@ -27,14 +27,14 @@ TEST(string, StrPartition)
{
const char delim[] = {'-', '.', '_', '~', '\\', '\0'};
const char *sep, *suf;
- size_t pre_ln;
+ size_t pre_len;
{
const char *str = "mat.e-r_ial";
/* "mat.e-r_ial" -> "mat", '.', "e-r_ial", 3 */
- pre_ln = BLI_str_partition(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 3);
+ pre_len = BLI_str_partition(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 3);
EXPECT_EQ(&str[3], sep);
EXPECT_STREQ("e-r_ial", suf);
}
@@ -44,8 +44,8 @@ TEST(string, StrPartition)
const char *str = ".mate-rial--";
/* ".mate-rial--" -> "", '.', "mate-rial--", 0 */
- pre_ln = BLI_str_partition(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 0);
+ pre_len = BLI_str_partition(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 0);
EXPECT_EQ(&str[0], sep);
EXPECT_STREQ("mate-rial--", suf);
}
@@ -54,8 +54,8 @@ TEST(string, StrPartition)
const char *str = ".__.--_";
/* ".__.--_" -> "", '.', "__.--_", 0 */
- pre_ln = BLI_str_partition(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 0);
+ pre_len = BLI_str_partition(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 0);
EXPECT_EQ(&str[0], sep);
EXPECT_STREQ("__.--_", suf);
}
@@ -64,8 +64,8 @@ TEST(string, StrPartition)
const char *str = "";
/* "" -> "", NULL, NULL, 0 */
- pre_ln = BLI_str_partition(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 0);
+ pre_len = BLI_str_partition(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 0);
EXPECT_EQ(sep, (void *)nullptr);
EXPECT_EQ(suf, (void *)nullptr);
}
@@ -74,8 +74,8 @@ TEST(string, StrPartition)
const char *str = "material";
/* "material" -> "material", NULL, NULL, 8 */
- pre_ln = BLI_str_partition(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 8);
+ pre_len = BLI_str_partition(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 8);
EXPECT_EQ(sep, (void *)nullptr);
EXPECT_EQ(suf, (void *)nullptr);
}
@@ -86,14 +86,14 @@ TEST(string, StrRPartition)
{
const char delim[] = {'-', '.', '_', '~', '\\', '\0'};
const char *sep, *suf;
- size_t pre_ln;
+ size_t pre_len;
{
const char *str = "mat.e-r_ial";
/* "mat.e-r_ial" -> "mat.e-r", '_', "ial", 7 */
- pre_ln = BLI_str_rpartition(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 7);
+ pre_len = BLI_str_rpartition(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 7);
EXPECT_EQ(&str[7], sep);
EXPECT_STREQ("ial", suf);
}
@@ -103,8 +103,8 @@ TEST(string, StrRPartition)
const char *str = ".mate-rial--";
/* ".mate-rial--" -> ".mate-rial-", '-', "", 11 */
- pre_ln = BLI_str_rpartition(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 11);
+ pre_len = BLI_str_rpartition(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 11);
EXPECT_EQ(&str[11], sep);
EXPECT_STREQ("", suf);
}
@@ -113,8 +113,8 @@ TEST(string, StrRPartition)
const char *str = ".__.--_";
/* ".__.--_" -> ".__.--", '_', "", 6 */
- pre_ln = BLI_str_rpartition(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 6);
+ pre_len = BLI_str_rpartition(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 6);
EXPECT_EQ(&str[6], sep);
EXPECT_STREQ("", suf);
}
@@ -123,8 +123,8 @@ TEST(string, StrRPartition)
const char *str = "";
/* "" -> "", NULL, NULL, 0 */
- pre_ln = BLI_str_rpartition(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 0);
+ pre_len = BLI_str_rpartition(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 0);
EXPECT_EQ(sep, (void *)nullptr);
EXPECT_EQ(suf, (void *)nullptr);
}
@@ -133,8 +133,8 @@ TEST(string, StrRPartition)
const char *str = "material";
/* "material" -> "material", NULL, NULL, 8 */
- pre_ln = BLI_str_rpartition(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 8);
+ pre_len = BLI_str_rpartition(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 8);
EXPECT_EQ(sep, (void *)nullptr);
EXPECT_EQ(suf, (void *)nullptr);
}
@@ -145,7 +145,7 @@ TEST(string, StrPartitionEx)
{
const char delim[] = {'-', '.', '_', '~', '\\', '\0'};
const char *sep, *suf;
- size_t pre_ln;
+ size_t pre_len;
/* Only considering 'from_right' cases here. */
@@ -153,8 +153,8 @@ TEST(string, StrPartitionEx)
const char *str = "mat.e-r_ia.l";
/* "mat.e-r_ia.l" over "mat.e-r" -> "mat.e", '.', "r_ia.l", 3 */
- pre_ln = BLI_str_partition_ex(str, str + 6, delim, &sep, &suf, true);
- EXPECT_EQ(pre_ln, 5);
+ pre_len = BLI_str_partition_ex(str, str + 6, delim, &sep, &suf, true);
+ EXPECT_EQ(pre_len, 5);
EXPECT_EQ(&str[5], sep);
EXPECT_STREQ("r_ia.l", suf);
}
@@ -164,8 +164,8 @@ TEST(string, StrPartitionEx)
const char *str = "mate.rial";
/* "mate.rial" over "mate" -> "mate.rial", NULL, NULL, 4 */
- pre_ln = BLI_str_partition_ex(str, str + 4, delim, &sep, &suf, true);
- EXPECT_EQ(pre_ln, 4);
+ pre_len = BLI_str_partition_ex(str, str + 4, delim, &sep, &suf, true);
+ EXPECT_EQ(pre_len, 4);
EXPECT_EQ(sep, (void *)nullptr);
EXPECT_EQ(suf, (void *)nullptr);
}
@@ -176,14 +176,14 @@ TEST(string, StrPartitionUtf8)
{
const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
const char *sep, *suf;
- size_t pre_ln;
+ size_t pre_len;
{
const char *str = "ma\xc3\xb1te-r\xe2\x98\xafial";
/* "ma\xc3\xb1te-r\xe2\x98\xafial" -> "ma", '\xc3\xb1', "te-r\xe2\x98\xafial", 2 */
- pre_ln = BLI_str_partition_utf8(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 2);
+ pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 2);
EXPECT_EQ(&str[2], sep);
EXPECT_STREQ("te-r\xe2\x98\xafial", suf);
}
@@ -193,8 +193,8 @@ TEST(string, StrPartitionUtf8)
const char *str = "\xe2\x98\xafmate-rial-\xc3\xb1";
/* "\xe2\x98\xafmate-rial-\xc3\xb1" -> "", '\xe2\x98\xaf', "mate-rial-\xc3\xb1", 0 */
- pre_ln = BLI_str_partition_utf8(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 0);
+ pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 0);
EXPECT_EQ(&str[0], sep);
EXPECT_STREQ("mate-rial-\xc3\xb1", suf);
}
@@ -203,8 +203,8 @@ TEST(string, StrPartitionUtf8)
const char *str = "\xe2\x98\xaf.\xc3\xb1_.--\xc3\xb1";
/* "\xe2\x98\xaf.\xc3\xb1_.--\xc3\xb1" -> "", '\xe2\x98\xaf', ".\xc3\xb1_.--\xc3\xb1", 0 */
- pre_ln = BLI_str_partition_utf8(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 0);
+ pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 0);
EXPECT_EQ(&str[0], sep);
EXPECT_STREQ(".\xc3\xb1_.--\xc3\xb1", suf);
}
@@ -213,8 +213,8 @@ TEST(string, StrPartitionUtf8)
const char *str = "";
/* "" -> "", NULL, NULL, 0 */
- pre_ln = BLI_str_partition_utf8(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 0);
+ pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 0);
EXPECT_EQ(sep, (void *)nullptr);
EXPECT_EQ(suf, (void *)nullptr);
}
@@ -223,8 +223,8 @@ TEST(string, StrPartitionUtf8)
const char *str = "material";
/* "material" -> "material", NULL, NULL, 8 */
- pre_ln = BLI_str_partition_utf8(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 8);
+ pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 8);
EXPECT_EQ(sep, (void *)nullptr);
EXPECT_EQ(suf, (void *)nullptr);
}
@@ -235,14 +235,14 @@ TEST(string, StrRPartitionUtf8)
{
const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
const char *sep, *suf;
- size_t pre_ln;
+ size_t pre_len;
{
const char *str = "ma\xc3\xb1te-r\xe2\x98\xafial";
/* "ma\xc3\xb1te-r\xe2\x98\xafial" -> "mat\xc3\xb1te-r", '\xe2\x98\xaf', "ial", 8 */
- pre_ln = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 8);
+ pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 8);
EXPECT_EQ(&str[8], sep);
EXPECT_STREQ("ial", suf);
}
@@ -252,8 +252,8 @@ TEST(string, StrRPartitionUtf8)
const char *str = "\xe2\x98\xafmate-rial-\xc3\xb1";
/* "\xe2\x98\xafmate-rial-\xc3\xb1" -> "\xe2\x98\xafmate-rial-", '\xc3\xb1', "", 13 */
- pre_ln = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 13);
+ pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 13);
EXPECT_EQ(&str[13], sep);
EXPECT_STREQ("", suf);
}
@@ -262,8 +262,8 @@ TEST(string, StrRPartitionUtf8)
const char *str = "\xe2\x98\xaf.\xc3\xb1_.--\xc3\xb1";
/* "\xe2\x98\xaf.\xc3\xb1_.--\xc3\xb1" -> "\xe2\x98\xaf.\xc3\xb1_.--", '\xc3\xb1', "", 10 */
- pre_ln = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 10);
+ pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 10);
EXPECT_EQ(&str[10], sep);
EXPECT_STREQ("", suf);
}
@@ -272,8 +272,8 @@ TEST(string, StrRPartitionUtf8)
const char *str = "";
/* "" -> "", NULL, NULL, 0 */
- pre_ln = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 0);
+ pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 0);
EXPECT_EQ(sep, (void *)nullptr);
EXPECT_EQ(suf, (void *)nullptr);
}
@@ -282,8 +282,8 @@ TEST(string, StrRPartitionUtf8)
const char *str = "material";
/* "material" -> "material", NULL, NULL, 8 */
- pre_ln = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
- EXPECT_EQ(pre_ln, 8);
+ pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
+ EXPECT_EQ(pre_len, 8);
EXPECT_EQ(sep, (void *)nullptr);
EXPECT_EQ(suf, (void *)nullptr);
}
@@ -294,7 +294,7 @@ TEST(string, StrPartitionExUtf8)
{
const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
const char *sep, *suf;
- size_t pre_ln;
+ size_t pre_len;
/* Only considering 'from_right' cases here. */
@@ -303,8 +303,8 @@ TEST(string, StrPartitionExUtf8)
/* "ma\xc3\xb1te-r\xe2\x98\xafial" over
* "ma\xc3\xb1te" -> "ma", '\xc3\xb1', "te-r\xe2\x98\xafial", 2 */
- pre_ln = BLI_str_partition_ex_utf8(str, str + 6, delim, &sep, &suf, true);
- EXPECT_EQ(pre_ln, 2);
+ pre_len = BLI_str_partition_ex_utf8(str, str + 6, delim, &sep, &suf, true);
+ EXPECT_EQ(pre_len, 2);
EXPECT_EQ(&str[2], sep);
EXPECT_STREQ("te-r\xe2\x98\xafial", suf);
}
@@ -314,8 +314,8 @@ TEST(string, StrPartitionExUtf8)
const char *str = "mate\xe2\x98\xafrial";
/* "mate\xe2\x98\xafrial" over "mate" -> "mate\xe2\x98\xafrial", NULL, NULL, 4 */
- pre_ln = BLI_str_partition_ex_utf8(str, str + 4, delim, &sep, &suf, true);
- EXPECT_EQ(pre_ln, 4);
+ pre_len = BLI_str_partition_ex_utf8(str, str + 4, delim, &sep, &suf, true);
+ EXPECT_EQ(pre_len, 4);
EXPECT_EQ(sep, (void *)nullptr);
EXPECT_EQ(suf, (void *)nullptr);
}
@@ -802,3 +802,76 @@ TEST_F(StringCasecmpNatural, TextAndNumbers)
testReturnsLessThanZeroForAll(negative);
testReturnsMoreThanZeroForAll(positive);
}
+
+/* BLI_str_escape, BLI_str_unescape */
+
+class StringEscape : public testing::Test {
+ protected:
+ StringEscape()
+ {
+ }
+
+ using CompareWordsArray = vector<std::array<const char *, 2>>;
+
+ void testEscapeWords(const CompareWordsArray &items)
+ {
+ size_t dst_test_len;
+ char dst_test[64];
+ for (const auto &item : items) {
+ /* Escape the string. */
+ dst_test_len = BLI_str_escape(dst_test, item[0], SIZE_MAX);
+ EXPECT_STREQ(dst_test, item[1]);
+ EXPECT_EQ(dst_test_len, strlen(dst_test));
+ /* Escape back. */
+ dst_test_len = BLI_str_unescape(dst_test, item[1], strlen(item[1]));
+ EXPECT_STREQ(dst_test, item[0]);
+ EXPECT_EQ(dst_test_len, strlen(dst_test));
+ }
+ }
+};
+
+TEST_F(StringEscape, Simple)
+{
+ const CompareWordsArray equal{
+ {"", ""},
+ {"/", "/"},
+ {"'", "'"},
+ {"?", "?"},
+ };
+
+ const CompareWordsArray escaped{
+ {"\\", "\\\\"},
+ {"A\\", "A\\\\"},
+ {"\\A", "\\\\A"},
+ {"A\\B", "A\\\\B"},
+ {"?", "?"},
+ {"\"\\", "\\\"\\\\"},
+ {"\\\"", "\\\\\\\""},
+ {"\"\\\"", "\\\"\\\\\\\""},
+
+ {"\"\"\"", "\\\"\\\"\\\""},
+ {"\\\\\\", "\\\\\\\\\\\\"},
+ };
+
+ testEscapeWords(equal);
+ testEscapeWords(escaped);
+}
+
+TEST_F(StringEscape, Control)
+{
+ const CompareWordsArray escaped{
+ {"\n", "\\n"},
+ {"\r", "\\r"},
+ {"\t", "\\t"},
+ {"\a", "\\a"},
+ {"\b", "\\b"},
+ {"\f", "\\f"},
+ {"A\n", "A\\n"},
+ {"\nA", "\\nA"},
+ {"\n\r\t\a\b\f", "\\n\\r\\t\\a\\b\\f"},
+ {"\n_\r_\t_\a_\b_\f", "\\n_\\r_\\t_\\a_\\b_\\f"},
+ {"\n\\\r\\\t\\\a\\\b\\\f", "\\n\\\\\\r\\\\\\t\\\\\\a\\\\\\b\\\\\\f"},
+ };
+
+ testEscapeWords(escaped);
+}
diff --git a/source/blender/blenlib/tests/BLI_task_test.cc b/source/blender/blenlib/tests/BLI_task_test.cc
index 2a3fddf5e3d..fce3e56d105 100644
--- a/source/blender/blenlib/tests/BLI_task_test.cc
+++ b/source/blender/blenlib/tests/BLI_task_test.cc
@@ -1,7 +1,7 @@
/* Apache License, Version 2.0 */
#include "testing/testing.h"
-#include <string.h>
+#include <cstring>
#include "atomic_ops.h"
diff --git a/source/blender/blenloader/intern/blend_validate.c b/source/blender/blenloader/intern/blend_validate.c
index 2848aac2c77..c281e2fa643 100644
--- a/source/blender/blenloader/intern/blend_validate.c
+++ b/source/blender/blenloader/intern/blend_validate.c
@@ -148,7 +148,7 @@ bool BLO_main_validate_libraries(Main *bmain, ReportList *reports)
}
}
- BLI_linklist_free(names, free);
+ BLI_linklist_freeN(names);
}
BLO_blendhandle_close(bh);
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index 7a527b82e9f..1aecba5ba90 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -134,7 +134,7 @@ void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp)
* \param bh: The blendhandle to access.
* \param ofblocktype: The type of names to get.
* \param tot_names: The length of the returned list.
- * \return A BLI_linklist of strings. The string links should be freed with malloc.
+ * \return A BLI_linklist of strings. The string links should be freed with #MEM_freeN().
*/
LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype, int *tot_names)
{
@@ -147,7 +147,7 @@ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype,
if (bhead->code == ofblocktype) {
const char *idname = blo_bhead_id_name(fd, bhead);
- BLI_linklist_prepend(&names, strdup(idname + 2));
+ BLI_linklist_prepend(&names, BLI_strdup(idname + 2));
tot++;
}
else if (bhead->code == ENDB) {
@@ -254,7 +254,7 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *to
* (e.g. "Scene", "Mesh", "Light", etc.).
*
* \param bh: The blendhandle to access.
- * \return A BLI_linklist of strings. The string links should be freed with malloc.
+ * \return A BLI_linklist of strings. The string links should be freed with #MEM_freeN().
*/
LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh)
{
@@ -272,7 +272,7 @@ LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh)
const char *str = BKE_idtype_idcode_to_name(bhead->code);
if (BLI_gset_add(gathered, (void *)str)) {
- BLI_linklist_prepend(&names, strdup(str));
+ BLI_linklist_prepend(&names, BLI_strdup(str));
}
}
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 2c10dd446f1..9ce767b7ce1 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2834,10 +2834,8 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
tselem->id = NULL;
}
}
- if (space_outliner->treehash) {
- /* rebuild hash table, because it depends on ids too */
- space_outliner->storeflag |= SO_TREESTORE_REBUILD;
- }
+ /* rebuild hash table, because it depends on ids too */
+ space_outliner->storeflag |= SO_TREESTORE_REBUILD;
}
}
else if (sl->spacetype == SPACE_NODE) {
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index 9278ff51b8d..a98e7c46f10 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -181,7 +181,7 @@ static void seq_convert_transform_crop(const Scene *scene,
/* Convert offset animation, but only if crop is not used. */
if ((seq->flag & use_transform_flag) != 0 && (seq->flag & use_crop_flag) == 0) {
char name_esc[(sizeof(seq->name) - 2) * 2], *path;
- BLI_strescape(name_esc, seq->name + 2, sizeof(name_esc));
+ BLI_str_escape(name_esc, seq->name + 2, sizeof(name_esc));
path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].transform.offset_x", name_esc);
seq_convert_transform_animation(scene, path, image_size_x);
@@ -408,7 +408,7 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
const size_t node_name_escaped_max_length = (node_name_length * 2);
char *node_name_escaped = MEM_mallocN(node_name_escaped_max_length + 1,
"escaped name");
- BLI_strescape(node_name_escaped, node->name, node_name_escaped_max_length);
+ BLI_str_escape(node_name_escaped, node->name, node_name_escaped_max_length);
char *rna_path_prefix = BLI_sprintfN("nodes[\"%s\"].inputs", node_name_escaped);
BKE_animdata_fix_paths_rename_all_ex(
@@ -483,6 +483,13 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
}
}
}
+
+ /* Wet Paint Radius Factor */
+ for (Brush *br = bmain->brushes.first; br; br = br->id.next) {
+ if (br->ob_mode & OB_MODE_SCULPT && br->wet_paint_radius_factor == 0.0f) {
+ br->wet_paint_radius_factor = 1.0f;
+ }
+ }
}
static void panels_remove_x_closed_flag_recursive(Panel *panel)
@@ -1164,17 +1171,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
- /**
- * Versioning code until next subversion bump goes here.
- *
- * \note Be sure to check when bumping the version:
- * - "versioning_userdef.c", #blo_do_versions_userdef
- * - "versioning_userdef.c", #do_versions_theme
- *
- * \note Keep this message at the bottom of the function.
- */
- {
- /* Keep this block, even when empty. */
+ if (!MAIN_VERSION_ATLEAST(bmain, 292, 5)) {
/* Initialize the opacity of the overlay wireframe */
if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "wireframe_opacity")) {
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
@@ -1223,5 +1220,28 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
LISTBASE_FOREACH (PointCloud *, pointcloud, &bmain->pointclouds) {
do_versions_point_attribute_names(&pointcloud->pdata);
}
+
+ /* Cryptomatte render pass */
+ if (!DNA_struct_elem_find(fd->filesdna, "ViewLayer", "short", "cryptomatte_levels")) {
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ view_layer->cryptomatte_levels = 6;
+ view_layer->cryptomatte_flag = VIEW_LAYER_CRYPTOMATTE_ACCURATE;
+ }
+ }
+ }
+ }
+
+ /**
+ * Versioning code until next subversion bump goes here.
+ *
+ * \note Be sure to check when bumping the version:
+ * - "versioning_userdef.c", #blo_do_versions_userdef
+ * - "versioning_userdef.c", #do_versions_theme
+ *
+ * \note Keep this message at the bottom of the function.
+ */
+ {
+ /* Keep this block, even when empty. */
}
}
diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c
index f9050183dda..7bc11317bb4 100644
--- a/source/blender/blenloader/intern/versioning_userdef.c
+++ b/source/blender/blenloader/intern/versioning_userdef.c
@@ -246,6 +246,19 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
FROM_DEFAULT_V4_UCHAR(space_graph.vertex_active);
}
+ if (!USER_VERSION_ATLEAST(292, 5)) {
+ for (int i = 0; i < COLLECTION_COLOR_TOT; ++i) {
+ FROM_DEFAULT_V4_UCHAR(collection_color[i].color);
+ }
+ FROM_DEFAULT_V4_UCHAR(space_sequencer.row_alternate);
+ FROM_DEFAULT_V4_UCHAR(space_node.nodeclass_geometry);
+ FROM_DEFAULT_V4_UCHAR(space_node.nodeclass_attribute);
+ }
+
+ if (!USER_VERSION_ATLEAST(292, 6)) {
+ FROM_DEFAULT_V4_UCHAR(space_node.nodeclass_shader);
+ }
+
/**
* Versioning code until next subversion bump goes here.
*
@@ -257,12 +270,6 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
*/
{
/* Keep this block, even when empty. */
- for (int i = 0; i < COLLECTION_COLOR_TOT; ++i) {
- FROM_DEFAULT_V4_UCHAR(collection_color[i].color);
- }
- FROM_DEFAULT_V4_UCHAR(space_sequencer.row_alternate);
- FROM_DEFAULT_V4_UCHAR(space_node.nodeclass_geometry);
- FROM_DEFAULT_V4_UCHAR(space_node.nodeclass_attribute);
}
#undef FROM_DEFAULT_V4_UCHAR
@@ -814,10 +821,6 @@ void blo_do_versions_userdef(UserDef *userdef)
userdef->uiflag &= ~USER_UIFLAG_UNUSED_3;
}
- if (!USER_VERSION_ATLEAST(292, 4)) {
- userdef->animation_flag = USER_ANIM_SHOW_CHANNEL_GROUP_COLORS;
- }
-
/**
* Versioning code until next subversion bump goes here.
*
diff --git a/source/blender/blenloader/tests/blendfile_loading_base_test.cc b/source/blender/blenloader/tests/blendfile_loading_base_test.cc
index a3aabf6ac10..8d8dc3aebf7 100644
--- a/source/blender/blenloader/tests/blendfile_loading_base_test.cc
+++ b/source/blender/blenloader/tests/blendfile_loading_base_test.cc
@@ -103,7 +103,7 @@ void BlendfileLoadingBaseTest::TearDownTestCase()
BKE_blender_atexit();
BKE_tempdir_session_purge();
-
+ BKE_appdir_exit();
CLG_exit();
testing::Test::TearDownTestCase();
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 05b84ba21e2..4ce70e7bd5a 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -182,7 +182,7 @@ static BMOpDefine bmo_smooth_laplacian_vert_def = {
static BMOpDefine bmo_recalc_face_normals_def = {
"recalc_face_normals",
/* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
{{'\0'}},
},
{{{'\0'}}}, /* no output */
@@ -485,8 +485,7 @@ static BMOpDefine bmo_collapse_uvs_def = {
static BMOpDefine bmo_weld_verts_def = {
"weld_verts",
/* slots_in */
- /* maps welded vertices to verts they should weld to */
- {{"targetmap", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {{"targetmap", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, /* maps welded vertices to verts they should weld to */
{{'\0'}},
},
{{{'\0'}}}, /* no output */
@@ -527,11 +526,11 @@ static BMOpDefine bmo_join_triangles_def = {
"join_triangles",
/* slots_in */
{{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input geometry. */
- {"cmp_seam", BMO_OP_SLOT_BOOL},
- {"cmp_sharp", BMO_OP_SLOT_BOOL},
- {"cmp_uvs", BMO_OP_SLOT_BOOL},
- {"cmp_vcols", BMO_OP_SLOT_BOOL},
- {"cmp_materials", BMO_OP_SLOT_BOOL},
+ {"cmp_seam", BMO_OP_SLOT_BOOL}, /* Compare seam */
+ {"cmp_sharp", BMO_OP_SLOT_BOOL}, /* Compare sharp */
+ {"cmp_uvs", BMO_OP_SLOT_BOOL}, /* Compare UVs */
+ {"cmp_vcols", BMO_OP_SLOT_BOOL}, /* compare VCols */
+ {"cmp_materials", BMO_OP_SLOT_BOOL}, /* compare materials */
{"angle_face_threshold", BMO_OP_SLOT_FLT},
{"angle_shape_threshold", BMO_OP_SLOT_FLT},
{{'\0'}},
@@ -587,9 +586,9 @@ static BMOpDefine bmo_bridge_loops_def = {
{{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
{"use_pairs", BMO_OP_SLOT_BOOL},
{"use_cyclic", BMO_OP_SLOT_BOOL},
- {"use_merge", BMO_OP_SLOT_BOOL},
- {"merge_factor", BMO_OP_SLOT_FLT},
- {"twist_offset", BMO_OP_SLOT_INT},
+ {"use_merge", BMO_OP_SLOT_BOOL}, /* merge rather than creating faces */
+ {"merge_factor", BMO_OP_SLOT_FLT}, /* merge factor */
+ {"twist_offset", BMO_OP_SLOT_INT}, /* twist offset for closed loops */
{{'\0'}},
},
/* slots_out */
@@ -831,8 +830,8 @@ static BMOpDefine bmo_transform_def = {
static BMOpDefine bmo_object_load_bmesh_def = {
"object_load_bmesh",
/* slots_in */
- {{"scene", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_SCENE}},
- {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
+ {{"scene", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_SCENE}}, /* pointer to an scene structure */
+ {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}}, /* pointer to an object structure */
{{'\0'}},
},
{{{'\0'}}}, /* no output */
@@ -850,10 +849,8 @@ static BMOpDefine bmo_bmesh_to_mesh_def = {
"bmesh_to_mesh",
/* slots_in */
{
- /* pointer to a mesh structure to fill in */
- {"mesh", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
- /* pointer to an object structure */
- {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
+ {"mesh", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_MESH}}, /* pointer to a mesh structure to fill in */
+ {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}}, /* pointer to an object structure */
{{'\0'}},
},
{{{'\0'}}}, /* no output */
@@ -871,10 +868,8 @@ static BMOpDefine bmo_mesh_to_bmesh_def = {
"mesh_to_bmesh",
/* slots_in */
{
- /* pointer to a Mesh structure */
- {"mesh", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
- /* pointer to an Object structure */
- {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
+ {"mesh", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_MESH}}, /* pointer to a Mesh structure */
+ {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}}, /* pointer to an Object structure */
{"use_shapekey", BMO_OP_SLOT_BOOL}, /* load active shapekey coordinates into verts */
{{'\0'}},
},
@@ -955,8 +950,8 @@ static BMOpDefine bmo_extrude_vert_indiv_def = {
static BMOpDefine bmo_connect_verts_def = {
"connect_verts",
/* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
- {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces to explicitly exclude from connecting */
{"check_degenerate", BMO_OP_SLOT_BOOL}, /* prevent splits with overlaps & intersections */
{{'\0'}},
},
@@ -978,7 +973,7 @@ static BMOpDefine bmo_connect_verts_def = {
static BMOpDefine bmo_connect_verts_concave_def = {
"connect_verts_concave",
/* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
{{'\0'}},
},
/* slots_out */
@@ -1001,7 +996,7 @@ static BMOpDefine bmo_connect_verts_nonplanar_def = {
"connect_verts_nonplanar",
/* slots_in */
{{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
- {"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
{{'\0'}},
},
/* slots_out */
@@ -1023,9 +1018,9 @@ static BMOpDefine bmo_connect_verts_nonplanar_def = {
static BMOpDefine bmo_connect_vert_pair_def = {
"connect_vert_pair",
/* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
- {"verts_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
- {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"verts_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices to explicitly exclude from connecting */
+ {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces to explicitly exclude from connecting */
{{'\0'}},
},
/* slots_out */
@@ -1048,7 +1043,7 @@ static BMOpDefine bmo_extrude_face_region_def = {
"extrude_face_region",
/* slots_in */
{{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* edges and faces */
- {"edges_exclude", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_EMPTY}},
+ {"edges_exclude", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_EMPTY}}, /* input edges to explicitly exclude from extrusion */
{"use_keep_orig", BMO_OP_SLOT_BOOL}, /* keep original geometry (requires ``geom`` to include edges). */
{"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
{"use_normal_from_adjacent", BMO_OP_SLOT_BOOL}, /* Use winding from surrounding faces instead of this region. */
@@ -1070,9 +1065,9 @@ static BMOpDefine bmo_extrude_face_region_def = {
static BMOpDefine bmo_dissolve_verts_def = {
"dissolve_verts",
/* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
- {"use_face_split", BMO_OP_SLOT_BOOL},
- {"use_boundary_tear", BMO_OP_SLOT_BOOL},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"use_face_split", BMO_OP_SLOT_BOOL}, /* split off face corners to maintain surrounding geometry */
+ {"use_boundary_tear", BMO_OP_SLOT_BOOL}, /* split off face corners instead of merging faces */
{{'\0'}},
},
{{{'\0'}}}, /* no output */
@@ -1089,9 +1084,9 @@ static BMOpDefine bmo_dissolve_verts_def = {
static BMOpDefine bmo_dissolve_edges_def = {
"dissolve_edges",
/* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
{"use_verts", BMO_OP_SLOT_BOOL}, /* dissolve verts left between only 2 edges. */
- {"use_face_split", BMO_OP_SLOT_BOOL},
+ {"use_face_split", BMO_OP_SLOT_BOOL}, /* split off face corners to maintain surrounding geometry */
{{'\0'}},
},
/* slots_out */
@@ -1111,7 +1106,7 @@ static BMOpDefine bmo_dissolve_edges_def = {
static BMOpDefine bmo_dissolve_faces_def = {
"dissolve_faces",
/* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
{"use_verts", BMO_OP_SLOT_BOOL}, /* dissolve verts left between only 2 edges. */
{{'\0'}},
},
@@ -1144,10 +1139,10 @@ static BMOpDefine bmo_dissolve_limit_def = {
"dissolve_limit",
/* slots_in */
{{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
- {"use_dissolve_boundaries", BMO_OP_SLOT_BOOL},
- {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
- {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
- {"delimit", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_FLAG}, bmo_enum_dissolve_limit_flags},
+ {"use_dissolve_boundaries", BMO_OP_SLOT_BOOL}, /* dissolve all vertices in between face boundaries */
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {"delimit", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_FLAG}, bmo_enum_dissolve_limit_flags}, /* delimit dissolve operation */
{{'\0'}},
},
/* slots_out */
@@ -1169,7 +1164,7 @@ static BMOpDefine bmo_dissolve_degenerate_def = {
"dissolve_degenerate",
/* slots_in */
{{"dist", BMO_OP_SLOT_FLT}, /* maximum distance to consider degenerate */
- {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
{{'\0'}},
},
/* slots_out */
@@ -1201,9 +1196,9 @@ static BMO_FlagSet bmo_enum_triangulate_ngon_method[] = {
static BMOpDefine bmo_triangulate_def = {
"triangulate",
/* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
- {"quad_method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_triangulate_quad_method},
- {"ngon_method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_triangulate_ngon_method},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"quad_method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_triangulate_quad_method}, /* method for splitting the quads into triangles */
+ {"ngon_method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_triangulate_ngon_method}, /* method for splitting the polygons into triangles */
{{'\0'}},
},
/* slots_out */
@@ -1228,7 +1223,7 @@ static BMOpDefine bmo_unsubdivide_def = {
"unsubdivide",
/* slots_in */
{{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
- {"iterations", BMO_OP_SLOT_INT},
+ {"iterations", BMO_OP_SLOT_INT}, /* number of times to unsubdivide */
{{'\0'}},
},
{{{'\0'}}}, /* no output */
@@ -1256,13 +1251,13 @@ static BMO_FlagSet bmo_enum_subdivide_edges_quad_corner_type[] = {
static BMOpDefine bmo_subdivide_edges_def = {
"subdivide_edges",
/* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
- {"smooth", BMO_OP_SLOT_FLT},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {"smooth", BMO_OP_SLOT_FLT}, /* smoothness factor */
{"smooth_falloff", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_falloff_type}, /* smooth falloff type */
- {"fractal", BMO_OP_SLOT_FLT},
- {"along_normal", BMO_OP_SLOT_FLT},
- {"cuts", BMO_OP_SLOT_INT},
- {"seed", BMO_OP_SLOT_INT},
+ {"fractal", BMO_OP_SLOT_FLT}, /* fractal randomness factor */
+ {"along_normal", BMO_OP_SLOT_FLT}, /* apply fractal displacement along normal only */
+ {"cuts", BMO_OP_SLOT_INT}, /* number of cuts */
+ {"seed", BMO_OP_SLOT_INT}, /* seed for the random number generator */
{"custom_patterns", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL}}, /* uses custom pointers */
{"edge_percents", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_FLT}},
{"quad_corner_type", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_subdivide_edges_quad_corner_type}, /* quad corner type */
@@ -1304,10 +1299,10 @@ static BMOpDefine bmo_subdivide_edgering_def = {
/* slots_in */
{{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input vertices */
{"interp_mode", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_subdivide_edgering_interp_mode}, /* interpolation method */
- {"smooth", BMO_OP_SLOT_FLT},
- {"cuts", BMO_OP_SLOT_INT},
+ {"smooth", BMO_OP_SLOT_FLT}, /* smoothness factor */
+ {"cuts", BMO_OP_SLOT_INT}, /* number of cuts */
{"profile_shape", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_falloff_type}, /* profile shape type */
- {"profile_shape_factor", BMO_OP_SLOT_FLT},
+ {"profile_shape_factor", BMO_OP_SLOT_FLT}, /* how much intermediary new edges are shrunk/expanded */
{{'\0'}},
},
{{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
@@ -1327,7 +1322,7 @@ static BMOpDefine bmo_subdivide_edgering_def = {
static BMOpDefine bmo_bisect_plane_def = {
"bisect_plane",
/* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
{"dist", BMO_OP_SLOT_FLT}, /* minimum distance when testing if a vert is exactly on the plane */
{"plane_co", BMO_OP_SLOT_VEC}, /* point on the plane */
{"plane_no", BMO_OP_SLOT_VEC}, /* direction of the plane */
@@ -1365,7 +1360,7 @@ static BMO_FlagSet bmo_enum_delete_context[] = {
static BMOpDefine bmo_delete_def = {
"delete",
/* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
{"context", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_delete_context}, /* geometry types to delete */
{{'\0'}},
},
@@ -1385,9 +1380,8 @@ static BMOpDefine bmo_delete_def = {
static BMOpDefine bmo_duplicate_def = {
"duplicate",
/* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- /* destination bmesh, if NULL will use current on */
- {"dest", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
+ {"dest", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_BMESH}}, /* destination bmesh, if NULL will use current on */
{"use_select_history", BMO_OP_SLOT_BOOL},
{"use_edge_flip_from_face", BMO_OP_SLOT_BOOL},
{{'\0'}},
@@ -1418,9 +1412,8 @@ static BMOpDefine bmo_duplicate_def = {
static BMOpDefine bmo_split_def = {
"split",
/* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- /* destination bmesh, if NULL will use current one */
- {"dest", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
+ {"dest", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_BMESH}}, /* destination bmesh, if NULL will use current one */
{"use_only_faces", BMO_OP_SLOT_BOOL}, /* when enabled. don't duplicate loose verts/edges */
{{'\0'}},
},
@@ -1444,7 +1437,7 @@ static BMOpDefine bmo_split_def = {
static BMOpDefine bmo_spin_def = {
"spin",
/* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
{"cent", BMO_OP_SLOT_VEC}, /* rotation center */
{"axis", BMO_OP_SLOT_VEC}, /* rotation axis */
{"dvec", BMO_OP_SLOT_VEC}, /* translation delta per step */
@@ -1657,7 +1650,7 @@ static BMOpDefine bmo_create_cone_def = {
/* slots_in */
{{"cap_ends", BMO_OP_SLOT_BOOL}, /* whether or not to fill in the ends with faces */
{"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */
- {"segments", BMO_OP_SLOT_INT},
+ {"segments", BMO_OP_SLOT_INT}, /* number of vertices in the base circle */
{"diameter1", BMO_OP_SLOT_FLT}, /* diameter of one end */
{"diameter2", BMO_OP_SLOT_FLT}, /* diameter of the opposite */
{"depth", BMO_OP_SLOT_FLT}, /* distance between ends */
@@ -1682,7 +1675,7 @@ static BMOpDefine bmo_create_circle_def = {
/* slots_in */
{{"cap_ends", BMO_OP_SLOT_BOOL}, /* whether or not to fill in the ends with faces */
{"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */
- {"segments", BMO_OP_SLOT_INT},
+ {"segments", BMO_OP_SLOT_INT}, /* number of vertices in the circle */
{"radius", BMO_OP_SLOT_FLT}, /* Radius of the circle. */
{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
{"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
@@ -1795,7 +1788,7 @@ static BMOpDefine bmo_bevel_def = {
{"smoothresh", BMO_OP_SLOT_FLT}, /* for passing mesh's smoothresh, used in hardening */
{"custom_profile", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_STRUCT}}, /* CurveProfile */
{"vmesh_method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM},
- bmo_enum_bevel_vmesh_method},
+ bmo_enum_bevel_vmesh_method}, /* The method to use to create meshes at intersections. */
{{'\0'}},
},
/* slots_out */
@@ -1852,7 +1845,7 @@ static BMOpDefine bmo_beautify_fill_def = {
static BMOpDefine bmo_triangle_fill_def = {
"triangle_fill",
/* slots_in */
- {{"use_beauty", BMO_OP_SLOT_BOOL},
+ {{"use_beauty", BMO_OP_SLOT_BOOL}, /* use best triangulation division */
{"use_dissolve", BMO_OP_SLOT_BOOL}, /* dissolve resulting faces */
{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
{"normal", BMO_OP_SLOT_VEC}, /* optionally pass the fill normal to use */
@@ -1876,8 +1869,8 @@ static BMOpDefine bmo_triangle_fill_def = {
static BMOpDefine bmo_solidify_def = {
"solidify",
/* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"thickness", BMO_OP_SLOT_FLT},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
+ {"thickness", BMO_OP_SLOT_FLT}, /* thickness */
{{'\0'}},
},
/* slots_out */
@@ -1898,11 +1891,11 @@ static BMOpDefine bmo_inset_individual_def = {
"inset_individual",
/* slots_in */
{{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
- {"thickness", BMO_OP_SLOT_FLT},
- {"depth", BMO_OP_SLOT_FLT},
- {"use_even_offset", BMO_OP_SLOT_BOOL},
- {"use_interpolate", BMO_OP_SLOT_BOOL},
- {"use_relative_offset", BMO_OP_SLOT_BOOL},
+ {"thickness", BMO_OP_SLOT_FLT}, /* thickness */
+ {"depth", BMO_OP_SLOT_FLT}, /* depth */
+ {"use_even_offset", BMO_OP_SLOT_BOOL}, /* scale the offset to give more even thickness */
+ {"use_interpolate", BMO_OP_SLOT_BOOL}, /* blend face data across the inset */
+ {"use_relative_offset", BMO_OP_SLOT_BOOL}, /* scale the offset by surrounding geometry */
{{'\0'}},
},
/* slots_out */
@@ -1923,15 +1916,15 @@ static BMOpDefine bmo_inset_region_def = {
"inset_region",
/* slots_in */
{{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
- {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
- {"use_boundary", BMO_OP_SLOT_BOOL},
- {"use_even_offset", BMO_OP_SLOT_BOOL},
- {"use_interpolate", BMO_OP_SLOT_BOOL},
- {"use_relative_offset", BMO_OP_SLOT_BOOL},
- {"use_edge_rail", BMO_OP_SLOT_BOOL},
- {"thickness", BMO_OP_SLOT_FLT},
- {"depth", BMO_OP_SLOT_FLT},
- {"use_outset", BMO_OP_SLOT_BOOL},
+ {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces to explicitly exclude from inset */
+ {"use_boundary", BMO_OP_SLOT_BOOL}, /* inset face boundaries */
+ {"use_even_offset", BMO_OP_SLOT_BOOL}, /* scale the offset to give more even thickness */
+ {"use_interpolate", BMO_OP_SLOT_BOOL}, /* blend face data across the inset */
+ {"use_relative_offset", BMO_OP_SLOT_BOOL}, /* scale the offset by surrounding geometry */
+ {"use_edge_rail", BMO_OP_SLOT_BOOL}, /* inset the region along existing edges */
+ {"thickness", BMO_OP_SLOT_FLT}, /* thickness */
+ {"depth", BMO_OP_SLOT_FLT}, /* depth */
+ {"use_outset", BMO_OP_SLOT_BOOL}, /* outset rather than inset */
{{'\0'}},
},
/* slots_out */
@@ -1951,12 +1944,12 @@ static BMOpDefine bmo_inset_region_def = {
static BMOpDefine bmo_offset_edgeloops_def = {
"offset_edgeloops",
/* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input faces */
- {"use_cap_endpoint", BMO_OP_SLOT_BOOL},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {"use_cap_endpoint", BMO_OP_SLOT_BOOL}, /* extend loop around end-points */
{{'\0'}},
},
/* slots_out */
- {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output faces */
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output edges */
{{'\0'}},
},
bmo_offset_edgeloops_exec,
@@ -1973,15 +1966,15 @@ static BMOpDefine bmo_wireframe_def = {
"wireframe",
/* slots_in */
{{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
- {"thickness", BMO_OP_SLOT_FLT},
- {"offset", BMO_OP_SLOT_FLT},
- {"use_replace", BMO_OP_SLOT_BOOL},
- {"use_boundary", BMO_OP_SLOT_BOOL},
- {"use_even_offset", BMO_OP_SLOT_BOOL},
- {"use_crease", BMO_OP_SLOT_BOOL},
- {"crease_weight", BMO_OP_SLOT_FLT},
- {"use_relative_offset", BMO_OP_SLOT_BOOL},
- {"material_offset", BMO_OP_SLOT_INT},
+ {"thickness", BMO_OP_SLOT_FLT}, /* thickness */
+ {"offset", BMO_OP_SLOT_FLT}, /* offset the thickness from the center */
+ {"use_replace", BMO_OP_SLOT_BOOL}, /* remove original geometry */
+ {"use_boundary", BMO_OP_SLOT_BOOL}, /* inset face boundaries */
+ {"use_even_offset", BMO_OP_SLOT_BOOL}, /* scale the offset to give more even thickness */
+ {"use_crease", BMO_OP_SLOT_BOOL}, /* crease hub edges for improved subdivision surface */
+ {"crease_weight", BMO_OP_SLOT_FLT}, /* the mean crease weight for resulting edges */
+ {"use_relative_offset", BMO_OP_SLOT_BOOL}, /* scale the offset by surrounding geometry */
+ {"material_offset", BMO_OP_SLOT_INT}, /* offset material index of generated faces */
{{'\0'}},
},
/* slots_out */
@@ -2045,8 +2038,8 @@ static BMOpDefine bmo_poke_def = {
static BMOpDefine bmo_convex_hull_def = {
"convex_hull",
/* slots_in */
- {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"use_existing_faces", BMO_OP_SLOT_BOOL},
+ {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
+ {"use_existing_faces", BMO_OP_SLOT_BOOL}, /* skip hull triangles that are covered by a pre-existing face */
{{'\0'}},
},
/* slots_out */
@@ -2076,7 +2069,7 @@ static BMOpDefine bmo_convex_hull_def = {
static BMOpDefine bmo_symmetrize_def = {
"symmetrize",
/* slots_in */
- {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
{"direction", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_axis_neg_xyz_and_xyz}, /* axis to use */
{"dist", BMO_OP_SLOT_FLT}, /* minimum distance */
{{'\0'}},
diff --git a/source/blender/bmesh/tools/bmesh_boolean.cc b/source/blender/bmesh/tools/bmesh_boolean.cc
index 6031e160c8c..bfb093c569f 100644
--- a/source/blender/bmesh/tools/bmesh_boolean.cc
+++ b/source/blender/bmesh/tools/bmesh_boolean.cc
@@ -30,6 +30,10 @@
#include "bmesh_boolean.h"
#include "bmesh_edgesplit.h"
+#include "PIL_time.h"
+
+// #define PERF_DEBUG
+
namespace blender::meshintersect {
#ifdef WITH_GMP
@@ -354,7 +358,14 @@ static bool bmesh_boolean(BMesh *bm,
{
IMeshArena arena;
IMesh m_triangulated;
+# ifdef PERF_DEBUG
+ double start_time = PIL_check_seconds_timer();
+# endif
IMesh m_in = mesh_from_bm(bm, looptris, looptris_tot, &m_triangulated, &arena);
+# ifdef PERF_DEBUG
+ double mesh_time = PIL_check_seconds_timer();
+ std::cout << "bmesh_boolean, imesh_from_bm done, time = " << mesh_time - start_time << "\n";
+# endif
std::function<int(int)> shape_fn;
if (use_self && boolean_mode == BoolOpType::None) {
/* Unary knife operation. Want every face where test_fn doesn't return -1. */
@@ -379,7 +390,16 @@ static bool bmesh_boolean(BMesh *bm,
}
IMesh m_out = boolean_mesh(
m_in, boolean_mode, nshapes, shape_fn, use_self, &m_triangulated, &arena);
+# ifdef PERF_DEBUG
+ double boolean_time = PIL_check_seconds_timer();
+ std::cout << "boolean done, time = " << boolean_time - mesh_time << "\n";
+# endif
bool any_change = apply_mesh_output_to_bmesh(bm, m_out, keep_hidden);
+# ifdef PERF_DEBUG
+ double apply_mesh_time = PIL_check_seconds_timer();
+ std::cout << "applied boolean output to bmesh, time = " << apply_mesh_time - boolean_time
+ << "\n";
+# endif
if (use_separate_all) {
/* We are supposed to separate all faces that are incident on intersection edges. */
BM_mesh_edgesplit(bm, false, true, false);
diff --git a/source/blender/compositor/intern/COM_ChunkOrderHotspot.cpp b/source/blender/compositor/intern/COM_ChunkOrderHotspot.cpp
index e95dd4233c4..b111fba44b7 100644
--- a/source/blender/compositor/intern/COM_ChunkOrderHotspot.cpp
+++ b/source/blender/compositor/intern/COM_ChunkOrderHotspot.cpp
@@ -17,7 +17,7 @@
*/
#include "COM_ChunkOrderHotspot.h"
-#include <math.h>
+#include <cmath>
ChunkOrderHotspot::ChunkOrderHotspot(int x, int y, float addition)
{
diff --git a/source/blender/compositor/intern/COM_CompositorContext.cpp b/source/blender/compositor/intern/COM_CompositorContext.cpp
index 52e705ffb79..2e168221b7b 100644
--- a/source/blender/compositor/intern/COM_CompositorContext.cpp
+++ b/source/blender/compositor/intern/COM_CompositorContext.cpp
@@ -18,7 +18,7 @@
#include "COM_CompositorContext.h"
#include "COM_defines.h"
-#include <stdio.h>
+#include <cstdio>
CompositorContext::CompositorContext()
{
diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp
index 9b3355f535a..d8f67571ee5 100644
--- a/source/blender/compositor/intern/COM_Converter.cpp
+++ b/source/blender/compositor/intern/COM_Converter.cpp
@@ -16,7 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#include <string.h>
+#include <cstring>
#include "DNA_node_types.h"
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp
index 27cec28f5d5..b026d2e60d9 100644
--- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp
+++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp
@@ -17,9 +17,9 @@
*/
#include <algorithm>
-#include <math.h>
+#include <cmath>
+#include <cstdlib>
#include <sstream>
-#include <stdlib.h>
#include "atomic_ops.h"
diff --git a/source/blender/compositor/intern/COM_Node.cpp b/source/blender/compositor/intern/COM_Node.cpp
index 74aefaf0e6d..897d4e1df02 100644
--- a/source/blender/compositor/intern/COM_Node.cpp
+++ b/source/blender/compositor/intern/COM_Node.cpp
@@ -16,7 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#include <string.h>
+#include <cstring>
#include "BKE_node.h"
diff --git a/source/blender/compositor/intern/COM_NodeOperation.cpp b/source/blender/compositor/intern/COM_NodeOperation.cpp
index 0842721a9e5..1a30806f28c 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.cpp
+++ b/source/blender/compositor/intern/COM_NodeOperation.cpp
@@ -16,7 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#include <stdio.h>
+#include <cstdio>
#include <typeinfo>
#include "COM_ExecutionSystem.h"
diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp b/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp
index 1237e728079..35a3314db3b 100644
--- a/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp
+++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp
@@ -304,7 +304,7 @@ void NodeOperationBuilder::add_operation_input_constants()
/* Note: unconnected inputs cached first to avoid modifying
* m_operations while iterating over it
*/
- typedef std::vector<NodeOperationInput *> Inputs;
+ using Inputs = std::vector<NodeOperationInput *>;
Inputs pending_inputs;
for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) {
NodeOperation *op = *it;
@@ -597,7 +597,7 @@ void NodeOperationBuilder::add_complex_operation_buffers()
}
}
-typedef std::set<NodeOperation *> Tags;
+using Tags = std::set<NodeOperation *>;
static void find_reachable_operations_recursive(Tags &reachable, NodeOperation *op)
{
diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cpp b/source/blender/compositor/intern/COM_OpenCLDevice.cpp
index 51ae9d6652e..acfe800e433 100644
--- a/source/blender/compositor/intern/COM_OpenCLDevice.cpp
+++ b/source/blender/compositor/intern/COM_OpenCLDevice.cpp
@@ -19,7 +19,7 @@
#include "COM_OpenCLDevice.h"
#include "COM_WorkScheduler.h"
-typedef enum COM_VendorID { NVIDIA = 0x10DE, AMD = 0x1002 } COM_VendorID;
+enum COM_VendorID { NVIDIA = 0x10DE, AMD = 0x1002 };
const cl_image_format IMAGE_FORMAT_COLOR = {
CL_RGBA,
CL_FLOAT,
diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp
index 450b64eec5a..f726caa3d66 100644
--- a/source/blender/compositor/intern/COM_WorkScheduler.cpp
+++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp
@@ -16,8 +16,8 @@
* Copyright 2011, Blender Foundation.
*/
+#include <cstdio>
#include <list>
-#include <stdio.h>
#include "COM_CPUDevice.h"
#include "COM_OpenCLDevice.h"
diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
index 74f5fceacfb..b2dfb558028 100644
--- a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
+++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
@@ -330,11 +330,11 @@ void DilateStepOperation::initExecution()
}
// small helper to pass data from initializeTileData to executePixel
-typedef struct tile_info {
+struct tile_info {
rcti rect;
int width;
float *buffer;
-} tile_info;
+};
static tile_info *create_cache(int xmin, int xmax, int ymin, int ymax)
{
diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
index 7ef0d7b7606..fbbd373ba09 100644
--- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
+++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
@@ -16,7 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#include <stdlib.h>
+#include <cstdlib>
#include "BLI_math.h"
#include "COM_DoubleEdgeMaskOperation.h"
diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
index e87d40b4c86..157c595afcb 100644
--- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
@@ -16,7 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#include <limits.h>
+#include <climits>
#include "BLI_utildefines.h"
#include "COM_FastGaussianBlurOperation.h"
diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp
index acc1dddacdd..362905761bb 100644
--- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp
+++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp
@@ -23,7 +23,7 @@
* 2D Fast Hartley Transform, used for convolution
*/
-typedef float fREAL;
+using fREAL = float;
// returns next highest power of 2 of x, as well its log2 in L2
static unsigned int nextPow2(unsigned int x, unsigned int *L2)
diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp
index f7fabfb9572..21d9177ddd5 100644
--- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp
+++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp
@@ -19,7 +19,7 @@
#include "COM_OutputFileMultiViewOperation.h"
#include "COM_OutputFileOperation.h"
-#include <string.h>
+#include <cstring>
#include "BLI_listbase.h"
#include "BLI_path_util.h"
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
index c5623fdbd37..2676ab1b9ca 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
@@ -18,7 +18,7 @@
#include "COM_OutputFileOperation.h"
-#include <string.h>
+#include <cstring>
#include "BLI_listbase.h"
#include "BLI_path_util.h"
diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
index 0776c97563e..f7b908deaf4 100644
--- a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
@@ -16,7 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#include <string.h>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -141,7 +141,7 @@ void VectorBlurOperation::generateVectorBlur(float *data,
/* ****************** Spans ******************************* */
/* span fill in method, is also used to localize data for zbuffering */
-typedef struct ZSpan {
+struct ZSpan {
/* range for clipping */
int rectx, recty;
@@ -157,8 +157,7 @@ typedef struct ZSpan {
int *rectz;
DrawBufPixel *rectdraw;
float clipcrop;
-
-} ZSpan;
+};
/* each zbuffer has coordinates transformed to local rect coordinates, so we can simply clip */
void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty, float clipcrop)
@@ -294,10 +293,10 @@ static void zbuf_add_to_span(ZSpan *zspan, const float v1[2], const float v2[2])
/* ******************** VECBLUR ACCUM BUF ************************* */
-typedef struct DrawBufPixel {
+struct DrawBufPixel {
const float *colpoin;
float alpha;
-} DrawBufPixel;
+};
static void zbuf_fill_in_rgba(
ZSpan *zspan, DrawBufPixel *col, float *v1, float *v2, float *v3, float *v4)
diff --git a/source/blender/compositor/operations/COM_WrapOperation.cpp b/source/blender/compositor/operations/COM_WrapOperation.cpp
index 7f7c1b7b639..37b7d68d495 100644
--- a/source/blender/compositor/operations/COM_WrapOperation.cpp
+++ b/source/blender/compositor/operations/COM_WrapOperation.cpp
@@ -16,7 +16,7 @@
* Copyright 2011, Blender Foundation.
*/
-#include <math.h>
+#include <cmath>
#include "COM_WrapOperation.h"
diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp
index 574978e5a5f..9fb995bf463 100644
--- a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp
+++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp
@@ -19,7 +19,7 @@
#include "COM_WriteBufferOperation.h"
#include "COM_OpenCLDevice.h"
#include "COM_defines.h"
-#include <stdio.h>
+#include <cstdio>
WriteBufferOperation::WriteBufferOperation(DataType datatype)
{
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 9cae343dcde..5af70305e13 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -25,8 +25,8 @@
#include "intern/builder/deg_builder_nodes.h"
-#include <stdio.h>
-#include <stdlib.h>
+#include <cstdio>
+#include <cstdlib>
#include "MEM_guardedalloc.h"
@@ -1247,8 +1247,7 @@ void DepsgraphNodeBuilder::build_particle_settings(ParticleSettings *particle_se
&particle_settings->id, NodeType::PARTICLE_SETTINGS, OperationCode::PARTICLE_SETTINGS_EVAL);
op_node->set_as_exit();
/* Texture slots. */
- for (int mtex_index = 0; mtex_index < MAX_MTEX; mtex_index++) {
- MTex *mtex = particle_settings->mtex[mtex_index];
+ for (MTex *mtex : particle_settings->mtex) {
if (mtex == nullptr || mtex->tex == nullptr) {
continue;
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
index 3c55d832568..8ba4b4a427f 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
@@ -25,8 +25,8 @@
#include "intern/builder/deg_builder_nodes.h"
-#include <stdio.h>
-#include <stdlib.h>
+#include <cstdio>
+#include <cstdlib>
#include "MEM_guardedalloc.h"
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
index 7a6dc6e2315..c7669b9fecb 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
@@ -25,8 +25,8 @@
#include "intern/builder/deg_builder_nodes.h"
-#include <stdio.h>
-#include <stdlib.h>
+#include <cstdio>
+#include <cstdlib>
#include "MEM_guardedalloc.h"
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc
index 4406cc83a0d..197e14c1a21 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc
@@ -23,8 +23,8 @@
#include "intern/builder/deg_builder_pchanmap.h"
-#include <stdio.h>
-#include <string.h>
+#include <cstdio>
+#include <cstring>
#include "BLI_utildefines.h"
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index a55966632d8..11d34782569 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -25,9 +25,9 @@
#include "intern/builder/deg_builder_relations.h"
+#include <cstdio>
+#include <cstdlib>
#include <cstring> /* required for STREQ later on. */
-#include <stdio.h>
-#include <stdlib.h>
#include "MEM_guardedalloc.h"
@@ -1907,8 +1907,7 @@ void DepsgraphRelationBuilder::build_particle_settings(ParticleSettings *part)
particle_settings_init_key, particle_settings_eval_key, "Particle Settings Init Order");
add_relation(particle_settings_reset_key, particle_settings_eval_key, "Particle Settings Reset");
/* Texture slots. */
- for (int mtex_index = 0; mtex_index < MAX_MTEX; mtex_index++) {
- MTex *mtex = part->mtex[mtex_index];
+ for (MTex *mtex : part->mtex) {
if (mtex == nullptr || mtex->tex == nullptr) {
continue;
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
index 39a60c9029c..32c36d78250 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
@@ -25,9 +25,9 @@
#include "intern/builder/deg_builder_relations.h"
+#include <cstdio>
+#include <cstdlib>
#include <cstring> /* required for STREQ later on. */
-#include <stdio.h>
-#include <stdlib.h>
#include "MEM_guardedalloc.h"
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
index b58d4a22712..8df8d4914c3 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
@@ -25,9 +25,9 @@
#include "intern/builder/deg_builder_relations.h"
+#include <cstdio>
+#include <cstdlib>
#include <cstring> /* required for STREQ later on. */
-#include <stdio.h>
-#include <stdlib.h>
#include "MEM_guardedalloc.h"
diff --git a/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc b/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc
index d02aa16f26b..dd71cc0504e 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc
+++ b/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc
@@ -36,7 +36,7 @@ class AllObjectsNodeBuilder : public DepsgraphNodeBuilder {
{
}
- virtual bool need_pull_base_into_graph(Base * /*base*/) override
+ bool need_pull_base_into_graph(Base * /*base*/) override
{
return true;
}
@@ -49,7 +49,7 @@ class AllObjectsRelationBuilder : public DepsgraphRelationBuilder {
{
}
- virtual bool need_pull_base_into_graph(Base * /*base*/) override
+ bool need_pull_base_into_graph(Base * /*base*/) override
{
return true;
}
diff --git a/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc b/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc
index 5fd4a0fc3dd..9e62432ea54 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc
+++ b/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc
@@ -55,7 +55,7 @@ class DepsgraphFromIDsNodeBuilder : public DepsgraphNodeBuilder {
{
}
- virtual bool need_pull_base_into_graph(Base *base) override
+ bool need_pull_base_into_graph(Base *base) override
{
if (!filter_.contains(&base->object->id)) {
return false;
@@ -63,7 +63,7 @@ class DepsgraphFromIDsNodeBuilder : public DepsgraphNodeBuilder {
return DepsgraphNodeBuilder::need_pull_base_into_graph(base);
}
- virtual void build_object_proxy_group(Object *object, bool is_visible) override
+ void build_object_proxy_group(Object *object, bool is_visible) override
{
if (object->proxy_group == nullptr) {
return;
@@ -88,7 +88,7 @@ class DepsgraphFromIDsRelationBuilder : public DepsgraphRelationBuilder {
{
}
- virtual bool need_pull_base_into_graph(Base *base) override
+ bool need_pull_base_into_graph(Base *base) override
{
if (!filter_.contains(&base->object->id)) {
return false;
@@ -96,7 +96,7 @@ class DepsgraphFromIDsRelationBuilder : public DepsgraphRelationBuilder {
return DepsgraphRelationBuilder::need_pull_base_into_graph(base);
}
- virtual void build_object_proxy_group(Object *object) override
+ void build_object_proxy_group(Object *object) override
{
if (object->proxy_group == nullptr) {
return;
diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc
index d0eedd6d811..57de62e1880 100644
--- a/source/blender/depsgraph/intern/depsgraph_query.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query.cc
@@ -25,7 +25,7 @@
#include "MEM_guardedalloc.h"
-#include <string.h> /* XXX: memcpy */
+#include <cstring> /* XXX: memcpy */
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
@@ -90,8 +90,8 @@ bool DEG_id_type_any_updated(const Depsgraph *graph)
const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
/* Loop over all ID types. */
- for (int id_type_index = 0; id_type_index < MAX_LIBARRAY; id_type_index++) {
- if (deg_graph->id_type_updated[id_type_index]) {
+ for (char id_type_index : deg_graph->id_type_updated) {
+ if (id_type_index) {
return true;
}
}
diff --git a/source/blender/depsgraph/intern/depsgraph_query_foreach.cc b/source/blender/depsgraph/intern/depsgraph_query_foreach.cc
index ed7011ba306..6ce7cc0837b 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_foreach.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_foreach.cc
@@ -47,9 +47,9 @@ namespace deg = blender::deg;
namespace blender::deg {
namespace {
-typedef deque<OperationNode *> TraversalQueue;
+using TraversalQueue = deque<OperationNode *>;
-typedef void (*DEGForeachOperation)(OperationNode *op_node, void *user_data);
+using DEGForeachOperation = void (*)(OperationNode *, void *);
bool deg_foreach_needs_visit(const OperationNode *op_node, const int flags)
{
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index aec3dd4b9ea..95ee8234ef3 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -25,9 +25,9 @@
#include "intern/depsgraph_tag.h"
+#include <cstdio>
#include <cstring> /* required for memset */
#include <queue>
-#include <stdio.h>
#include "BLI_math_bits.h"
#include "BLI_task.h"
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index fa7cfb305ee..1b24e2b7ad2 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -82,7 +82,7 @@ enum {
COMPONENT_STATE_DONE = 2,
};
-typedef deque<OperationNode *> FlushQueue;
+using FlushQueue = deque<OperationNode *>;
namespace {
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.cc
index 8e9fff56023..8fe0dd95bc2 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_volume.cc
@@ -31,7 +31,7 @@
#include "BKE_volume.h"
-#include <stdio.h>
+#include <cstdio>
namespace blender::deg {
diff --git a/source/blender/depsgraph/intern/node/deg_node.cc b/source/blender/depsgraph/intern/node/deg_node.cc
index 6266acae651..0d3563ee3de 100644
--- a/source/blender/depsgraph/intern/node/deg_node.cc
+++ b/source/blender/depsgraph/intern/node/deg_node.cc
@@ -23,7 +23,7 @@
#include "intern/node/deg_node.h"
-#include <stdio.h>
+#include <cstdio>
#include "BLI_utildefines.h"
diff --git a/source/blender/depsgraph/intern/node/deg_node_component.cc b/source/blender/depsgraph/intern/node/deg_node_component.cc
index 6ffe5db3fec..d824fb14718 100644
--- a/source/blender/depsgraph/intern/node/deg_node_component.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_component.cc
@@ -23,8 +23,8 @@
#include "intern/node/deg_node_component.h"
+#include <cstdio>
#include <cstring> /* required for STREQ later on. */
-#include <stdio.h>
#include "BLI_ghash.h"
#include "BLI_hash.hh"
diff --git a/source/blender/depsgraph/intern/node/deg_node_id.cc b/source/blender/depsgraph/intern/node/deg_node_id.cc
index 345da466960..4f2fcab5823 100644
--- a/source/blender/depsgraph/intern/node/deg_node_id.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_id.cc
@@ -23,8 +23,8 @@
#include "intern/node/deg_node_id.h"
+#include <cstdio>
#include <cstring> /* required for STREQ later on. */
-#include <stdio.h>
#include "BLI_string.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 2de6ee1f57d..a6cc9fddd69 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -80,6 +80,7 @@ set(SRC
engines/image/image_engine.c
engines/image/image_shader.c
engines/eevee/eevee_bloom.c
+ engines/eevee/eevee_cryptomatte.c
engines/eevee/eevee_data.c
engines/eevee/eevee_depth_of_field.c
engines/eevee/eevee_effects.c
@@ -250,6 +251,7 @@ data_to_c_simple(engines/eevee/shaders/bsdf_sampling_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/raytrace_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/renderpass_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/renderpass_postprocess_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/cryptomatte_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/ltc_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/ssr_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/surface_frag.glsl SRC)
diff --git a/source/blender/draw/engines/eevee/eevee_cryptomatte.c b/source/blender/draw/engines/eevee/eevee_cryptomatte.c
new file mode 100644
index 00000000000..44ff86b3333
--- /dev/null
+++ b/source/blender/draw/engines/eevee/eevee_cryptomatte.c
@@ -0,0 +1,654 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2020, Blender Foundation.
+ */
+
+/** \file
+ * \ingroup EEVEE
+ *
+ * This file implements Cryptomatte for EEVEE. Cryptomatte is used to extract mattes using
+ * information already available at render time. See
+ * https://raw.githubusercontent.com/Psyop/Cryptomatte/master/specification/IDmattes_poster.pdf
+ * for reference to the cryptomatte specification.
+ *
+ * The challenge with cryptomatte in EEVEE is the merging and sorting of the samples.
+ * User can enable up to 3 cryptomatte layers (Object, Material and Asset).
+ *
+ * Process
+ *
+ * - Cryptomatte sample: Rendering of a cryptomatte sample is stored in a GPUBuffer. The buffer
+ * holds a single float per pixel per number of active cryptomatte layers. The float is the
+ * cryptomatte hash of each layer. After drawing the cryptomatte sample the intermediate result is
+ * downloaded to a CPU buffer (`cryptomatte_download_buffer`).
+ *
+ * Accurate mode
+ *
+ * There are two accuracy modes. The difference between the two is the number of render samples
+ * they take into account to create the render passes. When accurate mode is off the number of
+ * levels is used as the number of cryptomatte samples to take. When accuracy mode is on the number
+ * of render samples is used.
+ *
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+#include "BKE_cryptomatte.h"
+
+#include "GPU_batch.h"
+
+#include "RE_pipeline.h"
+
+#include "BLI_alloca.h"
+#include "BLI_math_bits.h"
+#include "BLI_rect.h"
+
+#include "DNA_hair_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_particle_types.h"
+
+#include "eevee_private.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Data Management cryptomatte accum buffer
+ * \{ */
+
+BLI_INLINE eViewLayerCryptomatteFlags eevee_cryptomatte_active_layers(const ViewLayer *view_layer)
+{
+ const eViewLayerCryptomatteFlags cryptomatte_layers = view_layer->cryptomatte_flag &
+ VIEW_LAYER_CRYPTOMATTE_ALL;
+ return cryptomatte_layers;
+}
+
+/* The number of cryptomatte layers that are enabled */
+BLI_INLINE int eevee_cryptomatte_layers_count(const ViewLayer *view_layer)
+{
+ const eViewLayerCryptomatteFlags cryptomatte_layers = eevee_cryptomatte_active_layers(
+ view_layer);
+ return count_bits_i(cryptomatte_layers);
+}
+
+/* The number of render result passes are needed to store a single cryptomatte layer. Per
+ * renderpass 2 cryptomatte samples can be stored. */
+BLI_INLINE int eevee_cryptomatte_passes_per_layer(const ViewLayer *view_layer)
+{
+ const int num_cryptomatte_levels = view_layer->cryptomatte_levels;
+ const int num_cryptomatte_passes = (num_cryptomatte_levels + 1) / 2;
+ return num_cryptomatte_passes;
+}
+
+BLI_INLINE int eevee_cryptomatte_layer_stride(const ViewLayer *view_layer)
+{
+ return view_layer->cryptomatte_levels;
+}
+
+BLI_INLINE int eevee_cryptomatte_layer_offset(const ViewLayer *view_layer, const int layer)
+{
+ return view_layer->cryptomatte_levels * layer;
+}
+
+BLI_INLINE int eevee_cryptomatte_pixel_stride(const ViewLayer *view_layer)
+{
+ return eevee_cryptomatte_layer_stride(view_layer) * eevee_cryptomatte_layers_count(view_layer);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Init Renderpasses
+ * \{ */
+
+void EEVEE_cryptomatte_renderpasses_init(EEVEE_Data *vedata)
+{
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ViewLayer *view_layer = draw_ctx->view_layer;
+
+ /* Cryptomatte is only rendered for final image renders */
+ if (!DRW_state_is_image_render()) {
+ return;
+ }
+ if (eevee_cryptomatte_active_layers(view_layer) != 0) {
+ g_data->render_passes |= EEVEE_RENDER_PASS_CRYPTOMATTE;
+ g_data->cryptomatte_accurate_mode = (view_layer->cryptomatte_flag &
+ VIEW_LAYER_CRYPTOMATTE_ACCURATE) != 0;
+ }
+}
+
+void EEVEE_cryptomatte_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
+ EEVEE_Data *vedata,
+ int UNUSED(tot_samples))
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_PrivateData *g_data = vedata->stl->g_data;
+
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const ViewLayer *view_layer = draw_ctx->view_layer;
+
+ const int num_cryptomatte_layers = eevee_cryptomatte_layers_count(view_layer);
+ eGPUTextureFormat format = (num_cryptomatte_layers == 1) ?
+ GPU_R32F :
+ (num_cryptomatte_layers == 2) ? GPU_RG32F : GPU_RGBA32F;
+ const float *viewport_size = DRW_viewport_size_get();
+ const int buffer_size = viewport_size[0] * viewport_size[1];
+
+ if (g_data->cryptomatte_accum_buffer == NULL) {
+ g_data->cryptomatte_accum_buffer = MEM_calloc_arrayN(
+ sizeof(EEVEE_CryptomatteSample),
+ buffer_size * eevee_cryptomatte_pixel_stride(view_layer),
+ __func__);
+ /* Download buffer should store a float per active cryptomatte layer. */
+ g_data->cryptomatte_download_buffer = MEM_malloc_arrayN(
+ sizeof(float), buffer_size * num_cryptomatte_layers, __func__);
+ }
+
+ DRW_texture_ensure_fullscreen_2d(&txl->cryptomatte, format, 0);
+ GPU_framebuffer_ensure_config(&fbl->cryptomatte_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(dtxl->depth),
+ GPU_ATTACHMENT_TEXTURE(txl->cryptomatte),
+ });
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Populate Cache
+ * \{ */
+
+void EEVEE_cryptomatte_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_PassList *psl = vedata->psl;
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_CRYPTOMATTE) != 0) {
+ DRW_PASS_CREATE(psl->cryptomatte_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
+ }
+}
+
+static DRWShadingGroup *eevee_cryptomatte_shading_group_create(EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *UNUSED(sldata),
+ Object *ob,
+ Material *material,
+ bool is_hair)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const ViewLayer *view_layer = draw_ctx->view_layer;
+ const eViewLayerCryptomatteFlags cryptomatte_layers = eevee_cryptomatte_active_layers(
+ view_layer);
+ float cryptohash[4] = {0.0f};
+
+ EEVEE_PassList *psl = vedata->psl;
+ int layer_offset = 0;
+ if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_OBJECT) != 0) {
+ uint32_t cryptomatte_hash = BKE_cryptomatte_object_hash(ob);
+ float cryptomatte_color_value = BKE_cryptomatte_hash_to_float(cryptomatte_hash);
+ cryptohash[layer_offset] = cryptomatte_color_value;
+ layer_offset++;
+ }
+ if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_MATERIAL) != 0) {
+ uint32_t cryptomatte_hash = BKE_cryptomatte_material_hash(material);
+ float cryptomatte_color_value = BKE_cryptomatte_hash_to_float(cryptomatte_hash);
+ cryptohash[layer_offset] = cryptomatte_color_value;
+ layer_offset++;
+ }
+ if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_ASSET) != 0) {
+ uint32_t cryptomatte_hash = BKE_cryptomatte_asset_hash(ob);
+ float cryptomatte_color_value = BKE_cryptomatte_hash_to_float(cryptomatte_hash);
+ cryptohash[layer_offset] = cryptomatte_color_value;
+ layer_offset++;
+ }
+
+ DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_cryptomatte_sh_get(is_hair),
+ psl->cryptomatte_ps);
+ DRW_shgroup_uniform_vec4_copy(grp, "cryptohash", cryptohash);
+
+ return grp;
+}
+
+static void eevee_cryptomatte_hair_cache_populate(EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata,
+ Object *ob,
+ ParticleSystem *psys,
+ ModifierData *md,
+ Material *material)
+{
+ DRWShadingGroup *grp = eevee_cryptomatte_shading_group_create(
+ vedata, sldata, ob, material, true);
+ DRW_shgroup_hair_create_sub(ob, psys, md, grp);
+}
+
+void EEVEE_cryptomatte_object_hair_cache_populate(EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata,
+ Object *ob)
+{
+ BLI_assert(ob->type == OB_HAIR);
+ Hair *hair = ob->data;
+ Material *material = hair->mat ? hair->mat[HAIR_MATERIAL_NR - 1] : NULL;
+ eevee_cryptomatte_hair_cache_populate(vedata, sldata, ob, NULL, NULL, material);
+}
+
+void EEVEE_cryptomatte_particle_hair_cache_populate(EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata,
+ Object *ob)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+
+ if (ob->type == OB_MESH) {
+ if (ob != draw_ctx->object_edit) {
+ LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
+ if (md->type != eModifierType_ParticleSystem) {
+ continue;
+ }
+ ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
+ if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
+ continue;
+ }
+ ParticleSettings *part = psys->part;
+ const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
+ if (draw_as != PART_DRAW_PATH) {
+ continue;
+ }
+ Mesh *mesh = ob->data;
+ Material *material = part->omat - 1 < mesh->totcol ? NULL : mesh->mat[part->omat - 1];
+ eevee_cryptomatte_hair_cache_populate(vedata, sldata, ob, psys, md, material);
+ }
+ }
+ }
+}
+
+void EEVEE_cryptomatte_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const ViewLayer *view_layer = draw_ctx->view_layer;
+ const eViewLayerCryptomatteFlags cryptomatte_layers = eevee_cryptomatte_active_layers(
+ view_layer);
+
+ if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_MATERIAL) != 0) {
+ const int materials_len = DRW_cache_object_material_count_get(ob);
+ struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
+ memset(gpumat_array, 0, sizeof(*gpumat_array) * materials_len);
+ struct GPUBatch **geoms = DRW_cache_object_surface_material_get(
+ ob, gpumat_array, materials_len);
+ if (geoms) {
+ for (int i = 0; i < materials_len; i++) {
+ struct GPUBatch *geom = geoms[i];
+ if (geom == NULL) {
+ continue;
+ }
+ Material *material = BKE_object_material_get(ob, i + 1);
+ DRWShadingGroup *grp = eevee_cryptomatte_shading_group_create(
+ vedata, sldata, ob, material, false);
+ DRW_shgroup_call(grp, geom, ob);
+ }
+ }
+ }
+ else {
+ GPUBatch *geom = DRW_cache_object_surface_get(ob);
+ if (geom) {
+ DRWShadingGroup *grp = eevee_cryptomatte_shading_group_create(
+ vedata, sldata, ob, false, NULL);
+ DRW_shgroup_call(grp, geom, ob);
+ }
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Accumulate Samples
+ * \{ */
+
+/* Downloads cryptomatte sample buffer from the GPU and integrate the samples with the accumulated
+ * cryptomatte samples. */
+static void eevee_cryptomatte_download_buffer(EEVEE_Data *vedata, GPUFrameBuffer *framebuffer)
+{
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const ViewLayer *view_layer = draw_ctx->view_layer;
+ const int num_cryptomatte_layers = eevee_cryptomatte_layers_count(view_layer);
+ const int num_levels = view_layer->cryptomatte_levels;
+ const float *viewport_size = DRW_viewport_size_get();
+ const int buffer_size = viewport_size[0] * viewport_size[1];
+
+ EEVEE_CryptomatteSample *accum_buffer = g_data->cryptomatte_accum_buffer;
+ float *download_buffer = g_data->cryptomatte_download_buffer;
+
+ BLI_assert(accum_buffer);
+ BLI_assert(download_buffer);
+
+ GPU_framebuffer_read_color(framebuffer,
+ 0,
+ 0,
+ viewport_size[0],
+ viewport_size[1],
+ num_cryptomatte_layers,
+ 0,
+ GPU_DATA_FLOAT,
+ download_buffer);
+
+ /* Integrate download buffer into the accum buffer.
+ * The download buffer contains upto 3 floats per pixel (one float per cryptomatte layer.
+ *
+ * NOTE: here we deviate from the cryptomatte standard. During integration the standard always
+ * sort the samples by its weight to make sure that samples with the lowest weight
+ * are discarded first. In our case the weight of each sample is always 1 as we don't have
+ * subsamples and apply the coverage during the post processing. When there is no room for new
+ * samples the new samples has a weight of 1 and will always be discarded. */
+ int download_pixel_index = 0;
+ int accum_pixel_index = 0;
+ int accum_pixel_stride = eevee_cryptomatte_pixel_stride(view_layer);
+ for (int pixel_index = 0; pixel_index < buffer_size; pixel_index++) {
+ for (int layer = 0; layer < num_cryptomatte_layers; layer++) {
+ const int layer_offset = eevee_cryptomatte_layer_offset(view_layer, layer);
+ float download_hash = download_buffer[download_pixel_index++];
+ for (int level = 0; level < num_levels; level++) {
+ EEVEE_CryptomatteSample *sample = &accum_buffer[accum_pixel_index + layer_offset + level];
+ if (sample->hash == download_hash) {
+ sample->weight += 1.0f;
+ break;
+ }
+ /* We test against weight as hash 0.0f is used for samples hitting the world background. */
+ if (sample->weight == 0.0f) {
+ sample->hash = download_hash;
+ sample->weight = 1.0f;
+ break;
+ }
+ }
+ }
+ accum_pixel_index += accum_pixel_stride;
+ }
+}
+
+void EEVEE_cryptomatte_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
+ EEVEE_EffectsInfo *effects = stl->effects;
+ EEVEE_PassList *psl = vedata->psl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const ViewLayer *view_layer = draw_ctx->view_layer;
+ const int cryptomatte_levels = view_layer->cryptomatte_levels;
+ const int current_sample = effects->taa_current_sample;
+
+ /* In accurate mode all render samples are evaluated. In inaccurate mode this is limited to the
+ * number of cryptomatte levels. This will reduce the overhead of downloading the GPU buffer and
+ * integrating it into the accum buffer. */
+ if (g_data->cryptomatte_accurate_mode || current_sample < cryptomatte_levels) {
+ static float clear_color[4] = {0.0};
+ GPU_framebuffer_bind(fbl->cryptomatte_fb);
+ GPU_framebuffer_clear_color(fbl->cryptomatte_fb, clear_color);
+ DRW_draw_pass(psl->cryptomatte_ps);
+
+ eevee_cryptomatte_download_buffer(vedata, fbl->cryptomatte_fb);
+
+ /* Restore */
+ GPU_framebuffer_bind(fbl->main_fb);
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Update Render Passes
+ * \{ */
+
+/* Register the render passes needed for cryptomatte
+ * normally this is done in `EEVEE_render_update_passes`, but it has been placed here to keep
+ * related code side-by-side for clarity. */
+void EEVEE_cryptomatte_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
+{
+ char cryptomatte_pass_name[MAX_NAME];
+ const short num_passes = eevee_cryptomatte_passes_per_layer(view_layer);
+ if ((view_layer->cryptomatte_flag & VIEW_LAYER_CRYPTOMATTE_OBJECT) != 0) {
+ for (short pass = 0; pass < num_passes; pass++) {
+ BLI_snprintf_rlen(cryptomatte_pass_name, MAX_NAME, "CryptoObject%02d", pass);
+ RE_engine_register_pass(
+ engine, scene, view_layer, cryptomatte_pass_name, 4, "RGBA", SOCK_RGBA);
+ }
+ }
+ if ((view_layer->cryptomatte_flag & VIEW_LAYER_CRYPTOMATTE_MATERIAL) != 0) {
+ for (short pass = 0; pass < num_passes; pass++) {
+ BLI_snprintf_rlen(cryptomatte_pass_name, MAX_NAME, "CryptoMaterial%02d", pass);
+ RE_engine_register_pass(
+ engine, scene, view_layer, cryptomatte_pass_name, 4, "RGBA", SOCK_RGBA);
+ }
+ }
+ if ((view_layer->cryptomatte_flag & VIEW_LAYER_CRYPTOMATTE_ASSET) != 0) {
+ for (short pass = 0; pass < num_passes; pass++) {
+ BLI_snprintf_rlen(cryptomatte_pass_name, MAX_NAME, "CryptoAsset%02d", pass);
+ RE_engine_register_pass(
+ engine, scene, view_layer, cryptomatte_pass_name, 4, "RGBA", SOCK_RGBA);
+ }
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Construct Render Result
+ * \{ */
+
+/* Compare function for cryptomatte samples. Samples with the highest weight will be at the
+ * beginning of the list. */
+static int eevee_cryptomatte_sample_cmp_reverse(const void *a_, const void *b_)
+{
+ const EEVEE_CryptomatteSample *a = a_;
+ const EEVEE_CryptomatteSample *b = b_;
+ if (a->weight < b->weight) {
+ return 1;
+ }
+ if (a->weight > b->weight) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Post process the weights. The accumulated weights buffer adds one to each weight per sample.
+ * During post processing ensure that the total of weights per sample is between 0 and 1. */
+static void eevee_cryptomatte_postprocess_weights(EEVEE_Data *vedata)
+{
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const ViewLayer *view_layer = draw_ctx->view_layer;
+ const int num_cryptomatte_layers = eevee_cryptomatte_layers_count(view_layer);
+ const int num_levels = view_layer->cryptomatte_levels;
+ const float *viewport_size = DRW_viewport_size_get();
+ const int buffer_size = viewport_size[0] * viewport_size[1];
+
+ EEVEE_CryptomatteSample *accum_buffer = g_data->cryptomatte_accum_buffer;
+ BLI_assert(accum_buffer);
+ int accum_pixel_index = 0;
+ int accum_pixel_stride = eevee_cryptomatte_pixel_stride(view_layer);
+
+ for (int pixel_index = 0; pixel_index < buffer_size;
+ pixel_index++, accum_pixel_index += accum_pixel_stride) {
+ for (int layer = 0; layer < num_cryptomatte_layers; layer++) {
+ const int layer_offset = eevee_cryptomatte_layer_offset(view_layer, layer);
+ /* Calculate the total weight of the sample. */
+ float total_weight = 0.0f;
+ for (int level = 0; level < num_levels; level++) {
+ EEVEE_CryptomatteSample *sample = &accum_buffer[accum_pixel_index + layer_offset + level];
+ total_weight += sample->weight;
+ }
+ BLI_assert(total_weight > 0.0f);
+
+ float total_weight_inv = 1.0f / total_weight;
+ for (int level = 0; level < num_levels; level++) {
+ EEVEE_CryptomatteSample *sample = &accum_buffer[accum_pixel_index + layer_offset + level];
+ /* Remove background samples. These samples were used to determine the correct weight
+ * but won't be part of the final result. */
+ if (sample->hash == 0.0f) {
+ sample->weight = 0.0f;
+ }
+ sample->weight *= total_weight_inv;
+ }
+
+ /* Sort accum buffer by coverage of each sample. */
+ qsort(&accum_buffer[accum_pixel_index + layer_offset],
+ num_levels,
+ sizeof(EEVEE_CryptomatteSample),
+ eevee_cryptomatte_sample_cmp_reverse);
+ }
+ }
+}
+
+/* Extract cryptomatte layer from the cryptomatte_accum_buffer to render passes. */
+static void eevee_cryptomatte_extract_render_passes(
+ RenderLayer *rl,
+ const char *viewname,
+ const char *render_pass_name_format,
+ EEVEE_CryptomatteSample *accum_buffer,
+ /* number of render passes per cryptomatte layer. */
+ const int num_cryptomatte_passes,
+ const int num_cryptomatte_levels,
+ const int accum_pixel_stride,
+ const int layer_stride,
+ const int layer_index,
+ const int rect_width,
+ const int rect_height,
+ const int rect_offset_x,
+ const int rect_offset_y,
+ const int viewport_width)
+{
+ char cryptomatte_pass_name[MAX_NAME];
+ /* A pass can store 2 levels. Technically the last pass can have a single level if the number of
+ * levels is an odd number. This parameter counts the number of levels it has processed. */
+ int levels_done = 0;
+ for (int pass = 0; pass < num_cryptomatte_passes; pass++) {
+ /* Each pass holds 2 cryptomatte samples. */
+ const int pass_offset = pass * 2;
+ BLI_snprintf_rlen(cryptomatte_pass_name, MAX_NAME, render_pass_name_format, pass);
+ RenderPass *rp_object = RE_pass_find_by_name(rl, cryptomatte_pass_name, viewname);
+ for (int y = 0; y < rect_height; y++) {
+ for (int x = 0; x < rect_width; x++) {
+ const int accum_buffer_offset = (rect_offset_x + x +
+ (rect_offset_y + y) * viewport_width) *
+ accum_pixel_stride +
+ layer_index * layer_stride + pass_offset;
+ const int render_pass_offset = (y * rect_width + x) * 4;
+ rp_object->rect[render_pass_offset] = accum_buffer[accum_buffer_offset].hash;
+ rp_object->rect[render_pass_offset + 1] = accum_buffer[accum_buffer_offset].weight;
+ if (levels_done + 1 < num_cryptomatte_levels) {
+ rp_object->rect[render_pass_offset + 2] = accum_buffer[accum_buffer_offset + 1].hash;
+ rp_object->rect[render_pass_offset + 3] = accum_buffer[accum_buffer_offset + 1].weight;
+ }
+ else {
+ rp_object->rect[render_pass_offset + 2] = 0.0f;
+ rp_object->rect[render_pass_offset + 3] = 0.0f;
+ }
+ }
+ }
+ levels_done++;
+ }
+}
+
+void EEVEE_cryptomatte_render_result(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *UNUSED(sldata))
+{
+ EEVEE_PrivateData *g_data = vedata->stl->g_data;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const ViewLayer *view_layer = draw_ctx->view_layer;
+ const eViewLayerCryptomatteFlags cryptomatte_layers = view_layer->cryptomatte_flag &
+ VIEW_LAYER_CRYPTOMATTE_ALL;
+
+ eevee_cryptomatte_postprocess_weights(vedata);
+
+ const int rect_width = BLI_rcti_size_x(rect);
+ const int rect_height = BLI_rcti_size_y(rect);
+ const int rect_offset_x = vedata->stl->g_data->overscan_pixels + rect->xmin;
+ const int rect_offset_y = vedata->stl->g_data->overscan_pixels + rect->ymin;
+ const float *viewport_size = DRW_viewport_size_get();
+ const int viewport_width = viewport_size[0];
+ EEVEE_CryptomatteSample *accum_buffer = g_data->cryptomatte_accum_buffer;
+ BLI_assert(accum_buffer);
+ const int num_cryptomatte_levels = view_layer->cryptomatte_levels;
+ const int num_cryptomatte_passes = eevee_cryptomatte_passes_per_layer(view_layer);
+ const int layer_stride = eevee_cryptomatte_layer_stride(view_layer);
+ const int accum_pixel_stride = eevee_cryptomatte_pixel_stride(view_layer);
+
+ int layer_index = 0;
+ if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_OBJECT) != 0) {
+ eevee_cryptomatte_extract_render_passes(rl,
+ viewname,
+ "CryptoObject%02d",
+ accum_buffer,
+ num_cryptomatte_passes,
+ num_cryptomatte_levels,
+ accum_pixel_stride,
+ layer_stride,
+ layer_index,
+ rect_width,
+ rect_height,
+ rect_offset_x,
+ rect_offset_y,
+ viewport_width);
+ layer_index++;
+ }
+ if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_MATERIAL) != 0) {
+ eevee_cryptomatte_extract_render_passes(rl,
+ viewname,
+ "CryptoMaterial%02d",
+ accum_buffer,
+ num_cryptomatte_passes,
+ num_cryptomatte_levels,
+ accum_pixel_stride,
+ layer_stride,
+ layer_index,
+ rect_width,
+ rect_height,
+ rect_offset_x,
+ rect_offset_y,
+ viewport_width);
+ layer_index++;
+ }
+ if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_ASSET) != 0) {
+ eevee_cryptomatte_extract_render_passes(rl,
+ viewname,
+ "CryptoAsset%02d",
+ accum_buffer,
+ num_cryptomatte_passes,
+ num_cryptomatte_levels,
+ accum_pixel_stride,
+ layer_stride,
+ layer_index,
+ rect_width,
+ rect_height,
+ rect_offset_x,
+ rect_offset_y,
+ viewport_width);
+ layer_index++;
+ }
+}
+
+/** \} */
+
+void EEVEE_cryptomatte_free(EEVEE_Data *vedata)
+{
+ EEVEE_PrivateData *g_data = vedata->stl->g_data;
+ MEM_SAFE_FREE(g_data->cryptomatte_accum_buffer);
+ MEM_SAFE_FREE(g_data->cryptomatte_download_buffer);
+}
diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c
index 5c4ee015c86..47068d0b843 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -240,6 +240,9 @@ void EEVEE_view_layer_data_free(void *storage)
DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.spec_light);
DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.emit);
DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.environment);
+ for (int aov_index = 0; aov_index < MAX_AOVS; aov_index++) {
+ DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.aovs[aov_index]);
+ }
if (sldata->material_cache) {
BLI_memblock_destroy(sldata->material_cache, NULL);
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 7d1f40ba5d8..f233b0fda96 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -570,6 +570,8 @@ static void eevee_render_to_image(void *vedata,
EEVEE_motion_blur_data_free(&ved->stl->effects->motion_blur);
if (RE_engine_test_break(engine)) {
+ /* Cryptomatte buffers are freed during render_read_result */
+ EEVEE_cryptomatte_free(vedata);
return;
}
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 58f182ecf8d..c7a8f7729eb 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -244,31 +244,31 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
/* Create RenderPass UBO */
if (sldata->renderpass_ubo.combined == NULL) {
EEVEE_RenderPassData data;
- data = (EEVEE_RenderPassData){true, true, true, true, true, false, false};
+ data = (EEVEE_RenderPassData){true, true, true, true, true, false, false, false, 0};
sldata->renderpass_ubo.combined = GPU_uniformbuf_create_ex(
sizeof(data), &data, "renderpass_ubo.combined");
- data = (EEVEE_RenderPassData){true, false, false, false, false, true, false};
+ data = (EEVEE_RenderPassData){true, false, false, false, false, true, false, false, 0};
sldata->renderpass_ubo.diff_color = GPU_uniformbuf_create_ex(
sizeof(data), &data, "renderpass_ubo.diff_color");
- data = (EEVEE_RenderPassData){true, true, false, false, false, false, false};
+ data = (EEVEE_RenderPassData){true, true, false, false, false, false, false, false, 0};
sldata->renderpass_ubo.diff_light = GPU_uniformbuf_create_ex(
sizeof(data), &data, "renderpass_ubo.diff_light");
- data = (EEVEE_RenderPassData){false, false, true, false, false, false, false};
+ data = (EEVEE_RenderPassData){false, false, true, false, false, false, false, false, 0};
sldata->renderpass_ubo.spec_color = GPU_uniformbuf_create_ex(
sizeof(data), &data, "renderpass_ubo.spec_color");
- data = (EEVEE_RenderPassData){false, false, true, true, false, false, false};
+ data = (EEVEE_RenderPassData){false, false, true, true, false, false, false, false, 0};
sldata->renderpass_ubo.spec_light = GPU_uniformbuf_create_ex(
sizeof(data), &data, "renderpass_ubo.spec_light");
- data = (EEVEE_RenderPassData){false, false, false, false, true, false, false};
+ data = (EEVEE_RenderPassData){false, false, false, false, true, false, false, false, 0};
sldata->renderpass_ubo.emit = GPU_uniformbuf_create_ex(
sizeof(data), &data, "renderpass_ubo.emit");
- data = (EEVEE_RenderPassData){true, true, true, true, true, false, true};
+ data = (EEVEE_RenderPassData){true, true, true, true, true, false, true, false, 0};
sldata->renderpass_ubo.environment = GPU_uniformbuf_create_ex(
sizeof(data), &data, "renderpass_ubo.environment");
}
@@ -276,6 +276,51 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
/* Used combined pass by default. */
g_data->renderpass_ubo = sldata->renderpass_ubo.combined;
+ {
+ g_data->num_aovs_used = 0;
+ if ((stl->g_data->render_passes & EEVEE_RENDER_PASS_AOV) != 0) {
+ EEVEE_RenderPassData data = {true, true, true, true, true, false, false, true, 0};
+ if (stl->g_data->aov_hash == EEVEE_AOV_HASH_ALL) {
+ ViewLayer *view_layer = draw_ctx->view_layer;
+ int aov_index = 0;
+ LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
+ if ((aov->flag & AOV_CONFLICT) != 0) {
+ continue;
+ }
+ if (aov_index == MAX_AOVS) {
+ break;
+ }
+ data.renderPassAOVActive = EEVEE_renderpasses_aov_hash(aov);
+ if (sldata->renderpass_ubo.aovs[aov_index]) {
+ GPU_uniformbuf_update(sldata->renderpass_ubo.aovs[aov_index], &data);
+ }
+ else {
+ sldata->renderpass_ubo.aovs[aov_index] = GPU_uniformbuf_create_ex(
+ sizeof(data), &data, "renderpass_ubo.aovs");
+ }
+ aov_index++;
+ }
+ g_data->num_aovs_used = aov_index;
+ }
+ else {
+ /* Rendering a single AOV in the 3d viewport */
+ data.renderPassAOVActive = stl->g_data->aov_hash;
+ if (sldata->renderpass_ubo.aovs[0]) {
+ GPU_uniformbuf_update(sldata->renderpass_ubo.aovs[0], &data);
+ }
+ else {
+ sldata->renderpass_ubo.aovs[0] = GPU_uniformbuf_create_ex(
+ sizeof(data), &data, "renderpass_ubo.aovs");
+ }
+ g_data->num_aovs_used = 1;
+ }
+ }
+ /* Free AOV UBO's that are not in use. */
+ for (int aov_index = g_data->num_aovs_used; aov_index < MAX_AOVS; aov_index++) {
+ DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.aovs[aov_index]);
+ }
+ }
+
/* HACK: EEVEE_material_get can create a new context. This can only be
* done when there is no active framebuffer. We do this here otherwise
* `EEVEE_renderpasses_output_init` will fail. It cannot be done in
@@ -949,6 +994,11 @@ void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
if (pd->render_passes & EEVEE_RENDER_PASS_SPECULAR_COLOR) {
material_renderpass_init(fbl, &txl->spec_color_accum, texture_format, do_clear);
}
+ if (pd->render_passes & EEVEE_RENDER_PASS_AOV) {
+ for (int aov_index = 0; aov_index < pd->num_aovs_used; aov_index++) {
+ material_renderpass_init(fbl, &txl->aov_surface_accum[aov_index], texture_format, do_clear);
+ }
+ }
if (pd->render_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT) {
material_renderpass_init(fbl, &txl->spec_light_accum, texture_format, do_clear);
@@ -960,6 +1010,7 @@ void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
static void material_renderpass_accumulate(EEVEE_FramebufferList *fbl,
DRWPass *renderpass,
+ DRWPass *renderpass2,
EEVEE_PrivateData *pd,
GPUTexture *output_tx,
struct GPUUniformBuf *renderpass_option_ubo)
@@ -969,6 +1020,9 @@ static void material_renderpass_accumulate(EEVEE_FramebufferList *fbl,
pd->renderpass_ubo = renderpass_option_ubo;
DRW_draw_pass(renderpass);
+ if (renderpass2) {
+ DRW_draw_pass(renderpass2);
+ }
GPU_framebuffer_texture_detach(fbl->material_accum_fb, output_tx);
}
@@ -983,38 +1037,69 @@ void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
if (fbl->material_accum_fb != NULL) {
DRWPass *material_accum_ps = psl->material_accum_ps;
+ DRWPass *background_accum_ps = psl->background_accum_ps;
if (pd->render_passes & EEVEE_RENDER_PASS_ENVIRONMENT) {
material_renderpass_accumulate(
- fbl, psl->background_accum_ps, pd, txl->env_accum, sldata->renderpass_ubo.environment);
+ fbl, background_accum_ps, NULL, pd, txl->env_accum, sldata->renderpass_ubo.environment);
}
if (pd->render_passes & EEVEE_RENDER_PASS_EMIT) {
material_renderpass_accumulate(
- fbl, material_accum_ps, pd, txl->emit_accum, sldata->renderpass_ubo.emit);
+ fbl, material_accum_ps, NULL, pd, txl->emit_accum, sldata->renderpass_ubo.emit);
}
if (pd->render_passes & EEVEE_RENDER_PASS_DIFFUSE_COLOR) {
- material_renderpass_accumulate(
- fbl, material_accum_ps, pd, txl->diff_color_accum, sldata->renderpass_ubo.diff_color);
+ material_renderpass_accumulate(fbl,
+ material_accum_ps,
+ NULL,
+ pd,
+ txl->diff_color_accum,
+ sldata->renderpass_ubo.diff_color);
}
if (pd->render_passes & EEVEE_RENDER_PASS_DIFFUSE_LIGHT) {
- material_renderpass_accumulate(
- fbl, material_accum_ps, pd, txl->diff_light_accum, sldata->renderpass_ubo.diff_light);
+ material_renderpass_accumulate(fbl,
+ material_accum_ps,
+ NULL,
+ pd,
+ txl->diff_light_accum,
+ sldata->renderpass_ubo.diff_light);
if (effects->enabled_effects & EFFECT_SSS) {
EEVEE_subsurface_output_accumulate(sldata, vedata);
}
}
if (pd->render_passes & EEVEE_RENDER_PASS_SPECULAR_COLOR) {
- material_renderpass_accumulate(
- fbl, material_accum_ps, pd, txl->spec_color_accum, sldata->renderpass_ubo.spec_color);
+ material_renderpass_accumulate(fbl,
+ material_accum_ps,
+ NULL,
+ pd,
+ txl->spec_color_accum,
+ sldata->renderpass_ubo.spec_color);
}
if (pd->render_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT) {
- material_renderpass_accumulate(
- fbl, material_accum_ps, pd, txl->spec_light_accum, sldata->renderpass_ubo.spec_light);
+ material_renderpass_accumulate(fbl,
+ material_accum_ps,
+ NULL,
+ pd,
+ txl->spec_light_accum,
+ sldata->renderpass_ubo.spec_light);
if (effects->enabled_effects & EFFECT_SSR) {
EEVEE_reflection_output_accumulate(sldata, vedata);
}
}
+ if (pd->render_passes & EEVEE_RENDER_PASS_AOV) {
+ for (int aov_index = 0; aov_index < pd->num_aovs_used; aov_index++) {
+ material_renderpass_accumulate(fbl,
+ material_accum_ps,
+ background_accum_ps,
+ pd,
+ txl->aov_surface_accum[aov_index],
+ sldata->renderpass_ubo.aovs[aov_index]);
+ }
+ }
+ /* Free unused aov textures. */
+ for (int aov_index = pd->num_aovs_used; aov_index < MAX_AOVS; aov_index++) {
+ DRW_TEXTURE_FREE_SAFE(txl->aov_surface_accum[aov_index]);
+ }
/* Restore default. */
pd->renderpass_ubo = sldata->renderpass_ubo.combined;
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index f5cef8f3c25..a6a480ca967 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -53,6 +53,7 @@ extern struct DrawEngineType draw_engine_eevee_type;
#define MAX_SHADOW_CASCADE 8
#define MAX_SHADOW_CUBE (MAX_SHADOW - MAX_CASCADE_NUM * MAX_SHADOW_CASCADE)
#define MAX_BLOOM_STEP 16
+#define MAX_AOVS 64
// #define DEBUG_SHADOW_DISTRIBUTION
@@ -163,7 +164,10 @@ BLI_INLINE bool eevee_hdri_preview_overlay_enabled(const View3D *v3d)
#define EEVEE_RENDERPASSES_MATERIAL \
(EEVEE_RENDER_PASS_EMIT | EEVEE_RENDER_PASS_DIFFUSE_COLOR | EEVEE_RENDER_PASS_DIFFUSE_LIGHT | \
EEVEE_RENDER_PASS_SPECULAR_COLOR | EEVEE_RENDER_PASS_SPECULAR_LIGHT | \
- EEVEE_RENDER_PASS_ENVIRONMENT)
+ EEVEE_RENDER_PASS_ENVIRONMENT | EEVEE_RENDER_PASS_AOV)
+#define EEVEE_AOV_HASH_ALL -1
+#define EEVEE_AOV_HASH_COLOR_TYPE_MASK 1
+#define MAX_CRYPTOMATTE_LAYERS 3
/* Material shader variations */
enum {
@@ -293,6 +297,7 @@ typedef struct EEVEE_PassList {
/* Renderpass Accumulation. */
struct DRWPass *material_accum_ps;
struct DRWPass *background_accum_ps;
+ struct DRWPass *cryptomatte_ps;
struct DRWPass *depth_ps;
struct DRWPass *depth_cull_ps;
@@ -325,6 +330,7 @@ typedef struct EEVEE_FramebufferList {
struct GPUFrameBuffer *bloom_down_fb[MAX_BLOOM_STEP];
struct GPUFrameBuffer *bloom_accum_fb[MAX_BLOOM_STEP - 1];
struct GPUFrameBuffer *bloom_pass_accum_fb;
+ struct GPUFrameBuffer *cryptomatte_fb;
struct GPUFrameBuffer *shadow_accum_fb;
struct GPUFrameBuffer *ssr_accum_fb;
struct GPUFrameBuffer *sss_blur_fb;
@@ -376,10 +382,12 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *diff_light_accum;
struct GPUTexture *spec_color_accum;
struct GPUTexture *spec_light_accum;
+ struct GPUTexture *aov_surface_accum[MAX_AOVS];
struct GPUTexture *emit_accum;
struct GPUTexture *bloom_accum;
struct GPUTexture *ssr_accum;
struct GPUTexture *shadow_accum;
+ struct GPUTexture *cryptomatte;
struct GPUTexture *refract_color;
struct GPUTexture *taa_history;
@@ -430,7 +438,9 @@ typedef struct EEVEE_RenderPassData {
int renderPassEmit;
int renderPassSSSColor;
int renderPassEnvironment;
- int _pad[1];
+ int renderPassAOV;
+ int renderPassAOVActive;
+ int _pad[3];
} EEVEE_RenderPassData;
/* ************ LIGHT UBO ************* */
@@ -860,6 +870,7 @@ typedef struct EEVEE_ViewLayerData {
struct GPUUniformBuf *spec_color;
struct GPUUniformBuf *spec_light;
struct GPUUniformBuf *emit;
+ struct GPUUniformBuf *aovs[MAX_AOVS];
} renderpass_ubo;
/* Common Uniform Buffer */
@@ -904,6 +915,11 @@ typedef struct EEVEE_WorldEngineData {
DrawData dd;
} EEVEE_WorldEngineData;
+typedef struct EEVEE_CryptomatteSample {
+ float hash;
+ float weight;
+} EEVEE_CryptomatteSample;
+
/* *********************************** */
typedef struct EEVEE_Data {
@@ -959,6 +975,12 @@ typedef struct EEVEE_PrivateData {
/* Renderpasses */
/* Bitmask containing the active render_passes */
eViewLayerEEVEEPassType render_passes;
+ int aov_hash;
+ int num_aovs_used;
+ bool cryptomatte_accurate_mode;
+ EEVEE_CryptomatteSample *cryptomatte_accum_buffer;
+ float *cryptomatte_download_buffer;
+
/* Uniform references that are referenced inside the `renderpass_pass`. They are updated
* to reuse the drawing pass and the shading group. */
int renderpass_type;
@@ -1111,6 +1133,7 @@ struct GPUShader *EEVEE_shaders_effect_ambient_occlusion_layer_sh_get(void);
struct GPUShader *EEVEE_shaders_effect_ambient_occlusion_debug_sh_get(void);
struct GPUShader *EEVEE_shaders_effect_screen_raytrace_sh_get(EEVEE_SSRShaderOptions options);
struct GPUShader *EEVEE_shaders_renderpasses_post_process_sh_get(void);
+struct GPUShader *EEVEE_shaders_cryptomatte_sh_get(bool is_hair);
struct GPUShader *EEVEE_shaders_shadow_sh_get(void);
struct GPUShader *EEVEE_shaders_shadow_accum_sh_get(void);
struct GPUShader *EEVEE_shaders_subsurface_first_pass_sh_get(void);
@@ -1215,6 +1238,30 @@ void EEVEE_bloom_draw(EEVEE_Data *vedata);
void EEVEE_bloom_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples);
void EEVEE_bloom_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+/* eevee_cryptomatte.c */
+void EEVEE_cryptomatte_renderpasses_init(EEVEE_Data *vedata);
+void EEVEE_cryptomatte_output_init(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ int tot_samples);
+void EEVEE_cryptomatte_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_cryptomatte_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob);
+void EEVEE_cryptomatte_particle_hair_cache_populate(EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata,
+ Object *ob);
+void EEVEE_cryptomatte_object_hair_cache_populate(EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata,
+ Object *ob);
+void EEVEE_cryptomatte_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_cryptomatte_update_passes(struct RenderEngine *engine,
+ struct Scene *scene,
+ struct ViewLayer *view_layer);
+void EEVEE_cryptomatte_render_result(struct RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata);
+void EEVEE_cryptomatte_free(EEVEE_Data *vedata);
+
/* eevee_occlusion.c */
int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata,
@@ -1284,10 +1331,12 @@ void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata,
bool post_effect);
void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
- eViewLayerEEVEEPassType renderpass_type);
+ eViewLayerEEVEEPassType renderpass_type,
+ int aov_index);
void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_renderpasses_draw_debug(EEVEE_Data *vedata);
bool EEVEE_renderpasses_only_first_sample_pass_active(EEVEE_Data *vedata);
+int EEVEE_renderpasses_aov_hash(const ViewLayerAOV *aov);
/* eevee_temporal_sampling.c */
void EEVEE_temporal_sampling_reset(EEVEE_Data *vedata);
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index 504e4e1d336..2b2ff2e5c90 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -191,6 +191,7 @@ void EEVEE_render_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
EEVEE_subsurface_cache_init(sldata, vedata);
EEVEE_temporal_sampling_cache_init(sldata, vedata);
EEVEE_volumes_cache_init(sldata, vedata);
+ EEVEE_cryptomatte_cache_init(sldata, vedata);
}
/* Used by light cache. in this case engine is NULL. */
@@ -200,9 +201,15 @@ void EEVEE_render_cache(void *vedata,
struct Depsgraph *depsgraph)
{
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
+ EEVEE_Data *data = vedata;
+ EEVEE_StorageList *stl = data->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
EEVEE_LightProbesInfo *pinfo = sldata->probes;
bool cast_shadow = false;
+ const bool do_cryptomatte = (engine != NULL) &&
+ ((g_data->render_passes & EEVEE_RENDER_PASS_CRYPTOMATTE) != 0);
+
eevee_id_update(vedata, &ob->id);
if (pinfo->vis_data.collection) {
@@ -227,14 +234,23 @@ void EEVEE_render_cache(void *vedata,
const int ob_visibility = DRW_object_visibility_in_active_context(ob);
if (ob_visibility & OB_VISIBLE_PARTICLES) {
EEVEE_particle_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
+ if (do_cryptomatte) {
+ EEVEE_cryptomatte_particle_hair_cache_populate(data, sldata, ob);
+ }
}
if (ob_visibility & OB_VISIBLE_SELF) {
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
+ if (do_cryptomatte) {
+ EEVEE_cryptomatte_cache_populate(data, sldata, ob);
+ }
}
else if (ob->type == OB_HAIR) {
EEVEE_object_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
+ if (do_cryptomatte) {
+ EEVEE_cryptomatte_object_hair_cache_populate(data, sldata, ob);
+ }
}
else if (ob->type == OB_VOLUME) {
Scene *scene = DEG_get_evaluated_scene(depsgraph);
@@ -301,7 +317,7 @@ static void eevee_render_result_normal(RenderLayer *rl,
}
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_NORMAL) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_NORMAL);
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_NORMAL, 0);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_NORMAL, 3, vedata->fbl->renderpass_fb, vedata);
}
@@ -321,7 +337,7 @@ static void eevee_render_result_z(RenderLayer *rl,
}
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_Z) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_Z);
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_Z, 0);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_Z, 1, vedata->fbl->renderpass_fb, vedata);
}
@@ -334,7 +350,7 @@ static void eevee_render_result_mist(RenderLayer *rl,
EEVEE_ViewLayerData *sldata)
{
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_MIST) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_MIST);
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_MIST, 0);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_MIST, 1, vedata->fbl->renderpass_fb, vedata);
}
@@ -347,7 +363,7 @@ static void eevee_render_result_shadow(RenderLayer *rl,
EEVEE_ViewLayerData *sldata)
{
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_SHADOW) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_SHADOW);
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_SHADOW, 0);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_SHADOW, 3, vedata->fbl->renderpass_fb, vedata);
}
@@ -360,7 +376,7 @@ static void eevee_render_result_occlusion(RenderLayer *rl,
EEVEE_ViewLayerData *sldata)
{
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_AO) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_AO);
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_AO, 0);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_AO, 3, vedata->fbl->renderpass_fb, vedata);
}
@@ -378,7 +394,7 @@ static void eevee_render_result_bloom(RenderLayer *rl,
}
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_BLOOM) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_BLOOM);
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_BLOOM, 0);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_BLOOM, 3, vedata->fbl->renderpass_fb, vedata);
}
@@ -386,7 +402,7 @@ static void eevee_render_result_bloom(RenderLayer *rl,
#define EEVEE_RENDER_RESULT_MATERIAL_PASS(pass_name, eevee_pass_type) \
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_##eevee_pass_type) != 0) { \
- EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_##eevee_pass_type); \
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_##eevee_pass_type, 0); \
eevee_render_color_result( \
rl, viewname, rect, RE_PASSNAME_##pass_name, 3, vedata->fbl->renderpass_fb, vedata); \
}
@@ -462,8 +478,49 @@ static void eevee_render_result_volume_transmittance(RenderLayer *rl,
EEVEE_RENDER_RESULT_MATERIAL_PASS(VOLUME_TRANSMITTANCE, VOLUME_TRANSMITTANCE)
}
+static void eevee_render_result_aovs(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_AOV) != 0) {
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ViewLayer *view_layer = draw_ctx->view_layer;
+ int aov_index = 0;
+ LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
+ if ((aov->flag & AOV_CONFLICT) != 0) {
+ continue;
+ }
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_AOV, aov_index);
+ switch (aov->type) {
+ case AOV_TYPE_COLOR:
+ eevee_render_color_result(
+ rl, viewname, rect, aov->name, 4, vedata->fbl->renderpass_fb, vedata);
+ break;
+ case AOV_TYPE_VALUE:
+ eevee_render_color_result(
+ rl, viewname, rect, aov->name, 1, vedata->fbl->renderpass_fb, vedata);
+ }
+ aov_index++;
+ }
+ }
+}
+
#undef EEVEE_RENDER_RESULT_MATERIAL_PASS
+static void eevee_render_result_cryptomatte(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_CRYPTOMATTE) != 0) {
+ EEVEE_cryptomatte_render_result(rl, viewname, rect, vedata, sldata);
+ }
+ EEVEE_cryptomatte_free(vedata);
+}
+
static void eevee_render_draw_background(EEVEE_Data *vedata)
{
EEVEE_FramebufferList *fbl = vedata->fbl;
@@ -641,6 +698,8 @@ void EEVEE_render_read_result(EEVEE_Data *vedata,
eevee_render_result_bloom(rl, viewname, rect, vedata, sldata);
eevee_render_result_volume_scatter(rl, viewname, rect, vedata, sldata);
eevee_render_result_volume_transmittance(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_aovs(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_cryptomatte(rl, viewname, rect, vedata, sldata);
}
void EEVEE_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
@@ -675,6 +734,23 @@ void EEVEE_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *v
CHECK_PASS_EEVEE(VOLUME_TRANSMITTANCE, SOCK_RGBA, 3, "RGB");
CHECK_PASS_EEVEE(BLOOM, SOCK_RGBA, 3, "RGB");
+ LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
+ if ((aov->flag & AOV_CONFLICT) != 0) {
+ continue;
+ }
+ switch (aov->type) {
+ case AOV_TYPE_COLOR:
+ RE_engine_register_pass(engine, scene, view_layer, aov->name, 4, "RGBA", SOCK_RGBA);
+ break;
+ case AOV_TYPE_VALUE:
+ RE_engine_register_pass(engine, scene, view_layer, aov->name, 1, "X", SOCK_FLOAT);
+ break;
+ default:
+ break;
+ }
+ }
+ EEVEE_cryptomatte_update_passes(engine, scene, view_layer);
+
#undef CHECK_PASS_LEGACY
#undef CHECK_PASS_EEVEE
}
diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c
index be73225b348..e7a03c678a8 100644
--- a/source/blender/draw/engines/eevee/eevee_renderpasses.c
+++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c
@@ -27,6 +27,7 @@
#include "BKE_global.h" /* for G.debug_value */
+#include "BLI_hash.h"
#include "BLI_string_utils.h"
#include "DEG_depsgraph_query.h"
@@ -36,12 +37,13 @@
typedef enum eRenderPassPostProcessType {
PASS_POST_UNDEFINED = 0,
PASS_POST_ACCUMULATED_COLOR = 1,
- PASS_POST_ACCUMULATED_LIGHT = 2,
- PASS_POST_ACCUMULATED_VALUE = 3,
- PASS_POST_DEPTH = 4,
- PASS_POST_AO = 5,
- PASS_POST_NORMAL = 6,
- PASS_POST_TWO_LIGHT_BUFFERS = 7,
+ PASS_POST_ACCUMULATED_COLOR_ALPHA = 2,
+ PASS_POST_ACCUMULATED_LIGHT = 3,
+ PASS_POST_ACCUMULATED_VALUE = 4,
+ PASS_POST_DEPTH = 5,
+ PASS_POST_AO = 6,
+ PASS_POST_NORMAL = 7,
+ PASS_POST_TWO_LIGHT_BUFFERS = 8,
} eRenderPassPostProcessType;
/* bitmask containing all renderpasses that need post-processing */
@@ -70,6 +72,15 @@ bool EEVEE_renderpasses_only_first_sample_pass_active(EEVEE_Data *vedata)
return (g_data->render_passes & ~EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE) == 0;
}
+/* Calculate the hash for an AOV. The least significant bit is used to store the AOV
+ * type the rest of the bits are used for the name hash. */
+int EEVEE_renderpasses_aov_hash(const ViewLayerAOV *aov)
+{
+ int hash = BLI_hash_string(aov->name);
+ SET_FLAG_FROM_TEST(hash, aov->type == AOV_TYPE_COLOR, EEVEE_AOV_HASH_COLOR_TYPE_MASK);
+ return hash;
+}
+
void EEVEE_renderpasses_init(EEVEE_Data *vedata)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -81,10 +92,24 @@ void EEVEE_renderpasses_init(EEVEE_Data *vedata)
if (v3d) {
const Scene *scene = draw_ctx->scene;
eViewLayerEEVEEPassType render_pass = v3d->shading.render_pass;
+ g_data->aov_hash = 0;
+
if (render_pass == EEVEE_RENDER_PASS_BLOOM &&
((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) {
render_pass = EEVEE_RENDER_PASS_COMBINED;
}
+ if (render_pass == EEVEE_RENDER_PASS_AOV) {
+ ViewLayerAOV *aov = BLI_findstring(
+ &view_layer->aovs, v3d->shading.aov_name, offsetof(ViewLayerAOV, name));
+ if (aov != NULL) {
+ g_data->aov_hash = EEVEE_renderpasses_aov_hash(aov);
+ }
+ else {
+ /* AOV not found in view layer. */
+ render_pass = EEVEE_RENDER_PASS_COMBINED;
+ }
+ }
+
g_data->render_passes = render_pass;
}
else {
@@ -110,11 +135,16 @@ void EEVEE_renderpasses_init(EEVEE_Data *vedata)
ENABLE_FROM_LEGACY(ENVIRONMENT, ENVIRONMENT)
#undef ENABLE_FROM_LEGACY
+ if (DRW_state_is_image_render() && !BLI_listbase_is_empty(&view_layer->aovs)) {
+ enabled_render_passes |= EEVEE_RENDER_PASS_AOV;
+ g_data->aov_hash = EEVEE_AOV_HASH_ALL;
+ }
+
g_data->render_passes = (enabled_render_passes & EEVEE_RENDERPASSES_ALL) |
EEVEE_RENDER_PASS_COMBINED;
}
-
EEVEE_material_renderpasses_init(vedata);
+ EEVEE_cryptomatte_renderpasses_init(vedata);
}
void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
@@ -174,6 +204,11 @@ void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
DRW_TEXTURE_FREE_SAFE(txl->renderpass);
GPU_FRAMEBUFFER_FREE_SAFE(fbl->renderpass_fb);
}
+
+ /* Cryptomatte doesn't use the GPU shader for post processing */
+ if ((g_data->render_passes & (EEVEE_RENDER_PASS_CRYPTOMATTE)) != 0) {
+ EEVEE_cryptomatte_output_init(sldata, vedata, tot_samples);
+ }
}
void EEVEE_renderpasses_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
@@ -216,7 +251,8 @@ void EEVEE_renderpasses_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ve
* After invoking this function the active frame-buffer is set to `vedata->fbl->renderpass_fb`. */
void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *UNUSED(sldata),
EEVEE_Data *vedata,
- eViewLayerEEVEEPassType renderpass_type)
+ eViewLayerEEVEEPassType renderpass_type,
+ int aov_index)
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_TextureList *txl = vedata->txl;
@@ -311,6 +347,11 @@ void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *UNUSED(sldata),
}
break;
}
+ case EEVEE_RENDER_PASS_AOV: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR_ALPHA;
+ g_data->renderpass_input = txl->aov_surface_accum[aov_index];
+ break;
+ }
case EEVEE_RENDER_PASS_BLOOM: {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
g_data->renderpass_input = txl->bloom_accum;
@@ -350,6 +391,9 @@ void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata,
(EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE | EEVEE_RENDER_PASS_VOLUME_SCATTER)) != 0) {
EEVEE_volumes_output_accumulate(sldata, vedata);
}
+ if ((render_pass & EEVEE_RENDER_PASS_CRYPTOMATTE) != 0) {
+ EEVEE_cryptomatte_output_accumulate(sldata, vedata);
+ }
}
else {
if ((render_pass & EEVEE_RENDER_PASS_BLOOM) != 0 &&
@@ -392,7 +436,7 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
if (is_valid) {
- EEVEE_renderpasses_postprocess(sldata, vedata, render_pass);
+ EEVEE_renderpasses_postprocess(sldata, vedata, render_pass, 0);
GPU_framebuffer_bind(dfbl->default_fb);
DRW_transform_none(txl->renderpass);
}
diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c
index f46a98ed845..7a277c18f01 100644
--- a/source/blender/draw/engines/eevee/eevee_shaders.c
+++ b/source/blender/draw/engines/eevee/eevee_shaders.c
@@ -121,6 +121,7 @@ static struct {
/* Render Passes */
struct GPUShader *postprocess_sh;
+ struct GPUShader *cryptomatte_sh[2];
/* Screen Space Reflection */
struct GPUShader *ssr_sh[SSR_MAX_SHADER];
@@ -186,6 +187,7 @@ extern char datatoc_btdf_lut_frag_glsl[];
extern char datatoc_closure_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_common_utiltex_lib_glsl[];
+extern char datatoc_cryptomatte_frag_glsl[];
extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_default_frag_glsl[];
extern char datatoc_lookdev_world_frag_glsl[];
@@ -695,6 +697,34 @@ GPUShader *EEVEE_shaders_renderpasses_post_process_sh_get(void)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Cryptomatte
+ * \{ */
+
+GPUShader *EEVEE_shaders_cryptomatte_sh_get(bool is_hair)
+{
+ const int index = is_hair ? 1 : 0;
+ if (e_data.cryptomatte_sh[index] == NULL) {
+ DynStr *ds = BLI_dynstr_new();
+ BLI_dynstr_append(ds, SHADER_DEFINES);
+
+ if (is_hair) {
+ BLI_dynstr_append(ds, "#define HAIR_SHADER\n");
+ }
+ else {
+ BLI_dynstr_append(ds, "#define MESH_SHADER\n");
+ }
+ char *defines = BLI_dynstr_get_cstring(ds);
+ e_data.cryptomatte_sh[index] = DRW_shader_create_with_shaderlib(
+ datatoc_surface_vert_glsl, NULL, datatoc_cryptomatte_frag_glsl, e_data.lib, defines);
+ BLI_dynstr_free(ds);
+ MEM_freeN(defines);
+ }
+ return e_data.cryptomatte_sh[index];
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Screen Raytrace
* \{ */
@@ -1428,6 +1458,8 @@ void EEVEE_shaders_free(void)
DRW_SHADER_FREE_SAFE(e_data.velocity_resolve_sh);
DRW_SHADER_FREE_SAFE(e_data.taa_resolve_sh);
DRW_SHADER_FREE_SAFE(e_data.taa_resolve_reproject_sh);
+ DRW_SHADER_FREE_SAFE(e_data.cryptomatte_sh[0]);
+ DRW_SHADER_FREE_SAFE(e_data.cryptomatte_sh[1]);
for (int i = 0; i < 2; i++) {
DRW_SHADER_FREE_SAFE(e_data.bloom_blit_sh[i]);
DRW_SHADER_FREE_SAFE(e_data.bloom_downsample_sh[i]);
diff --git a/source/blender/draw/engines/eevee/shaders/cryptomatte_frag.glsl b/source/blender/draw/engines/eevee/shaders/cryptomatte_frag.glsl
new file mode 100644
index 00000000000..1e499dbf991
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/cryptomatte_frag.glsl
@@ -0,0 +1,7 @@
+uniform vec4 cryptohash;
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = cryptohash;
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl b/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl
index 36cf3cecf40..3e0a5e76d00 100644
--- a/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl
@@ -1,3 +1,4 @@
+#define EEVEE_AOV_HASH_COLOR_TYPE_MASK 1
/* ---------------------------------------------------------------------- */
/** \name Resources
@@ -12,6 +13,8 @@ layout(std140) uniform renderpass_block
bool renderPassEmit;
bool renderPassSSSColor;
bool renderPassEnvironment;
+ bool renderPassAOV;
+ int renderPassAOVActive;
};
/** \} */
@@ -40,4 +43,14 @@ vec3 render_pass_emission_mask(vec3 emission_light)
return renderPassEmit ? emission_light : vec3(0.0);
}
+bool render_pass_aov_is_color()
+{
+ return (renderPassAOVActive & EEVEE_AOV_HASH_COLOR_TYPE_MASK) != 0;
+}
+
+int render_pass_aov_hash()
+{
+ return renderPassAOVActive & ~EEVEE_AOV_HASH_COLOR_TYPE_MASK;
+}
+
/** \} */
diff --git a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
index 89a411bc7cb..eb6ca4b9de8 100644
--- a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
@@ -4,12 +4,13 @@
#define PASS_POST_UNDEFINED 0
#define PASS_POST_ACCUMULATED_COLOR 1
-#define PASS_POST_ACCUMULATED_LIGHT 2
-#define PASS_POST_ACCUMULATED_VALUE 3
-#define PASS_POST_DEPTH 4
-#define PASS_POST_AO 5
-#define PASS_POST_NORMAL 6
-#define PASS_POST_TWO_LIGHT_BUFFERS 7
+#define PASS_POST_ACCUMULATED_COLOR_ALPHA 2
+#define PASS_POST_ACCUMULATED_LIGHT 3
+#define PASS_POST_ACCUMULATED_VALUE 4
+#define PASS_POST_DEPTH 5
+#define PASS_POST_AO 6
+#define PASS_POST_NORMAL 7
+#define PASS_POST_TWO_LIGHT_BUFFERS 8
uniform int postProcessType;
uniform int currentSample;
@@ -55,7 +56,7 @@ vec3 safe_divide_even_color(vec3 a, vec3 b)
void main()
{
- vec3 color;
+ vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
ivec2 texel = ivec2(gl_FragCoord.xy);
if (postProcessType == PASS_POST_DEPTH) {
@@ -66,11 +67,11 @@ void main()
else {
depth = -get_view_z_from_depth(depth);
}
- color = vec3(depth);
+ color.rgb = vec3(depth);
}
else if (postProcessType == PASS_POST_AO) {
float ao_accum = texelFetch(inputBuffer, texel, 0).r;
- color = vec3(min(1.0, ao_accum / currentSample));
+ color.rgb = vec3(min(1.0, ao_accum / currentSample));
}
else if (postProcessType == PASS_POST_NORMAL) {
float depth = texelFetch(depthBuffer, texel, 0).r;
@@ -80,35 +81,39 @@ void main()
if (depth != 1.0 && any(notEqual(encoded_normal, vec2(0.0)))) {
vec3 decoded_normal = normal_decode(texelFetch(inputBuffer, texel, 0).rg, vec3(0.0));
vec3 world_normal = mat3(ViewMatrixInverse) * decoded_normal;
- color = world_normal;
+ color.rgb = world_normal;
}
else {
- color = vec3(0.0);
+ color.rgb = vec3(0.0);
}
}
else if (postProcessType == PASS_POST_ACCUMULATED_VALUE) {
float accumulated_value = texelFetch(inputBuffer, texel, 0).r;
- color = vec3(accumulated_value / currentSample);
+ color.rgb = vec3(accumulated_value / currentSample);
}
else if (postProcessType == PASS_POST_ACCUMULATED_COLOR) {
vec3 accumulated_color = texelFetch(inputBuffer, texel, 0).rgb;
+ color.rgb = (accumulated_color / currentSample);
+ }
+ else if (postProcessType == PASS_POST_ACCUMULATED_COLOR_ALPHA) {
+ vec4 accumulated_color = texelFetch(inputBuffer, texel, 0);
color = (accumulated_color / currentSample);
}
else if (postProcessType == PASS_POST_ACCUMULATED_LIGHT) {
vec3 accumulated_light = texelFetch(inputBuffer, texel, 0).rgb;
vec3 accumulated_color = texelFetch(inputColorBuffer, texel, 0).rgb;
- color = safe_divide_even_color(accumulated_light, accumulated_color);
+ color.rgb = safe_divide_even_color(accumulated_light, accumulated_color);
}
else if (postProcessType == PASS_POST_TWO_LIGHT_BUFFERS) {
vec3 accumulated_light = texelFetch(inputBuffer, texel, 0).rgb +
texelFetch(inputSecondLightBuffer, texel, 0).rgb;
vec3 accumulated_color = texelFetch(inputColorBuffer, texel, 0).rgb;
- color = safe_divide_even_color(accumulated_light, accumulated_color);
+ color.rgb = safe_divide_even_color(accumulated_light, accumulated_color);
}
else {
/* Output error color: Unknown how to post process this pass. */
- color = vec3(1.0, 0.0, 1.0);
+ color.rgb = vec3(1.0, 0.0, 1.0);
}
- fragColor = vec4(color, 1.0);
+ fragColor = color;
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 368530fde05..519b015a6ad 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -252,7 +252,7 @@ void GPENCIL_cache_init(void *ved)
pd->do_fast_drawing = false;
pd->obact = draw_ctx->obact;
- if (pd->obact && pd->obact->type == OB_GPENCIL) {
+ if (pd->obact && pd->obact->type == OB_GPENCIL && !(pd->draw_depth_only)) {
/* Check if active object has a temp stroke data. */
bGPdata *gpd = (bGPdata *)pd->obact->data;
if (gpd->runtime.sbuffer_used > 0) {
@@ -498,7 +498,7 @@ static void gpencil_stroke_cache_populate(bGPDlayer *gpl,
bool hide_onion = gpl && gpf && gpf->runtime.onion_id != 0 &&
((gp_style->flag & GP_MATERIAL_HIDE_ONIONSKIN) != 0);
- if (hide_material || (!show_stroke && !show_fill) || only_lines || hide_onion) {
+ if (hide_material || (!show_stroke && !show_fill) || (only_lines && hide_onion) || hide_onion) {
return;
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
index d01aaaed8b0..cb65fbd6ae7 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
+++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
@@ -95,7 +95,7 @@ static DRWShadingGroup *gpencil_vfx_pass_create(const char *name,
static void gpencil_vfx_blur(BlurShaderFxData *fx, Object *ob, gpIterVfxData *iter)
{
- if (fx->radius[0] == 0.0f && fx->radius[1] == 0.0f) {
+ if ((fx->samples == 0.0f) || (fx->radius[0] == 0.0f && fx->radius[1] == 0.0f)) {
return;
}
diff --git a/source/blender/draw/engines/image/image_private.h b/source/blender/draw/engines/image/image_private.h
index ad7ff78cb41..d5821cc5d70 100644
--- a/source/blender/draw/engines/image/image_private.h
+++ b/source/blender/draw/engines/image/image_private.h
@@ -43,7 +43,7 @@ typedef struct IMAGE_PrivateData {
void *lock;
struct ImBuf *ibuf;
struct Image *image;
- struct DRWView* view;
+ struct DRWView *view;
struct GPUTexture *texture;
bool owns_texture;
diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc
index 39d8e45cc19..d365f76aabe 100644
--- a/source/blender/draw/tests/shaders_test.cc
+++ b/source/blender/draw/tests/shaders_test.cc
@@ -332,6 +332,8 @@ TEST_F(DrawTest, eevee_glsl_shaders_static)
EXPECT_NE(EEVEE_shaders_probe_grid_fill_sh_get(), nullptr);
EXPECT_NE(EEVEE_shaders_probe_planar_downsample_sh_get(), nullptr);
EXPECT_NE(EEVEE_shaders_renderpasses_post_process_sh_get(), nullptr);
+ EXPECT_NE(EEVEE_shaders_cryptomatte_sh_get(false), nullptr);
+ EXPECT_NE(EEVEE_shaders_cryptomatte_sh_get(true), nullptr);
EXPECT_NE(EEVEE_shaders_shadow_sh_get(), nullptr);
EXPECT_NE(EEVEE_shaders_shadow_accum_sh_get(), nullptr);
EXPECT_NE(EEVEE_shaders_subsurface_first_pass_sh_get(), nullptr);
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index ba3796ad245..124992bed71 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -49,6 +49,7 @@
#include "BKE_gpencil.h"
#include "BKE_lib_id.h"
#include "BKE_mask.h"
+#include "BKE_nla.h"
#include "BKE_scene.h"
#include "DEG_depsgraph.h"
@@ -1063,18 +1064,27 @@ static void rearrange_animchannels_filter_visible(ListBase *anim_data_visible,
eAnim_ChannelType type)
{
ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale, *ale_next;
- int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ eAnimFilter_Flags filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
+ ANIMFILTER_LIST_CHANNELS);
/* get all visible channels */
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* now, only keep the ones that are of the types we are interested in */
- for (ale = anim_data.first; ale; ale = ale_next) {
- ale_next = ale->next;
-
+ LISTBASE_FOREACH_MUTABLE (bAnimListElem *, ale, &anim_data) {
if (ale->type != type) {
BLI_freelinkN(&anim_data, ale);
+ continue;
+ }
+
+ if (type == ANIMTYPE_NLATRACK) {
+ NlaTrack *nlt = (NlaTrack *)ale->data;
+
+ if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) {
+ /* No re-arrangement of non-local tracks of override data. */
+ BLI_freelinkN(&anim_data, ale);
+ continue;
+ }
}
}
@@ -1146,6 +1156,7 @@ static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, eRearrangeAn
{
AnimChanRearrangeFp rearrange_func;
ListBase anim_data_visible = {NULL, NULL};
+ const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ac->obact);
/* hack: invert mode so that functions will work in right order */
mode *= -1;
@@ -1156,6 +1167,29 @@ static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, eRearrangeAn
return;
}
+ /* In liboverride case, we need to extract non-local NLA tracks from current anim data before we
+ * can perform the move, and add then back afterwards. It's the only way to prevent them from
+ * being affected by the reordering.
+ *
+ * Note that both override apply code for NLA tracks collection, and NLA editing code, are
+ * responsible to ensure that non-local tracks always remain first in the list. */
+ ListBase extracted_nonlocal_nla_tracks = {NULL, NULL};
+ if (is_liboverride) {
+ NlaTrack *nla_track;
+ for (nla_track = adt->nla_tracks.first; nla_track != NULL; nla_track = nla_track->next) {
+ if (!BKE_nlatrack_is_nonlocal_in_liboverride(&ac->obact->id, nla_track)) {
+ break;
+ }
+ }
+ if (nla_track != NULL && nla_track->prev != NULL) {
+ extracted_nonlocal_nla_tracks.first = adt->nla_tracks.first;
+ extracted_nonlocal_nla_tracks.last = nla_track->prev;
+ adt->nla_tracks.first = nla_track;
+ nla_track->prev->next = NULL;
+ nla_track->prev = NULL;
+ }
+ }
+
/* Filter visible data. */
rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_NLATRACK);
@@ -1163,6 +1197,14 @@ static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, eRearrangeAn
rearrange_animchannel_islands(
&adt->nla_tracks, rearrange_func, mode, ANIMTYPE_NLATRACK, &anim_data_visible);
+ /* Add back non-local NLA tracks at the begining of the animation data's list. */
+ if (!BLI_listbase_is_empty(&extracted_nonlocal_nla_tracks)) {
+ BLI_assert(is_liboverride);
+ ((NlaTrack *)extracted_nonlocal_nla_tracks.last)->next = adt->nla_tracks.first;
+ ((NlaTrack *)adt->nla_tracks.first)->prev = extracted_nonlocal_nla_tracks.last;
+ adt->nla_tracks.first = extracted_nonlocal_nla_tracks.first;
+ }
+
/* free temp data */
BLI_freelistN(&anim_data_visible);
}
diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c
index e552a321bca..32ce78e405e 100644
--- a/source/blender/editors/animation/anim_deps.c
+++ b/source/blender/editors/animation/anim_deps.c
@@ -216,11 +216,13 @@ static void animchan_sync_fcurve_scene(bAnimListElem *ale)
/* get strip name, and check if this strip is selected */
char *seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all[");
- Sequence *seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false);
- if (seq_name) {
- MEM_freeN(seq_name);
+ if (seq_name == NULL) {
+ return;
}
+ Sequence *seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false);
+ MEM_freeN(seq_name);
+
if (seq == NULL) {
return;
}
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 2e65fff69f1..f4a487140ff 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -1063,13 +1063,12 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id
/* only consider if F-Curve involves pose.bones */
if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones")) {
- bPoseChannel *pchan;
- char *bone_name;
/* get bone-name, and check if this bone is selected */
- bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
- pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
+ bPoseChannel *pchan = NULL;
+ char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
if (bone_name) {
+ pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
MEM_freeN(bone_name);
}
@@ -1106,13 +1105,12 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id
if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) {
Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq = NULL;
- char *seq_name;
if (ed) {
/* get strip name, and check if this strip is selected */
- seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all[");
- seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false);
+ char *seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all[");
if (seq_name) {
+ seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false);
MEM_freeN(seq_name);
}
}
@@ -1130,13 +1128,12 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id
/* check for selected nodes */
if ((fcu->rna_path) && strstr(fcu->rna_path, "nodes")) {
- bNode *node;
- char *node_name;
+ bNode *node = NULL;
/* get strip name, and check if this strip is selected */
- node_name = BLI_str_quoted_substrN(fcu->rna_path, "nodes[");
- node = nodeFindNodebyName(ntree, node_name);
+ char *node_name = BLI_str_quoted_substrN(fcu->rna_path, "nodes[");
if (node_name) {
+ node = nodeFindNodebyName(ntree, node_name);
MEM_freeN(node_name);
}
diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c
index 72103d68b05..5992545bdbe 100644
--- a/source/blender/editors/animation/anim_ipo_utils.c
+++ b/source/blender/editors/animation/anim_ipo_utils.c
@@ -112,7 +112,8 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
char *constName = BLI_str_quoted_substrN(fcu->rna_path, "constraints[");
/* assemble the string to display in the UI... */
- structname = BLI_sprintfN("%s : %s", pchanName, constName);
+ structname = BLI_sprintfN(
+ "%s : %s", pchanName ? pchanName : "", constName ? constName : "");
free_structname = 1;
/* free the temp names */
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index 08b02020f76..6ed9803dbd3 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -767,16 +767,15 @@ short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data)
* Storing the relevant information here helps avoiding crashes if we undo-repaste. */
if ((aci->id_type == ID_OB) && (((Object *)aci->id)->type == OB_ARMATURE) && aci->rna_path) {
Object *ob = (Object *)aci->id;
- bPoseChannel *pchan;
- char *bone_name;
- bone_name = BLI_str_quoted_substrN(aci->rna_path, "pose.bones[");
- pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
- if (pchan) {
- aci->is_bone = true;
- }
+ char *bone_name = BLI_str_quoted_substrN(aci->rna_path, "pose.bones[");
if (bone_name) {
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
MEM_freeN(bone_name);
+
+ if (pchan) {
+ aci->is_bone = true;
+ }
}
}
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 09c33c48170..e8146ca960a 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -2236,20 +2236,18 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op))
/* in pose mode, only delete the F-Curve if it belongs to a selected bone */
if (ob->mode & OB_MODE_POSE) {
if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones[")) {
- bPoseChannel *pchan;
- char *bone_name;
/* get bone-name, and check if this bone is selected */
- bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
- pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
+ char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
if (bone_name) {
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
MEM_freeN(bone_name);
- }
- /* delete if bone is selected*/
- if ((pchan) && (pchan->bone)) {
- if (pchan->bone->flag & BONE_SELECTED) {
- can_delete = true;
+ /* delete if bone is selected*/
+ if ((pchan) && (pchan->bone)) {
+ if (pchan->bone->flag & BONE_SELECTED) {
+ can_delete = true;
+ }
}
}
}
@@ -2342,13 +2340,12 @@ static int delete_key_v3d_exec(bContext *C, wmOperator *op)
* In object mode, we're dealing with the entire object.
*/
if ((ob->mode & OB_MODE_POSE) && strstr(fcu->rna_path, "pose.bones[\"")) {
- bPoseChannel *pchan;
- char *bone_name;
+ bPoseChannel *pchan = NULL;
/* get bone-name, and check if this bone is selected */
- bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
- pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
+ char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
if (bone_name) {
+ pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
MEM_freeN(bone_name);
}
diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c
index fde062b8454..af323bf91e4 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -453,10 +453,13 @@ static void updateDuplicateActionConstraintSettings(EditBone *dup_bone,
float mat[4][4];
+ bConstraintOb cob = {.depsgraph = NULL, .scene = NULL, .ob = ob, .pchan = NULL};
+ BKE_constraint_custom_object_space_get(cob.space_obj_world_matrix, curcon);
+
unit_m4(mat);
bPoseChannel *target_pchan = BKE_pose_channel_find_name(ob->pose, act_con->subtarget);
BKE_constraint_mat_convertspace(
- ob, target_pchan, mat, curcon->tarspace, CONSTRAINT_SPACE_LOCAL, false);
+ ob, target_pchan, &cob, mat, curcon->tarspace, CONSTRAINT_SPACE_LOCAL, false);
float max_axis_val = 0;
int max_axis = 0;
@@ -605,8 +608,11 @@ static void updateDuplicateLocRotConstraintSettings(Object *ob,
unit_m4(local_mat);
+ bConstraintOb cob = {.depsgraph = NULL, .scene = NULL, .ob = ob, .pchan = pchan};
+ BKE_constraint_custom_object_space_get(cob.space_obj_world_matrix, curcon);
+
BKE_constraint_mat_convertspace(
- ob, pchan, local_mat, curcon->ownspace, CONSTRAINT_SPACE_LOCAL, false);
+ ob, pchan, &cob, local_mat, curcon->ownspace, CONSTRAINT_SPACE_LOCAL, false);
if (curcon->type == CONSTRAINT_TYPE_ROTLIMIT) {
/* Zero out any location translation */
@@ -657,9 +663,12 @@ static void updateDuplicateTransformConstraintSettings(Object *ob,
float target_mat[4][4], own_mat[4][4], imat[4][4];
+ bConstraintOb cob = {.depsgraph = NULL, .scene = NULL, .ob = ob, .pchan = pchan};
+ BKE_constraint_custom_object_space_get(cob.space_obj_world_matrix, curcon);
+
unit_m4(own_mat);
BKE_constraint_mat_convertspace(
- ob, pchan, own_mat, curcon->ownspace, CONSTRAINT_SPACE_LOCAL, false);
+ ob, pchan, &cob, own_mat, curcon->ownspace, CONSTRAINT_SPACE_LOCAL, false);
/* ###Source map mirroring### */
float old_min, old_max;
@@ -717,7 +726,7 @@ static void updateDuplicateTransformConstraintSettings(Object *ob,
bPoseChannel *target_pchan = BKE_pose_channel_find_name(ob->pose, trans->subtarget);
unit_m4(target_mat);
BKE_constraint_mat_convertspace(
- ob, target_pchan, target_mat, curcon->tarspace, CONSTRAINT_SPACE_LOCAL, false);
+ ob, target_pchan, &cob, target_mat, curcon->tarspace, CONSTRAINT_SPACE_LOCAL, false);
invert_m4_m4(imat, target_mat);
/* convert values into local object space */
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 731d0d10e0b..6a03207b3b0 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -1090,6 +1090,7 @@ static bool pose_select_same_keyingset(bContext *C, ReportList *reports, bool ex
if (boneName) {
bPoseChannel *pchan = BKE_pose_channel_find_name(pose, boneName);
+ MEM_freeN(boneName);
if (pchan) {
/* select if bone is visible and can be affected */
@@ -1098,9 +1099,6 @@ static bool pose_select_same_keyingset(bContext *C, ReportList *reports, bool ex
changed = true;
}
}
-
- /* free temp memory */
- MEM_freeN(boneName);
}
}
}
diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt
index e374010cf44..337fb18f835 100644
--- a/source/blender/editors/datafiles/CMakeLists.txt
+++ b/source/blender/editors/datafiles/CMakeLists.txt
@@ -791,6 +791,7 @@ if(WITH_BLENDER)
# images
data_to_c_simple(../../../../release/datafiles/splash.png SRC)
data_to_c_simple(../../../../release/datafiles/alert_icons.png SRC)
+ data_to_c_simple(../../../../release/datafiles/blender_logo.png SRC)
# XXX These are handy, but give nasty "false changes" in svn :/
# svg_to_png(../../../../release/datafiles/blender_icons.svg
# ../../../../release/datafiles/blender_icons16.png
diff --git a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c
index f7caf8e4c6a..8755dea51e1 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c
@@ -50,7 +50,6 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "wm.h"
/* own includes */
#include "../gizmo_geometry.h"
@@ -66,7 +65,13 @@ typedef struct SnapGizmo3D {
/* We could have other snap contexts, for now only support 3D view. */
SnapObjectContext *snap_context_v3d;
- int mval[2];
+
+ /* Copy of the parameters of the last event state in order to detect updates. */
+ struct {
+ int x;
+ int y;
+ short shift, ctrl, alt, oskey;
+ } last_eventstate;
#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
wmKeyMap *keymap;
@@ -77,6 +82,37 @@ typedef struct SnapGizmo3D {
short snap_elem;
} SnapGizmo3D;
+/* Checks if the current event is different from the one captured in the last update. */
+static bool eventstate_has_changed(SnapGizmo3D *snap_gizmo, const wmWindowManager *wm)
+{
+ if (wm && wm->winactive) {
+ const wmEvent *event = wm->winactive->eventstate;
+ if ((event->x != snap_gizmo->last_eventstate.x) ||
+ (event->y != snap_gizmo->last_eventstate.y) ||
+ (event->ctrl != snap_gizmo->last_eventstate.ctrl) ||
+ (event->shift != snap_gizmo->last_eventstate.shift) ||
+ (event->alt != snap_gizmo->last_eventstate.alt) ||
+ (event->oskey != snap_gizmo->last_eventstate.oskey)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Copies the current eventstate. */
+static void eventstate_save(SnapGizmo3D *snap_gizmo, const wmWindowManager *wm)
+{
+ if (wm && wm->winactive) {
+ const wmEvent *event = wm->winactive->eventstate;
+ snap_gizmo->last_eventstate.x = event->x;
+ snap_gizmo->last_eventstate.y = event->y;
+ snap_gizmo->last_eventstate.ctrl = event->ctrl;
+ snap_gizmo->last_eventstate.shift = event->shift;
+ snap_gizmo->last_eventstate.alt = event->alt;
+ snap_gizmo->last_eventstate.oskey = event->oskey;
+ }
+}
+
#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
static bool invert_snap(SnapGizmo3D *snap_gizmo, const wmWindowManager *wm)
{
@@ -84,6 +120,15 @@ static bool invert_snap(SnapGizmo3D *snap_gizmo, const wmWindowManager *wm)
return false;
}
+ const wmEvent *event = wm->winactive->eventstate;
+ if ((event->ctrl == snap_gizmo->last_eventstate.ctrl) &&
+ (event->shift == snap_gizmo->last_eventstate.shift) &&
+ (event->alt == snap_gizmo->last_eventstate.alt) &&
+ (event->oskey == snap_gizmo->last_eventstate.oskey)) {
+ /* Nothing has changed. */
+ return snap_gizmo->invert_snap;
+ }
+
if (snap_gizmo->keymap == NULL) {
/* Lazy initialization. */
snap_gizmo->keymap = WM_modalkeymap_find(wm->defaultconf, "Generic Gizmo Tweak Modal Map");
@@ -92,7 +137,6 @@ static bool invert_snap(SnapGizmo3D *snap_gizmo, const wmWindowManager *wm)
const int snap_on = snap_gizmo->snap_on;
wmKeyMap *keymap = WM_keymap_active(wm, snap_gizmo->keymap);
- const wmEvent *event = wm->winactive->eventstate;
for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) {
if (kmi->flag & KMI_INACTIVE) {
continue;
@@ -250,12 +294,6 @@ short ED_gizmotypes_snap_3d_update(wmGizmo *gz,
float r_nor[3])
{
SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
- Scene *scene = DEG_get_input_scene(depsgraph);
- float co[3], no[3];
- short snap_elem = 0;
- int snap_elem_index[3] = {-1, -1, -1};
- int index = -1;
-
if (snap_gizmo->use_snap_override != -1) {
if (snap_gizmo->use_snap_override == false) {
snap_gizmo->snap_elem = 0;
@@ -265,7 +303,12 @@ short ED_gizmotypes_snap_3d_update(wmGizmo *gz,
#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
snap_gizmo->invert_snap = invert_snap(snap_gizmo, wm);
+#endif
+ eventstate_save(snap_gizmo, wm);
+ Scene *scene = DEG_get_input_scene(depsgraph);
+
+#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
if (snap_gizmo->use_snap_override == -1) {
const ToolSettings *ts = scene->toolsettings;
if (snap_gizmo->invert_snap != !(ts->snap_flag & SCE_SNAP)) {
@@ -273,10 +316,13 @@ short ED_gizmotypes_snap_3d_update(wmGizmo *gz,
return 0;
}
}
-#else
- UNUSED_VARS(wm);
#endif
+ float co[3], no[3];
+ short snap_elem = 0;
+ int snap_elem_index[3] = {-1, -1, -1};
+ int index = -1;
+
wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "snap_elements");
int snap_elements = RNA_property_enum_get(&gz_prop->ptr, gz_prop->prop);
if (gz_prop->prop != snap_gizmo->prop_snap_force) {
@@ -381,14 +427,17 @@ static void snap_gizmo_draw(const bContext *C, wmGizmo *gz)
return;
}
- ARegion *region = CTX_wm_region(C);
- RegionView3D *rv3d = region->regiondata;
+ wmWindowManager *wm = CTX_wm_manager(C);
+ if (eventstate_has_changed(snap_gizmo, wm)) {
+ /* The eventstate has changed but the snap has not been updated.
+ * This means that the current position is no longer valid. */
+ snap_gizmo->snap_elem = 0;
+ return;
+ }
- /* Ideally, we shouldn't assign values here.
- * But `test_select` is not called during navigation.
- * And `snap_elem` is not really useful in this case. */
- if ((rv3d->rflag & RV3D_NAVIGATING) ||
- (!(gz->state & WM_GIZMO_STATE_HIGHLIGHT) && !wm_gizmomap_modal_get(region->gizmo_map))) {
+ RegionView3D *rv3d = CTX_wm_region_data(C);
+ if (rv3d->rflag & RV3D_NAVIGATING) {
+ /* Don't draw the gizmo while navigating. It can be distracting. */
snap_gizmo->snap_elem = 0;
return;
}
@@ -418,30 +467,17 @@ static void snap_gizmo_draw(const bContext *C, wmGizmo *gz)
static int snap_gizmo_test_select(bContext *C, wmGizmo *gz, const int mval[2])
{
SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
-
-#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
wmWindowManager *wm = CTX_wm_manager(C);
- const bool invert = invert_snap(snap_gizmo, wm);
- if (snap_gizmo->invert_snap == invert && snap_gizmo->mval[0] == mval[0] &&
- snap_gizmo->mval[1] == mval[1]) {
+ if (!eventstate_has_changed(snap_gizmo, wm)) {
/* Performance, do not update. */
return snap_gizmo->snap_elem ? 0 : -1;
}
- snap_gizmo->invert_snap = invert;
-#else
- if (snap_gizmo->mval[0] == mval[0] && snap_gizmo->mval[1] == mval[1]) {
- /* Performance, do not update. */
- return snap_gizmo->snap_elem ? 0 : -1;
- }
-#endif
- copy_v2_v2_int(snap_gizmo->mval, mval);
-
ARegion *region = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
const float mval_fl[2] = {UNPACK2(mval)};
short snap_elem = ED_gizmotypes_snap_3d_update(
- gz, CTX_data_ensure_evaluated_depsgraph(C), region, v3d, NULL, mval_fl, NULL, NULL);
+ gz, CTX_data_ensure_evaluated_depsgraph(C), region, v3d, wm, mval_fl, NULL, NULL);
if (snap_elem) {
ED_region_tag_redraw_editor_overlays(region);
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index 33b02d525d5..63aa242275a 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -1312,7 +1312,7 @@ static void gpencil_layer_to_curve(bContext *C,
Scene *scene = CTX_data_scene(C);
bGPDframe *gpf = BKE_gpencil_layer_frame_get(gpl, CFRA, GP_GETFRAME_USE_PREV);
- bGPDstroke *gps, *prev_gps = NULL;
+ bGPDstroke *prev_gps = NULL;
Object *ob;
Curve *cu;
Nurb *nu = NULL;
@@ -1353,7 +1353,10 @@ static void gpencil_layer_to_curve(bContext *C,
gtd->inittime = ((bGPDstroke *)gpf->strokes.first)->inittime;
/* add points to curve */
- for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ if (gps->totpoints < 1) {
+ continue;
+ }
const bool add_start_point = (link_strokes && !(prev_gps));
const bool add_end_point = (link_strokes && !(gps->next));
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index a963632a01b..33a1469beab 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -1586,6 +1586,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
gps = link->data;
BLI_remlink(&gpf->strokes, gps);
BLI_addtail(&gpf->strokes, gps);
+ changed = true;
}
break;
/* Bring Forward */
@@ -1593,6 +1594,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
LISTBASE_FOREACH_BACKWARD (LinkData *, link, &selected) {
gps = link->data;
BLI_listbase_link_move(&gpf->strokes, gps, 1);
+ changed = true;
}
break;
/* Send Backward */
@@ -1600,6 +1602,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
LISTBASE_FOREACH (LinkData *, link, &selected) {
gps = link->data;
BLI_listbase_link_move(&gpf->strokes, gps, -1);
+ changed = true;
}
break;
/* Send to Back */
@@ -1608,12 +1611,12 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
gps = link->data;
BLI_remlink(&gpf->strokes, gps);
BLI_addhead(&gpf->strokes, gps);
+ changed = true;
}
break;
default:
BLI_assert(0);
break;
- changed = true;
}
}
BLI_freelistN(&selected);
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 15162f491d5..95c94f8cfed 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -3577,7 +3577,7 @@ static int gpencil_stroke_join_exec(bContext *C, wmOperator *op)
if (tot_strokes == max_join_strokes) {
BKE_reportf(op->reports,
RPT_WARNING,
- "Too many strokes selected. Only joined first %d strokes.",
+ "Too many strokes selected, only joined first %d strokes",
max_join_strokes);
break;
}
@@ -5206,158 +5206,3 @@ void GPENCIL_OT_stroke_merge_by_distance(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Reset Stroke Vertex Color Operator
- * \{ */
-
-static void gpencil_reset_vertex(bGPDstroke *gps, eGp_Vertex_Mode mode)
-{
- if (mode != GPPAINT_MODE_STROKE) {
- zero_v4(gps->vert_color_fill);
- }
-
- if (mode != GPPAINT_MODE_FILL) {
- bGPDspoint *pt;
- for (int i = 0; i < gps->totpoints; i++) {
- pt = &gps->points[i];
- zero_v4(pt->vert_color);
- }
- }
-}
-
-static int gpencil_stroke_reset_vertex_color_exec(bContext *C, wmOperator *op)
-{
- Object *obact = CTX_data_active_object(C);
- bGPdata *gpd = (bGPdata *)obact->data;
- const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd);
- const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
- bGPDstroke *gps = NULL;
-
- if (gpd == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data");
- return OPERATOR_CANCELLED;
- }
- eGp_Vertex_Mode mode = RNA_enum_get(op->ptr, "mode");
-
- /* First need to check if there are something selected. If not, apply to all strokes. */
- bool all_strokes = true;
- CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
- bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
- for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
- if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
- if (gpf == NULL) {
- continue;
- }
- for (gps = gpf->strokes.first; gps; gps = gps->next) {
- /* skip strokes that are invalid for current view */
- if (ED_gpencil_stroke_can_use(C, gps) == false) {
- continue;
- }
-
- if (is_curve_edit) {
- if (gps->editcurve == NULL) {
- continue;
- }
- bGPDcurve *gpc = gps->editcurve;
- if (gpc->flag & GP_CURVE_SELECT) {
- all_strokes = false;
- break;
- }
- }
- else {
- if (gps->flag & GP_STROKE_SELECT) {
- all_strokes = false;
- break;
- }
- }
- }
- /* if not multiedit, exit loop*/
- if (!is_multiedit) {
- break;
- }
- }
- }
- }
- CTX_DATA_END;
-
- /* Reset Vertex colors. */
- bool changed = false;
- CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
- bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
-
- for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
- if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
- if (gpf == NULL) {
- continue;
- }
-
- for (gps = gpf->strokes.first; gps; gps = gps->next) {
- /* skip strokes that are invalid for current view */
- if (ED_gpencil_stroke_can_use(C, gps) == false) {
- continue;
- }
-
- if (is_curve_edit) {
- if (gps->editcurve == NULL) {
- continue;
- }
- bGPDcurve *gpc = gps->editcurve;
- if ((all_strokes) || (gpc->flag & GP_CURVE_SELECT)) {
- gpencil_reset_vertex(gps, mode);
- }
- }
- else {
- if ((all_strokes) || (gps->flag & GP_STROKE_SELECT)) {
- gpencil_reset_vertex(gps, mode);
- }
- }
-
- changed = true;
- }
- /* if not multiedit, exit loop*/
- if (!is_multiedit) {
- break;
- }
- }
- }
- }
- CTX_DATA_END;
-
- if (changed) {
- /* updates */
- DEG_id_tag_update(&gpd->id,
- ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
- DEG_id_tag_update(&obact->id, ID_RECALC_COPY_ON_WRITE);
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
- }
-
- return OPERATOR_FINISHED;
-}
-
-void GPENCIL_OT_stroke_reset_vertex_color(wmOperatorType *ot)
-{
- static EnumPropertyItem mode_types_items[] = {
- {GPPAINT_MODE_STROKE, "STROKE", 0, "Stroke", "Reset Vertex Color to Stroke only"},
- {GPPAINT_MODE_FILL, "FILL", 0, "Fill", "Reset Vertex Color to Fill only"},
- {GPPAINT_MODE_BOTH, "BOTH", 0, "Stroke and Fill", "Reset Vertex Color to Stroke and Fill"},
- {0, NULL, 0, NULL, NULL},
- };
-
- /* identifiers */
- ot->name = "Reset Vertex Color";
- ot->idname = "GPENCIL_OT_stroke_reset_vertex_color";
- ot->description = "Reset vertex color for all or selected strokes";
-
- /* callbacks */
- ot->exec = gpencil_stroke_reset_vertex_color_exec;
- ot->poll = gpencil_stroke_edit_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- ot->prop = RNA_def_enum(ot->srna, "mode", mode_types_items, GPPAINT_MODE_BOTH, "Mode", "");
-}
-
-/** \} */
diff --git a/source/blender/editors/gpencil/gpencil_vertex_ops.c b/source/blender/editors/gpencil/gpencil_vertex_ops.c
index 69e50beb66e..c3fd8d10b64 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_ops.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_ops.c
@@ -60,23 +60,69 @@
#include "gpencil_intern.h"
-enum {
- GP_PAINT_VERTEX_STROKE = 0,
- GP_PAINT_VERTEX_FILL = 1,
- GP_PAINT_VERTEX_BOTH = 2,
-};
-
static const EnumPropertyItem gpencil_modesEnumPropertyItem_mode[] = {
- {GP_PAINT_VERTEX_STROKE, "STROKE", 0, "Stroke", ""},
- {GP_PAINT_VERTEX_FILL, "FILL", 0, "Fill", ""},
- {GP_PAINT_VERTEX_BOTH, "BOTH", 0, "Both", ""},
+ {GPPAINT_MODE_STROKE, "STROKE", 0, "Stroke", ""},
+ {GPPAINT_MODE_FILL, "FILL", 0, "Fill", ""},
+ {GPPAINT_MODE_BOTH, "BOTH", 0, "Stroke and Fill", ""},
{0, NULL, 0, NULL, NULL},
};
+/* Helper: Check if any stroke is selected. */
+static bool is_any_stroke_selected(bContext *C, const bool is_multiedit, const bool is_curve_edit)
+{
+ bool is_selected = false;
+
+ /* If not enabled any mask mode, the strokes are considered as not selected. */
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ if (!GPENCIL_ANY_VERTEX_MASK(ts->gpencil_selectmode_vertex)) {
+ return false;
+ }
+
+ CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
+ bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ if (gpf == NULL) {
+ continue;
+ }
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
+ }
+
+ if (is_curve_edit) {
+ if (gps->editcurve == NULL) {
+ continue;
+ }
+ bGPDcurve *gpc = gps->editcurve;
+ if (gpc->flag & GP_CURVE_SELECT) {
+ is_selected = true;
+ break;
+ }
+ }
+ else {
+ if (gps->flag & GP_STROKE_SELECT) {
+ is_selected = true;
+ break;
+ }
+ }
+ }
+ /* if not multiedit, exit loop*/
+ if (!is_multiedit) {
+ break;
+ }
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ return is_selected;
+}
+
/* Poll callback for stroke vertex paint operator. */
static bool gpencil_vertexpaint_mode_poll(bContext *C)
{
- ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
if ((ob == NULL) || (ob->type != OB_GPENCIL)) {
return false;
@@ -84,10 +130,6 @@ static bool gpencil_vertexpaint_mode_poll(bContext *C)
bGPdata *gpd = (bGPdata *)ob->data;
if (GPENCIL_VERTEX_MODE(gpd)) {
- if (!(GPENCIL_ANY_VERTEX_MASK(ts->gpencil_selectmode_vertex))) {
- return false;
- }
-
/* Any data to use. */
if (gpd->layers.first) {
return true;
@@ -101,10 +143,9 @@ static int gpencil_vertexpaint_brightness_contrast_exec(bContext *C, wmOperator
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)ob->data;
- bool changed = false;
- int i;
- bGPDspoint *pt;
- const int mode = RNA_enum_get(op->ptr, "mode");
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ const eGp_Vertex_Mode mode = RNA_enum_get(op->ptr, "mode");
+ const bool any_selected = is_any_stroke_selected(C, is_multiedit, false);
float gain, offset;
{
@@ -130,34 +171,56 @@ static int gpencil_vertexpaint_brightness_contrast_exec(bContext *C, wmOperator
}
/* Loop all selected strokes. */
- GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
- if (gps->flag & GP_STROKE_SELECT) {
- changed = true;
- /* Fill color. */
- if (gps->flag & GP_STROKE_SELECT) {
- changed = true;
- if (mode != GP_PAINT_VERTEX_STROKE) {
- if (gps->vert_color_fill[3] > 0.0f) {
- for (int i2 = 0; i2 < 3; i2++) {
- gps->vert_color_fill[i2] = gain * gps->vert_color_fill[i2] + offset;
- }
- }
+ bool changed = false;
+ CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
+ bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
+
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ if (gpf == NULL) {
+ continue;
}
- }
- /* Stroke points. */
- if (mode != GP_PAINT_VERTEX_FILL) {
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- if ((pt->flag & GP_SPOINT_SELECT) && (pt->vert_color[3] > 0.0f)) {
- for (int i2 = 0; i2 < 3; i2++) {
- pt->vert_color[i2] = gain * pt->vert_color[i2] + offset;
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
+ }
+
+ if ((!any_selected) || (gps->flag & GP_STROKE_SELECT)) {
+ /* Fill color. */
+ if (mode != GPPAINT_MODE_STROKE) {
+ if (gps->vert_color_fill[3] > 0.0f) {
+ changed = true;
+ for (int i2 = 0; i2 < 3; i2++) {
+ gps->vert_color_fill[i2] = gain * gps->vert_color_fill[i2] + offset;
+ }
+ }
+ }
+ /* Stroke points. */
+ if (mode != GPPAINT_MODE_FILL) {
+ changed = true;
+ int i;
+ bGPDspoint *pt;
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (((!any_selected) || (pt->flag & GP_SPOINT_SELECT)) &&
+ (pt->vert_color[3] > 0.0f)) {
+ for (int i2 = 0; i2 < 3; i2++) {
+ pt->vert_color[i2] = gain * pt->vert_color[i2] + offset;
+ }
+ }
+ }
}
}
}
+ /* if not multiedit, exit loop*/
+ if (!is_multiedit) {
+ break;
+ }
}
}
}
- GP_EDITABLE_STROKES_END(gpstroke_iter);
+ CTX_DATA_END;
/* notifiers */
if (changed) {
@@ -185,7 +248,8 @@ void GPENCIL_OT_vertex_color_brightness_contrast(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* params */
- ot->prop = RNA_def_enum(ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, 0, "Mode", "");
+ ot->prop = RNA_def_enum(
+ ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, GPPAINT_MODE_BOTH, "Mode", "");
const float min = -100, max = +100;
prop = RNA_def_float(ot->srna, "brightness", 0.0f, min, max, "Brightness", "", min, max);
prop = RNA_def_float(ot->srna, "contrast", 0.0f, min, max, "Contrast", "", min, max);
@@ -197,64 +261,88 @@ static int gpencil_vertexpaint_hsv_exec(bContext *C, wmOperator *op)
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)ob->data;
- bool changed = false;
- int i;
- bGPDspoint *pt;
- float hsv[3];
-
- const int mode = RNA_enum_get(op->ptr, "mode");
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ const eGp_Vertex_Mode mode = RNA_enum_get(op->ptr, "mode");
+ const bool any_selected = is_any_stroke_selected(C, is_multiedit, false);
float hue = RNA_float_get(op->ptr, "h");
float sat = RNA_float_get(op->ptr, "s");
float val = RNA_float_get(op->ptr, "v");
- /* Loop all selected strokes. */
- GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
- if (gps->flag & GP_STROKE_SELECT) {
- changed = true;
-
- /* Fill color. */
- if (mode != GP_PAINT_VERTEX_STROKE) {
- if (gps->vert_color_fill[3] > 0.0f) {
+ bool changed = false;
+ CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
+ bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
- rgb_to_hsv_v(gps->vert_color_fill, hsv);
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ if (gpf == NULL) {
+ continue;
+ }
- hsv[0] += (hue - 0.5f);
- if (hsv[0] > 1.0f) {
- hsv[0] -= 1.0f;
- }
- else if (hsv[0] < 0.0f) {
- hsv[0] += 1.0f;
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
}
- hsv[1] *= sat;
- hsv[2] *= val;
- hsv_to_rgb_v(hsv, gps->vert_color_fill);
- }
- }
+ if ((!any_selected) || (gps->flag & GP_STROKE_SELECT)) {
+ float hsv[3];
- /* Stroke points. */
- if (mode != GP_PAINT_VERTEX_FILL) {
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- if ((pt->flag & GP_SPOINT_SELECT) && (pt->vert_color[3] > 0.0f)) {
- rgb_to_hsv_v(pt->vert_color, hsv);
+ /* Fill color. */
+ if (mode != GPPAINT_MODE_STROKE) {
+ if (gps->vert_color_fill[3] > 0.0f) {
+ changed = true;
- hsv[0] += (hue - 0.5f);
- if (hsv[0] > 1.0f) {
- hsv[0] -= 1.0f;
- }
- else if (hsv[0] < 0.0f) {
- hsv[0] += 1.0f;
+ rgb_to_hsv_v(gps->vert_color_fill, hsv);
+
+ hsv[0] += (hue - 0.5f);
+ if (hsv[0] > 1.0f) {
+ hsv[0] -= 1.0f;
+ }
+ else if (hsv[0] < 0.0f) {
+ hsv[0] += 1.0f;
+ }
+ hsv[1] *= sat;
+ hsv[2] *= val;
+
+ hsv_to_rgb_v(hsv, gps->vert_color_fill);
+ }
}
- hsv[1] *= sat;
- hsv[2] *= val;
- hsv_to_rgb_v(hsv, pt->vert_color);
+ /* Stroke points. */
+ if (mode != GPPAINT_MODE_FILL) {
+ changed = true;
+ int i;
+ bGPDspoint *pt;
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (((!any_selected) || (pt->flag & GP_SPOINT_SELECT)) &&
+ (pt->vert_color[3] > 0.0f)) {
+ rgb_to_hsv_v(pt->vert_color, hsv);
+
+ hsv[0] += (hue - 0.5f);
+ if (hsv[0] > 1.0f) {
+ hsv[0] -= 1.0f;
+ }
+ else if (hsv[0] < 0.0f) {
+ hsv[0] += 1.0f;
+ }
+ hsv[1] *= sat;
+ hsv[2] *= val;
+
+ hsv_to_rgb_v(hsv, pt->vert_color);
+ }
+ }
+ }
}
}
+ /* if not multiedit, exit loop*/
+ if (!is_multiedit) {
+ break;
+ }
}
}
}
- GP_EDITABLE_STROKES_END(gpstroke_iter);
+
+ CTX_DATA_END;
/* notifiers */
if (changed) {
@@ -280,7 +368,8 @@ void GPENCIL_OT_vertex_color_hsv(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* params */
- ot->prop = RNA_def_enum(ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, 0, "Mode", "");
+ ot->prop = RNA_def_enum(
+ ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, GPPAINT_MODE_BOTH, "Mode", "");
RNA_def_float(ot->srna, "h", 0.5f, 0.0f, 1.0f, "Hue", "", 0.0f, 1.0f);
RNA_def_float(ot->srna, "s", 1.0f, 0.0f, 2.0f, "Saturation", "", 0.0f, 2.0f);
RNA_def_float(ot->srna, "v", 1.0f, 0.0f, 2.0f, "Value", "", 0.0f, 2.0f);
@@ -291,41 +380,62 @@ static int gpencil_vertexpaint_invert_exec(bContext *C, wmOperator *op)
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)ob->data;
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ const eGp_Vertex_Mode mode = RNA_enum_get(op->ptr, "mode");
+ const bool any_selected = is_any_stroke_selected(C, is_multiedit, false);
+
bool changed = false;
- int i;
- bGPDspoint *pt;
+ CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
+ bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
- const int mode = RNA_enum_get(op->ptr, "mode");
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ if (gpf == NULL) {
+ continue;
+ }
- /* Loop all selected strokes. */
- GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
- if (gps->flag & GP_STROKE_SELECT) {
- changed = true;
- /* Fill color. */
- if (gps->flag & GP_STROKE_SELECT) {
- changed = true;
- if (mode != GP_PAINT_VERTEX_STROKE) {
- if (gps->vert_color_fill[3] > 0.0f) {
- for (int i2 = 0; i2 < 3; i2++) {
- gps->vert_color_fill[i2] = 1.0f - gps->vert_color_fill[i2];
- }
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
}
- }
- }
- /* Stroke points. */
- if (mode != GP_PAINT_VERTEX_FILL) {
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- if ((pt->flag & GP_SPOINT_SELECT) && (pt->vert_color[3] > 0.0f)) {
- for (int i2 = 0; i2 < 3; i2++) {
- pt->vert_color[i2] = 1.0f - pt->vert_color[i2];
+ if ((!any_selected) || (gps->flag & GP_STROKE_SELECT)) {
+ /* Fill color. */
+ if (mode != GPPAINT_MODE_STROKE) {
+ if (gps->vert_color_fill[3] > 0.0f) {
+ changed = true;
+ for (int i2 = 0; i2 < 3; i2++) {
+ gps->vert_color_fill[i2] = 1.0f - gps->vert_color_fill[i2];
+ }
+ }
+ }
+
+ /* Stroke points. */
+ if (mode != GPPAINT_MODE_FILL) {
+ changed = true;
+ int i;
+ bGPDspoint *pt;
+
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (((!any_selected) || (pt->flag & GP_SPOINT_SELECT)) &&
+ (pt->vert_color[3] > 0.0f)) {
+ for (int i2 = 0; i2 < 3; i2++) {
+ pt->vert_color[i2] = 1.0f - pt->vert_color[i2];
+ }
+ }
+ }
}
}
}
+ /* if not multiedit, exit loop*/
+ if (!is_multiedit) {
+ break;
+ }
}
}
}
- GP_EDITABLE_STROKES_END(gpstroke_iter);
+ CTX_DATA_END;
/* notifiers */
if (changed) {
@@ -351,7 +461,8 @@ void GPENCIL_OT_vertex_color_invert(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* params */
- ot->prop = RNA_def_enum(ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, 0, "Mode", "");
+ ot->prop = RNA_def_enum(
+ ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, GPPAINT_MODE_BOTH, "Mode", "");
}
static int gpencil_vertexpaint_levels_exec(bContext *C, wmOperator *op)
@@ -359,41 +470,63 @@ static int gpencil_vertexpaint_levels_exec(bContext *C, wmOperator *op)
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)ob->data;
- bool changed = false;
- bGPDspoint *pt;
-
- const int mode = RNA_enum_get(op->ptr, "mode");
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ const eGp_Vertex_Mode mode = RNA_enum_get(op->ptr, "mode");
+ const bool any_selected = is_any_stroke_selected(C, is_multiedit, false);
float gain = RNA_float_get(op->ptr, "gain");
float offset = RNA_float_get(op->ptr, "offset");
- /* Loop all selected strokes. */
- GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
+ bool changed = false;
+ CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
+ bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
- /* Fill color. */
- if (gps->flag & GP_STROKE_SELECT) {
- changed = true;
- if (mode != GP_PAINT_VERTEX_STROKE) {
- if (gps->vert_color_fill[3] > 0.0f) {
- for (int i2 = 0; i2 < 3; i2++) {
- gps->vert_color_fill[i2] = gain * (gps->vert_color_fill[i2] + offset);
- }
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ if (gpf == NULL) {
+ continue;
}
- }
- }
- /* Stroke points. */
- if (mode != GP_PAINT_VERTEX_FILL) {
- int i;
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- if ((pt->flag & GP_SPOINT_SELECT) && (pt->vert_color[3] > 0.0f)) {
- for (int i2 = 0; i2 < 3; i2++) {
- pt->vert_color[i2] = gain * (pt->vert_color[i2] + offset);
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
}
+
+ if ((!any_selected) || (gps->flag & GP_STROKE_SELECT)) {
+ /* Fill color. */
+ if (mode != GPPAINT_MODE_STROKE) {
+ if (gps->vert_color_fill[3] > 0.0f) {
+ changed = true;
+ for (int i2 = 0; i2 < 3; i2++) {
+ gps->vert_color_fill[i2] = gain * (gps->vert_color_fill[i2] + offset);
+ }
+ }
+ }
+ /* Stroke points. */
+ if (mode != GPPAINT_MODE_FILL) {
+ changed = true;
+ int i;
+ bGPDspoint *pt;
+
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (((!any_selected) || (pt->flag & GP_SPOINT_SELECT)) &&
+ (pt->vert_color[3] > 0.0f)) {
+ for (int i2 = 0; i2 < 3; i2++) {
+ pt->vert_color[i2] = gain * (pt->vert_color[i2] + offset);
+ }
+ }
+ }
+ }
+ }
+ }
+ /* if not multiedit, exit loop*/
+ if (!is_multiedit) {
+ break;
}
}
}
}
- GP_EDITABLE_STROKES_END(gpstroke_iter);
+ CTX_DATA_END;
/* notifiers */
if (changed) {
@@ -420,7 +553,8 @@ void GPENCIL_OT_vertex_color_levels(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* params */
- ot->prop = RNA_def_enum(ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, 0, "Mode", "");
+ ot->prop = RNA_def_enum(
+ ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, GPPAINT_MODE_BOTH, "Mode", "");
RNA_def_float(
ot->srna, "offset", 0.0f, -1.0f, 1.0f, "Offset", "Value to add to colors", -1.0f, 1.0f);
@@ -436,36 +570,58 @@ static int gpencil_vertexpaint_set_exec(bContext *C, wmOperator *op)
Paint *paint = &ts->gp_vertexpaint->paint;
Brush *brush = paint->brush;
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ const eGp_Vertex_Mode mode = RNA_enum_get(op->ptr, "mode");
+ const bool any_selected = is_any_stroke_selected(C, is_multiedit, false);
+ float factor = RNA_float_get(op->ptr, "factor");
+
bool changed = false;
- int i;
- bGPDspoint *pt;
+ CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
+ bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
- const int mode = RNA_enum_get(op->ptr, "mode");
- float factor = RNA_float_get(op->ptr, "factor");
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ if (gpf == NULL) {
+ continue;
+ }
- /* Loop all selected strokes. */
- GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
-
- /* Fill color. */
- if (gps->flag & GP_STROKE_SELECT) {
- changed = true;
- if (mode != GP_PAINT_VERTEX_STROKE) {
- copy_v3_v3(gps->vert_color_fill, brush->rgb);
- gps->vert_color_fill[3] = factor;
- }
- }
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
+ }
- /* Stroke points. */
- if (mode != GP_PAINT_VERTEX_FILL) {
- for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
- if (pt->flag & GP_SPOINT_SELECT) {
- copy_v3_v3(pt->vert_color, brush->rgb);
- pt->vert_color[3] = factor;
+ if ((!any_selected) || (gps->flag & GP_STROKE_SELECT)) {
+ /* Fill color. */
+ if (mode != GPPAINT_MODE_STROKE) {
+ changed = true;
+ copy_v3_v3(gps->vert_color_fill, brush->rgb);
+ gps->vert_color_fill[3] = factor;
+ }
+
+ /* Stroke points. */
+ if (mode != GPPAINT_MODE_FILL) {
+ changed = true;
+ int i;
+ bGPDspoint *pt;
+
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if ((!any_selected) || (pt->flag & GP_SPOINT_SELECT)) {
+ copy_v3_v3(pt->vert_color, brush->rgb);
+ pt->vert_color[3] = factor;
+ }
+ }
+ }
+ }
+ }
+ /* if not multiedit, exit loop*/
+ if (!is_multiedit) {
+ break;
}
}
}
}
- GP_EDITABLE_STROKES_END(gpstroke_iter);
+ CTX_DATA_END;
/* notifiers */
if (changed) {
@@ -492,7 +648,8 @@ void GPENCIL_OT_vertex_color_set(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* params */
- ot->prop = RNA_def_enum(ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, 0, "Mode", "");
+ ot->prop = RNA_def_enum(
+ ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, GPPAINT_MODE_BOTH, "Mode", "");
RNA_def_float(ot->srna, "factor", 1.0f, 0.001f, 1.0f, "Factor", "Mix Factor", 0.001f, 1.0f);
}
@@ -900,3 +1057,114 @@ void GPENCIL_OT_extract_palette_vertex(wmOperatorType *ot)
ot->srna, "selected", false, "Only Selected", "Convert only selected strokes");
RNA_def_int(ot->srna, "threshold", 1, 1, 4, "Threshold", "", 1, 4);
}
+
+/* -------------------------------------------------------------------- */
+/** \name Reset Stroke Vertex Color Operator
+ * \{ */
+
+static void gpencil_reset_vertex(bGPDstroke *gps, eGp_Vertex_Mode mode)
+{
+ if (mode != GPPAINT_MODE_STROKE) {
+ zero_v4(gps->vert_color_fill);
+ }
+
+ if (mode != GPPAINT_MODE_FILL) {
+ bGPDspoint *pt;
+ for (int i = 0; i < gps->totpoints; i++) {
+ pt = &gps->points[i];
+ zero_v4(pt->vert_color);
+ }
+ }
+}
+
+static int gpencil_stroke_reset_vertex_color_exec(bContext *C, wmOperator *op)
+{
+ Object *obact = CTX_data_active_object(C);
+ bGPdata *gpd = (bGPdata *)obact->data;
+ const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd);
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ const eGp_Vertex_Mode mode = RNA_enum_get(op->ptr, "mode");
+
+ /* First need to check if there are something selected. If not, apply to all strokes. */
+ const bool any_selected = is_any_stroke_selected(C, is_multiedit, is_curve_edit);
+
+ /* Reset Vertex colors. */
+ bool changed = false;
+ CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
+ bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
+
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ if (gpf == NULL) {
+ continue;
+ }
+
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
+ }
+
+ if (is_curve_edit) {
+ if (gps->editcurve == NULL) {
+ continue;
+ }
+ bGPDcurve *gpc = gps->editcurve;
+ if ((!any_selected) || (gpc->flag & GP_CURVE_SELECT)) {
+ gpencil_reset_vertex(gps, mode);
+ }
+ }
+ else {
+ if ((!any_selected) || (gps->flag & GP_STROKE_SELECT)) {
+ gpencil_reset_vertex(gps, mode);
+ }
+ }
+
+ changed = true;
+ }
+ /* if not multiedit, exit loop*/
+ if (!is_multiedit) {
+ break;
+ }
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ if (changed) {
+ /* updates */
+ DEG_id_tag_update(&gpd->id,
+ ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+ DEG_id_tag_update(&obact->id, ID_RECALC_COPY_ON_WRITE);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_stroke_reset_vertex_color(wmOperatorType *ot)
+{
+ static EnumPropertyItem mode_types_items[] = {
+ {GPPAINT_MODE_STROKE, "STROKE", 0, "Stroke", "Reset Vertex Color to Stroke only"},
+ {GPPAINT_MODE_FILL, "FILL", 0, "Fill", "Reset Vertex Color to Fill only"},
+ {GPPAINT_MODE_BOTH, "BOTH", 0, "Stroke and Fill", "Reset Vertex Color to Stroke and Fill"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ /* identifiers */
+ ot->name = "Reset Vertex Color";
+ ot->idname = "GPENCIL_OT_stroke_reset_vertex_color";
+ ot->description = "Reset vertex color for all or selected strokes";
+
+ /* callbacks */
+ ot->exec = gpencil_stroke_reset_vertex_color_exec;
+ ot->poll = gpencil_vertexpaint_mode_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_enum(ot->srna, "mode", mode_types_items, GPPAINT_MODE_BOTH, "Mode", "");
+}
+
+/** \} */
diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h
index ba77da24406..40b0a8d96b1 100644
--- a/source/blender/editors/include/ED_datafiles.h
+++ b/source/blender/editors/include/ED_datafiles.h
@@ -50,6 +50,9 @@ extern char datatoc_prvicons_png[];
extern int datatoc_alert_icons_png_size;
extern char datatoc_alert_icons_png[];
+extern int datatoc_blender_logo_png_size;
+extern char datatoc_blender_logo_png[];
+
extern int datatoc_splash_png_size;
extern char datatoc_splash_png[];
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h
index 84808416074..a5a8df916d6 100644
--- a/source/blender/editors/include/ED_fileselect.h
+++ b/source/blender/editors/include/ED_fileselect.h
@@ -101,9 +101,9 @@ typedef struct FileSelection {
struct View2D;
struct rcti;
-struct FileSelectParams *ED_fileselect_get_params(struct SpaceFile *sfile);
+struct FileSelectParams *ED_fileselect_ensure_active_params(struct SpaceFile *sfile);
+struct FileSelectParams *ED_fileselect_get_active_params(const struct SpaceFile *sfile);
-short ED_fileselect_set_params(struct SpaceFile *sfile);
void ED_fileselect_set_params_from_userdef(struct SpaceFile *sfile);
void ED_fileselect_params_to_userdef(struct SpaceFile *sfile,
const int temp_win_size[],
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index f9dc23502c7..005dbf0e381 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -26,6 +26,7 @@
#include "BLI_compiler_attrs.h"
#include "BLI_sys_types.h" /* size_t */
#include "RNA_types.h"
+#include "UI_interface_icons.h"
#ifdef __cplusplus
extern "C" {
@@ -1351,7 +1352,7 @@ struct PointerRNA *UI_but_operator_ptr_get(uiBut *but);
void UI_but_unit_type_set(uiBut *but, const int unit_type);
int UI_but_unit_type_get(const uiBut *but);
-enum {
+typedef enum uiStringInfoType {
BUT_GET_RNAPROP_IDENTIFIER = 1,
BUT_GET_RNASTRUCT_IDENTIFIER,
BUT_GET_RNAENUM_IDENTIFIER,
@@ -1364,10 +1365,10 @@ enum {
BUT_GET_RNAENUM_TIP,
BUT_GET_OP_KEYMAP,
BUT_GET_PROP_KEYMAP,
-};
+} uiStringInfoType;
typedef struct uiStringInfo {
- int type;
+ uiStringInfoType type;
char *strinfo;
} uiStringInfo;
@@ -2431,6 +2432,9 @@ void uiItemTabsEnumR_prop(uiLayout *layout,
/* Only for testing, inspecting layouts. */
const char *UI_layout_introspect(uiLayout *layout);
+/* Helper to add a big icon and create a split layout for alert boxes. */
+uiLayout *uiItemsAlertBox(uiBlock *block, const int size, const eAlertIcon icon);
+
/* UI Operators */
typedef struct uiDragColorHandle {
float color[3];
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 685b34b7185..4a02c6b6e88 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -6795,7 +6795,7 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...)
va_start(args, but);
while ((si = (uiStringInfo *)va_arg(args, void *))) {
- int type = si->type;
+ uiStringInfoType type = si->type;
char *tmp = NULL;
if (type == BUT_GET_LABEL) {
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index 02a9c3742d7..39b405a02b8 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -90,9 +90,8 @@ static IDProperty *shortcut_property_from_rna(bContext *C, uiBut *but)
}
/* Create ID property of data path, to pass to the operator. */
- IDProperty *prop;
const IDPropertyTemplate val = {0};
- prop = IDP_New(IDP_GROUP, &val, __func__);
+ IDProperty *prop = IDP_New(IDP_GROUP, &val, __func__);
IDP_AddToGroup(prop, IDP_NewString(final_data_path, "data_path", strlen(final_data_path) + 1));
MEM_freeN((void *)final_data_path);
@@ -167,43 +166,40 @@ static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event))
static uiBlock *menu_change_shortcut(bContext *C, ARegion *region, void *arg)
{
wmWindowManager *wm = CTX_wm_manager(C);
- uiBlock *block;
uiBut *but = (uiBut *)arg;
- wmKeyMap *km;
- wmKeyMapItem *kmi;
PointerRNA ptr;
- uiLayout *layout;
const uiStyle *style = UI_style_get_dpi();
IDProperty *prop;
const char *idname = shortcut_get_operator_property(C, but, &prop);
- kmi = WM_key_event_operator(C,
- idname,
- but->opcontext,
- prop,
- EVT_TYPE_MASK_HOTKEY_INCLUDE,
- EVT_TYPE_MASK_HOTKEY_EXCLUDE,
- &km);
+ wmKeyMap *km;
+ wmKeyMapItem *kmi = WM_key_event_operator(C,
+ idname,
+ but->opcontext,
+ prop,
+ EVT_TYPE_MASK_HOTKEY_INCLUDE,
+ EVT_TYPE_MASK_HOTKEY_EXCLUDE,
+ &km);
U.runtime.is_dirty = true;
BLI_assert(kmi != NULL);
RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
- block = UI_block_begin(C, region, "_popup", UI_EMBOSS);
+ uiBlock *block = UI_block_begin(C, region, "_popup", UI_EMBOSS);
UI_block_func_handle_set(block, but_shortcut_name_func, but);
UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT);
UI_block_direction_set(block, UI_DIR_CENTER_Y);
- layout = UI_block_layout(block,
- UI_LAYOUT_VERTICAL,
- UI_LAYOUT_PANEL,
- 0,
- 0,
- U.widget_unit * 10,
- U.widget_unit * 2,
- 0,
- style);
+ uiLayout *layout = UI_block_layout(block,
+ UI_LAYOUT_VERTICAL,
+ UI_LAYOUT_PANEL,
+ 0,
+ 0,
+ U.widget_unit * 10,
+ U.widget_unit * 2,
+ 0,
+ style);
uiItemL(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Change Shortcut"), ICON_HAND);
uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE);
@@ -223,22 +219,17 @@ static int g_kmi_id_hack;
static uiBlock *menu_add_shortcut(bContext *C, ARegion *region, void *arg)
{
wmWindowManager *wm = CTX_wm_manager(C);
- uiBlock *block;
uiBut *but = (uiBut *)arg;
- wmKeyMap *km;
- wmKeyMapItem *kmi;
PointerRNA ptr;
- uiLayout *layout;
const uiStyle *style = UI_style_get_dpi();
- int kmi_id;
IDProperty *prop;
const char *idname = shortcut_get_operator_property(C, but, &prop);
/* XXX this guess_opname can potentially return a different keymap
* than being found on adding later... */
- km = WM_keymap_guess_opname(C, idname);
- kmi = WM_keymap_add_item(km, idname, EVT_AKEY, KM_PRESS, 0, 0);
- kmi_id = kmi->id;
+ wmKeyMap *km = WM_keymap_guess_opname(C, idname);
+ wmKeyMapItem *kmi = WM_keymap_add_item(km, idname, EVT_AKEY, KM_PRESS, 0, 0);
+ int kmi_id = kmi->id;
/* This takes ownership of prop, or prop can be NULL for reset. */
WM_keymap_item_properties_reset(kmi, prop);
@@ -252,19 +243,19 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *region, void *arg)
RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
- block = UI_block_begin(C, region, "_popup", UI_EMBOSS);
+ uiBlock *block = UI_block_begin(C, region, "_popup", UI_EMBOSS);
UI_block_func_handle_set(block, but_shortcut_name_func, but);
UI_block_direction_set(block, UI_DIR_CENTER_Y);
- layout = UI_block_layout(block,
- UI_LAYOUT_VERTICAL,
- UI_LAYOUT_PANEL,
- 0,
- 0,
- U.widget_unit * 10,
- U.widget_unit * 2,
- 0,
- style);
+ uiLayout *layout = UI_block_layout(block,
+ UI_LAYOUT_VERTICAL,
+ UI_LAYOUT_PANEL,
+ 0,
+ 0,
+ U.widget_unit * 10,
+ U.widget_unit * 2,
+ 0,
+ style);
uiItemL(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Assign Shortcut"), ICON_HAND);
uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE);
@@ -282,24 +273,21 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *region, void *arg)
static void menu_add_shortcut_cancel(struct bContext *C, void *arg1)
{
uiBut *but = (uiBut *)arg1;
- wmKeyMap *km;
- wmKeyMapItem *kmi;
- int kmi_id;
IDProperty *prop;
const char *idname = shortcut_get_operator_property(C, but, &prop);
#ifdef USE_KEYMAP_ADD_HACK
- km = WM_keymap_guess_opname(C, idname);
- kmi_id = g_kmi_id_hack;
+ wmKeyMap *km = WM_keymap_guess_opname(C, idname);
+ int kmi_id = g_kmi_id_hack;
UNUSED_VARS(but);
#else
- kmi_id = WM_key_event_operator_id(C, idname, but->opcontext, prop, true, &km);
+ int kmi_id = WM_key_event_operator_id(C, idname, but->opcontext, prop, true, &km);
#endif
shortcut_free_operator_property(prop);
- kmi = WM_keymap_item_find_id(km, kmi_id);
+ wmKeyMapItem *kmi = WM_keymap_item_find_id(km, kmi_id);
WM_keymap_remove_item(km, kmi);
}
@@ -312,18 +300,17 @@ static void popup_change_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg
static void remove_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
{
uiBut *but = (uiBut *)arg1;
- wmKeyMap *km;
- wmKeyMapItem *kmi;
IDProperty *prop;
const char *idname = shortcut_get_operator_property(C, but, &prop);
- kmi = WM_key_event_operator(C,
- idname,
- but->opcontext,
- prop,
- EVT_TYPE_MASK_HOTKEY_INCLUDE,
- EVT_TYPE_MASK_HOTKEY_EXCLUDE,
- &km);
+ wmKeyMap *km;
+ wmKeyMapItem *kmi = WM_key_event_operator(C,
+ idname,
+ but->opcontext,
+ prop,
+ EVT_TYPE_MASK_HOTKEY_INCLUDE,
+ EVT_TYPE_MASK_HOTKEY_EXCLUDE,
+ &km);
BLI_assert(kmi != NULL);
WM_keymap_remove_item(km, kmi);
@@ -349,7 +336,6 @@ static bool ui_but_is_user_menu_compatible(bContext *C, uiBut *but)
static bUserMenuItem *ui_but_user_menu_find(bContext *C, uiBut *but, bUserMenu *um)
{
- MenuType *mt = NULL;
if (but->optype) {
IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
return (bUserMenuItem *)ED_screen_user_menu_item_find_operator(
@@ -373,7 +359,9 @@ static bUserMenuItem *ui_but_user_menu_find(bContext *C, uiBut *but, bUserMenu *
}
return umi;
}
- if ((mt = UI_but_menutype_get(but))) {
+
+ MenuType *mt = UI_but_menutype_get(but);
+ if (mt != NULL) {
return (bUserMenuItem *)ED_screen_user_menu_item_find_menu(&um->items, mt);
}
return NULL;
@@ -515,7 +503,6 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
uiPopupMenu *pup;
uiLayout *layout;
-
{
uiStringInfo label = {BUT_GET_LABEL, NULL};
@@ -979,7 +966,6 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
if (ui_but_is_user_menu_compatible(C, but)) {
uiBlock *block = uiLayoutGetBlock(layout);
const int w = uiLayoutGetWidth(layout);
- uiBut *but2;
bool item_found = false;
uint um_array_len;
@@ -991,7 +977,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
}
bUserMenuItem *umi = ui_but_user_menu_find(C, but, um);
if (umi != NULL) {
- but2 = uiDefIconTextBut(
+ uiBut *but2 = uiDefIconTextBut(
block,
UI_BTYPE_BUT,
0,
@@ -1016,7 +1002,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
}
if (!item_found) {
- but2 = uiDefIconTextBut(
+ uiBut *but2 = uiDefIconTextBut(
block,
UI_BTYPE_BUT,
0,
@@ -1043,11 +1029,10 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
const char *idname = shortcut_get_operator_property(C, but, &prop);
if (idname != NULL) {
uiBlock *block = uiLayoutGetBlock(layout);
- uiBut *but2;
const int w = uiLayoutGetWidth(layout);
- wmKeyMap *km;
/* We want to know if this op has a shortcut, be it hotkey or not. */
+ wmKeyMap *km;
wmKeyMapItem *kmi = WM_key_event_operator(
C, idname, but->opcontext, prop, EVT_TYPE_MASK_ALL, 0, &km);
@@ -1066,77 +1051,80 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
"");
#endif
- but2 = uiDefIconTextBut(block,
- UI_BTYPE_BUT,
- 0,
- ICON_HAND,
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Change Shortcut"),
- 0,
- 0,
- w,
- UI_UNIT_Y,
- NULL,
- 0,
- 0,
- 0,
- 0,
- "");
+ uiBut *but2 = uiDefIconTextBut(
+ block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_HAND,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Change Shortcut"),
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ "");
UI_but_func_set(but2, popup_change_shortcut_func, but, NULL);
}
else {
- but2 = uiDefIconTextBut(block,
- UI_BTYPE_BUT,
- 0,
- ICON_HAND,
- IFACE_("Non-Keyboard Shortcut"),
- 0,
- 0,
- w,
- UI_UNIT_Y,
- NULL,
- 0,
- 0,
- 0,
- 0,
- TIP_("Only keyboard shortcuts can be edited that way, "
- "please use User Preferences otherwise"));
+ uiBut *but2 = uiDefIconTextBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_HAND,
+ IFACE_("Non-Keyboard Shortcut"),
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Only keyboard shortcuts can be edited that way, "
+ "please use User Preferences otherwise"));
UI_but_flag_enable(but2, UI_BUT_DISABLED);
}
- but2 = uiDefIconTextBut(block,
- UI_BTYPE_BUT,
- 0,
- ICON_BLANK1,
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Shortcut"),
- 0,
- 0,
- w,
- UI_UNIT_Y,
- NULL,
- 0,
- 0,
- 0,
- 0,
- "");
+ uiBut *but2 = uiDefIconTextBut(
+ block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_BLANK1,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Shortcut"),
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ "");
UI_but_func_set(but2, remove_shortcut_func, but, NULL);
}
/* only show 'assign' if there's a suitable key map for it to go in */
else if (WM_keymap_guess_opname(C, idname)) {
- but2 = uiDefIconTextBut(block,
- UI_BTYPE_BUT,
- 0,
- ICON_HAND,
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Assign Shortcut"),
- 0,
- 0,
- w,
- UI_UNIT_Y,
- NULL,
- 0,
- 0,
- 0,
- 0,
- "");
+ uiBut *but2 = uiDefIconTextBut(
+ block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_HAND,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Assign Shortcut"),
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ "");
UI_but_func_set(but2, popup_add_shortcut_func, but, NULL);
}
@@ -1239,9 +1227,6 @@ void ui_popup_context_menu_for_panel(bContext *C, ARegion *region, Panel *panel)
bScreen *screen = CTX_wm_screen(C);
const bool has_panel_category = UI_panel_category_is_visible(region);
const bool any_item_visible = has_panel_category;
- PointerRNA ptr;
- uiPopupMenu *pup;
- uiLayout *layout;
if (!any_item_visible) {
return;
@@ -1250,10 +1235,11 @@ void ui_popup_context_menu_for_panel(bContext *C, ARegion *region, Panel *panel)
return;
}
+ PointerRNA ptr;
RNA_pointer_create(&screen->id, &RNA_Panel, panel, &ptr);
- pup = UI_popup_menu_begin(C, IFACE_("Panel"), ICON_NONE);
- layout = UI_popup_menu_layout(pup);
+ uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Panel"), ICON_NONE);
+ uiLayout *layout = UI_popup_menu_layout(pup);
if (has_panel_category) {
char tmpstr[80];
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 3c028977a36..f914ccd7497 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -838,6 +838,7 @@ static void ui_apply_but_undo(uiBut *but)
/* fallback, else we don't get an undo! */
if (str == NULL || str[0] == '\0' || str_len_clip == 0) {
str = "Unknown Action";
+ str_len_clip = strlen(str);
}
/* Optionally override undo when undo system doesn't support storing properties. */
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index d61e80e6505..0403287125c 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -5951,3 +5951,45 @@ const char *UI_layout_introspect(uiLayout *layout)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Alert Box with Big Icon
+ * \{ */
+
+/**
+ * Helper to add a big icon and create a split layout for alert popups.
+ * Returns the layout to place further items into the alert box.
+ */
+uiLayout *uiItemsAlertBox(uiBlock *block, const int size, const eAlertIcon icon)
+{
+ const uiStyle *style = UI_style_get_dpi();
+ const short icon_size = 64 * U.dpi_fac;
+ const int text_points_max = MAX2(style->widget.points, style->widgetlabel.points);
+ const int dialog_width = icon_size + (text_points_max * size * U.dpi_fac);
+ /* By default, the space between icon and text/buttons will be equal to the 'columnspace',
+ this extra padding will add some space by increasing the left column width,
+ making the icon placement more symmetrical, between the block edge and the text. */
+ const float icon_padding = 5.0f * U.dpi_fac;
+ /* Calculate the factor of the fixed icon column depending on the block width. */
+ const float split_factor = ((float)icon_size + icon_padding) /
+ (float)(dialog_width - style->columnspace);
+
+ uiLayout *block_layout = UI_block_layout(
+ block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, dialog_width, 0, 0, style);
+
+ /* Split layout to put alert icon on left side. */
+ uiLayout *split_block = uiLayoutSplit(block_layout, split_factor, false);
+
+ /* Alert icon on the left. */
+ uiLayout *layout = uiLayoutRow(split_block, false);
+ /* Using 'align_left' with 'row' avoids stretching the icon along the width of column. */
+ uiLayoutSetAlignment(layout, UI_LAYOUT_ALIGN_LEFT);
+ uiDefButAlert(block, icon, 0, 0, icon_size, icon_size);
+
+ /* The rest of the content on the right. */
+ layout = uiLayoutColumn(split_block, false);
+
+ return layout;
+}
+
+/** \} */
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 0d1e2802242..e5aa0665a16 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -1223,7 +1223,7 @@ typedef struct uiEditSourceStore {
typedef struct uiEditSourceButStore {
char py_dbg_fn[FILE_MAX];
- int py_dbg_ln;
+ int py_dbg_line_number;
} uiEditSourceButStore;
/* should only ever be set while the edit source operator is running */
@@ -1276,21 +1276,21 @@ void UI_editsource_active_but_test(uiBut *but)
struct uiEditSourceButStore *but_store = MEM_callocN(sizeof(uiEditSourceButStore), __func__);
const char *fn;
- int lineno = -1;
+ int line_number = -1;
# if 0
printf("comparing buttons: '%s' == '%s'\n", but->drawstr, ui_editsource_info->but_orig.drawstr);
# endif
- PyC_FileAndNum_Safe(&fn, &lineno);
+ PyC_FileAndNum_Safe(&fn, &line_number);
- if (lineno != -1) {
+ if (line_number != -1) {
BLI_strncpy(but_store->py_dbg_fn, fn, sizeof(but_store->py_dbg_fn));
- but_store->py_dbg_ln = lineno;
+ but_store->py_dbg_line_number = line_number;
}
else {
but_store->py_dbg_fn[0] = '\0';
- but_store->py_dbg_ln = -1;
+ but_store->py_dbg_line_number = -1;
}
BLI_ghash_insert(ui_editsource_info->hash, but, but_store);
@@ -1375,8 +1375,8 @@ static int editsource_exec(bContext *C, wmOperator *op)
}
if (but_store) {
- if (but_store->py_dbg_ln != -1) {
- ret = editsource_text_edit(C, op, but_store->py_dbg_fn, but_store->py_dbg_ln);
+ if (but_store->py_dbg_line_number != -1) {
+ ret = editsource_text_edit(C, op, but_store->py_dbg_fn, but_store->py_dbg_line_number);
}
else {
BKE_report(
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index b60fa40f39a..e96c0a25d6d 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -2452,11 +2452,12 @@ int ui_handler_panel_region(bContext *C,
if (mouse_state == PANEL_MOUSE_INSIDE_HEADER) {
/* All mouse clicks inside panel headers should return in break. */
- retval = WM_UI_HANDLER_BREAK;
if (ELEM(event->type, EVT_RETKEY, EVT_PADENTER, LEFTMOUSE)) {
+ retval = WM_UI_HANDLER_BREAK;
ui_handle_panel_header(C, block, mx, event->type, event->ctrl, event->shift);
}
else if (event->type == RIGHTMOUSE) {
+ retval = WM_UI_HANDLER_BREAK;
ui_popup_context_menu_for_panel(C, region, block->panel);
}
break;
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 4dd543e71a9..a2fe949b6c5 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -3574,7 +3574,7 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE
/* To support redo. */
{
- /* Note that the `base_index` can't be used as the index depends on the view-port
+ /* Note that the `base_index` can't be used as the index depends on the 3D Viewport
* which might not be available on redo. */
BM_mesh_elem_index_ensure(bm, ele->head.htype);
int object_index;
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 4e0f6211c18..bbfdfb2532d 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1618,6 +1618,7 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
Object *ob = ED_object_add_type(C, OB_SPEAKER, NULL, loc, rot, false, local_view_bits);
+ const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ob);
/* to make it easier to start using this immediately in NLA, a default sound clip is created
* ready to be moved around to retime the sound and/or make new sound clips
@@ -1625,13 +1626,13 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op)
{
/* create new data for NLA hierarchy */
AnimData *adt = BKE_animdata_add_id(&ob->id);
- NlaTrack *nlt = BKE_nlatrack_add(adt, NULL);
+ NlaTrack *nlt = BKE_nlatrack_add(adt, NULL, is_liboverride);
NlaStrip *strip = BKE_nla_add_soundstrip(bmain, scene, ob->data);
strip->start = CFRA;
strip->end += strip->start;
/* hook them up */
- BKE_nlatrack_add_strip(nlt, strip);
+ BKE_nlatrack_add_strip(nlt, strip, is_liboverride);
/* auto-name the strip, and give the track an interesting name */
BLI_strncpy(nlt->name, DATA_("SoundTrack"), sizeof(nlt->name));
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index fa8531dfb48..dd015f59e8d 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -706,11 +706,10 @@ static bool edit_constraint_poll_generic(bContext *C,
return false;
}
- if (ID_IS_OVERRIDE_LIBRARY(ob) && !is_liboverride_allowed) {
- if ((con == NULL) || (con->flag & CONSTRAINT_OVERRIDE_LIBRARY_LOCAL) == 0) {
- CTX_wm_operator_poll_msg_set(C, "Cannot edit constraints coming from library override");
- return false;
- }
+ if (!is_liboverride_allowed && BKE_constraint_is_nonlocal_in_liboverride(ob, con)) {
+ CTX_wm_operator_poll_msg_set(
+ C, "Cannot edit constraints coming from linked data in a library override");
+ return false;
}
return true;
diff --git a/source/blender/editors/object/object_gpencil_modifier.c b/source/blender/editors/object/object_gpencil_modifier.c
index eed3c7f419d..af95f5581bd 100644
--- a/source/blender/editors/object/object_gpencil_modifier.c
+++ b/source/blender/editors/object/object_gpencil_modifier.c
@@ -319,6 +319,8 @@ int ED_object_gpencil_modifier_copy(ReportList *reports, Object *ob, GpencilModi
BLI_insertlinkafter(&ob->greasepencil_modifiers, md, nmd);
BKE_gpencil_modifier_unique_name(&ob->greasepencil_modifiers, nmd);
+ nmd->flag |= eGpencilModifierFlag_OverrideLibrary_Local;
+
return 1;
}
@@ -422,7 +424,10 @@ void OBJECT_OT_gpencil_modifier_add(wmOperatorType *ot)
/********** generic functions for operators using mod names and data context *********************/
-static bool gpencil_edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
+static bool gpencil_edit_modifier_poll_generic(bContext *C,
+ StructRNA *rna_type,
+ int obtype_flag,
+ const bool is_liboverride_allowed)
{
PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", rna_type);
Object *ob = (ptr.owner_id) ? (Object *)ptr.owner_id : ED_object_active_context(C);
@@ -438,11 +443,10 @@ static bool gpencil_edit_modifier_poll_generic(bContext *C, StructRNA *rna_type,
return false;
}
- if (ID_IS_OVERRIDE_LIBRARY(ob)) {
- if ((mod == NULL) || (mod->flag & eGpencilModifierFlag_OverrideLibrary_Local) == 0) {
- CTX_wm_operator_poll_msg_set(C, "Cannot edit modifiers coming from library override");
- return false;
- }
+ if (!is_liboverride_allowed && BKE_gpencil_modifier_is_nonlocal_in_liboverride(ob, mod)) {
+ CTX_wm_operator_poll_msg_set(
+ C, "Cannot edit modifiers coming from linked data in a library override");
+ return false;
}
return true;
@@ -450,7 +454,14 @@ static bool gpencil_edit_modifier_poll_generic(bContext *C, StructRNA *rna_type,
static bool gpencil_edit_modifier_poll(bContext *C)
{
- return gpencil_edit_modifier_poll_generic(C, &RNA_GpencilModifier, 0);
+ return gpencil_edit_modifier_poll_generic(C, &RNA_GpencilModifier, 0, false);
+}
+
+/* Used by operators performing actions allowed also on modifiers from the overridden linked object
+ * (not only from added 'local' ones). */
+static bool gpencil_edit_modifier_liboverride_allowed_poll(bContext *C)
+{
+ return gpencil_edit_modifier_poll_generic(C, &RNA_Modifier, 0, true);
}
static void gpencil_edit_modifier_properties(wmOperatorType *ot)
@@ -669,11 +680,6 @@ void OBJECT_OT_gpencil_modifier_move_down(wmOperatorType *ot)
/* ************************* Move to Index Gpencil Modifier Operator ************************* */
-static bool gpencil_modifier_move_to_index_poll(bContext *C)
-{
- return gpencil_edit_modifier_poll(C);
-}
-
static int gpencil_modifier_move_to_index_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_active_context(C);
@@ -706,7 +712,7 @@ void OBJECT_OT_gpencil_modifier_move_to_index(wmOperatorType *ot)
ot->invoke = gpencil_modifier_move_to_index_invoke;
ot->exec = gpencil_modifier_move_to_index_exec;
- ot->poll = gpencil_modifier_move_to_index_poll;
+ ot->poll = gpencil_edit_modifier_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
@@ -823,7 +829,7 @@ void OBJECT_OT_gpencil_modifier_copy(wmOperatorType *ot)
ot->invoke = gpencil_modifier_copy_invoke;
ot->exec = gpencil_modifier_copy_exec;
- ot->poll = gpencil_edit_modifier_poll;
+ ot->poll = gpencil_edit_modifier_liboverride_allowed_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 7d12fa1805b..3111003703f 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -1052,11 +1052,10 @@ bool edit_modifier_poll_generic(bContext *C,
return false;
}
- if (ID_IS_OVERRIDE_LIBRARY(ob) && !is_liboverride_allowed) {
- if ((mod == NULL) || (mod->flag & eModifierFlag_OverrideLibrary_Local) == 0) {
- CTX_wm_operator_poll_msg_set(C, "Cannot edit modifiers coming from library override");
- return false;
- }
+ if (!is_liboverride_allowed && BKE_modifier_is_nonlocal_in_liboverride(ob, mod)) {
+ CTX_wm_operator_poll_msg_set(
+ C, "Cannot edit modifiers coming from linked data in a library override");
+ return false;
}
if (!is_editmode_allowed && CTX_data_edit_object(C) != NULL) {
diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h
index d3a06f0fc2c..e1d03e6f3be 100644
--- a/source/blender/editors/render/render_intern.h
+++ b/source/blender/editors/render/render_intern.h
@@ -46,6 +46,8 @@ void MATERIAL_OT_paste(struct wmOperatorType *ot);
void SCENE_OT_view_layer_add(struct wmOperatorType *ot);
void SCENE_OT_view_layer_remove(struct wmOperatorType *ot);
+void SCENE_OT_view_layer_add_aov(struct wmOperatorType *ot);
+void SCENE_OT_view_layer_remove_aov(struct wmOperatorType *ot);
void SCENE_OT_light_cache_bake(struct wmOperatorType *ot);
void SCENE_OT_light_cache_free(struct wmOperatorType *ot);
diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c
index 706249a3f8b..e0aa02b354d 100644
--- a/source/blender/editors/render/render_ops.c
+++ b/source/blender/editors/render/render_ops.c
@@ -53,6 +53,8 @@ void ED_operatortypes_render(void)
WM_operatortype_append(SCENE_OT_view_layer_add);
WM_operatortype_append(SCENE_OT_view_layer_remove);
+ WM_operatortype_append(SCENE_OT_view_layer_add_aov);
+ WM_operatortype_append(SCENE_OT_view_layer_remove_aov);
WM_operatortype_append(SCENE_OT_render_view_add);
WM_operatortype_append(SCENE_OT_render_view_remove);
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 60e5c2081fd..b69337b1621 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -90,6 +90,7 @@
#include "UI_interface.h"
+#include "RE_engine.h"
#include "RE_pipeline.h"
#include "engines/eevee/eevee_lightcache.h"
@@ -1014,6 +1015,93 @@ void SCENE_OT_view_layer_remove(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name View Layer Add AOV Operator
+ * \{ */
+
+static int view_layer_add_aov_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+
+ BKE_view_layer_add_aov(view_layer);
+
+ RenderEngineType *engine_type = RE_engines_find(scene->r.engine);
+ if (engine_type->update_render_passes) {
+ RenderEngine *engine = RE_engine_create(engine_type);
+ if (engine) {
+ BKE_view_layer_verify_aov(engine, scene, view_layer);
+ }
+ RE_engine_free(engine);
+ engine = NULL;
+ }
+
+ DEG_id_tag_update(&scene->id, 0);
+ DEG_relations_tag_update(CTX_data_main(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_view_layer_add_aov(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add AOV";
+ ot->idname = "SCENE_OT_view_layer_add_aov";
+ ot->description = "Add a Shader AOV";
+
+ /* api callbacks */
+ ot->exec = view_layer_add_aov_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name View Layer Remove AOV Operator
+ * \{ */
+
+static int view_layer_remove_aov_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ BKE_view_layer_remove_aov(view_layer, view_layer->active_aov);
+
+ RenderEngineType *engine_type = RE_engines_find(scene->r.engine);
+ if (engine_type->update_render_passes) {
+ RenderEngine *engine = RE_engine_create(engine_type);
+ if (engine) {
+ BKE_view_layer_verify_aov(engine, scene, view_layer);
+ }
+ RE_engine_free(engine);
+ engine = NULL;
+ }
+
+ DEG_id_tag_update(&scene->id, 0);
+ DEG_relations_tag_update(CTX_data_main(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_view_layer_remove_aov(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Remove AOV";
+ ot->idname = "SCENE_OT_view_layer_remove_aov";
+ ot->description = "Remove Active AOV";
+
+ /* api callbacks */
+ ot->exec = view_layer_remove_aov_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Light Cache Bake Operator
* \{ */
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index af09100b8e6..244ebea5bbe 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -1004,6 +1004,11 @@ static eContextResult screen_ctx_selected_editable_keyframes(const bContext *C,
}
fcurve = (FCurve *)ale->data;
+ if (fcurve->bezt == NULL) {
+ /* Skip baked FCurves. */
+ continue;
+ }
+
for (i = 0, bezt = fcurve->bezt; i < fcurve->totvert; i++, bezt++) {
if ((bezt->f2 & SELECT) == 0) {
continue;
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 8c16300a047..98f4b4013cb 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -6748,7 +6748,7 @@ void PAINT_OT_add_texture_paint_slot(wmOperatorType *ot)
"Generated Type",
"Fill the image with a grid for UV map testing");
RNA_def_boolean(
- ot->srna, "float", 0, "32 bit Float", "Create image with 32 bit floating point bit depth");
+ ot->srna, "float", 0, "32-bit Float", "Create image with 32-bit floating-point bit depth");
}
static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op))
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index 11d897cf76f..17690757fa5 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -335,7 +335,7 @@ static void sculpt_gesture_operator_properties(wmOperatorType *ot)
false,
"Limit to Segment",
"Apply the gesture action only to the area that is contained within the "
- "segement without extending its effect to the entire line");
+ "segment without extending its effect to the entire line");
}
static void sculpt_gesture_context_init_common(bContext *C,
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
index eea79bad789..8eb2ebd0f19 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
@@ -120,13 +120,8 @@ static int weight_from_bones_exec(bContext *C, wmOperator *op)
Mesh *me = ob->data;
int type = RNA_enum_get(op->ptr, "type");
- ED_object_vgroup_calc_from_armature(op->reports,
- depsgraph,
- scene,
- ob,
- armob,
- type,
- (me->editflag & ME_EDIT_VERTEX_GROUPS_X_SYMMETRY));
+ ED_object_vgroup_calc_from_armature(
+ op->reports, depsgraph, scene, ob, armob, type, (me->symmetry & ME_SYMMETRY_X));
DEG_id_tag_update(&me->id, 0);
DEG_relations_tag_update(CTX_data_main(C));
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index b9427677745..fd7ec1da497 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -4232,6 +4232,8 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
(len_v3(grab_delta) / ss->cache->radius)) :
0.0f;
+ const bool do_elastic = brush->snake_hook_deform_type == BRUSH_SNAKE_HOOK_DEFORM_ELASTIC;
+
proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
SculptBrushTest test;
@@ -4239,18 +4241,28 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ KelvinletParams params;
+ BKE_kelvinlet_init_params(&params, ss->cache->radius, bstrength, 1.0f, 0.4f);
+
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (do_elastic || sculpt_brush_test_sq_fn(&test, vd.co)) {
+
+ float fade;
+ if (do_elastic) {
+ fade = 1.0f;
+ }
+ else {
+ fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+ }
mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
@@ -4289,6 +4301,17 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
add_v3_v3(proxy[vd.i], delta_rotate);
}
+ if (do_elastic) {
+ float disp[3];
+ BKE_kelvinlet_grab_triscale(disp, &params, vd.co, ss->cache->location, proxy[vd.i]);
+ mul_v3_fl(disp, bstrength * 20.0f);
+ if (vd.mask) {
+ mul_v3_fl(disp, 1.0f - *vd.mask);
+ }
+ mul_v3_fl(disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index));
+ copy_v3_v3(proxy[vd.i], disp);
+ }
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -5714,16 +5737,8 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
/* Build a list of all nodes that are potentially within the brush's area of influence */
- /* These brushes need to update all nodes as they are not constrained by the brush radius */
- /* Elastic deform needs all nodes to avoid artifacts as the effect of the brush is not
- * constrained by the radius. */
- /* Pose needs all nodes because it applies all symmetry iterations at the same time and the IK
- * chain can grow to any area of the model. */
- /* This can be optimized by filtering the nodes after calculating the chain. */
- if (ELEM(brush->sculpt_tool,
- SCULPT_TOOL_ELASTIC_DEFORM,
- SCULPT_TOOL_POSE,
- SCULPT_TOOL_BOUNDARY)) {
+ if (SCULPT_tool_needs_all_pbvh_nodes(brush)) {
+ /* These brushes need to update all nodes as they are not constrained by the brush radius */
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
}
else if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c
index 7c8a4c5a857..ad42750bb92 100644
--- a/source/blender/editors/sculpt_paint/sculpt_face_set.c
+++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c
@@ -1307,8 +1307,8 @@ static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEven
SculptCursorGeometryInfo sgi;
const float mouse[2] = {event->mval[0], event->mval[1]};
if (!SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false)) {
- /* The cursor is not over the mesh. Cancel to avoid editing the last updated Face Set ID. */
- return OPERATOR_CANCELLED;
+ /* The cursor is not over the mesh. Cancel to avoid editing the last updated Face Set ID. */
+ return OPERATOR_CANCELLED;
}
const int active_face_set = SCULPT_active_face_set_get(ss);
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
index 11af63c6e47..02d4be20e1b 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
@@ -448,7 +448,7 @@ static void mesh_filter_task_cb(void *__restrict userdata,
mul_v3_v3fl(disp, ss->filter_cache->detail_directions[vd.index], -fabsf(fade));
} break;
case MESH_FILTER_ERASE_DISPLACEMENT: {
- fade = clamp_f(fade, 0.0f, 1.0f);
+ fade = clamp_f(fade, -1.0f, 1.0f);
sub_v3_v3v3(disp, ss->filter_cache->limit_surface_co[vd.index], orig_co);
mul_v3_fl(disp, fade);
break;
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 99ee22328ea..3b48207f461 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -434,6 +434,38 @@ BLI_INLINE bool SCULPT_is_cloth_deform_brush(const Brush *brush)
brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM);
}
+BLI_INLINE bool SCULPT_tool_needs_all_pbvh_nodes(const Brush *brush)
+{
+ if (brush->sculpt_tool == SCULPT_TOOL_ELASTIC_DEFORM) {
+ /* Elastic deformations in any brush need all nodes to avoid artifacts as the effect
+ * of the Kelvinlet is not constrained by the radius. */
+ return true;
+ }
+
+ if (brush->sculpt_tool == SCULPT_TOOL_POSE) {
+ /* Pose needs all nodes because it applies all symmetry iterations at the same time
+ * and the IK chain can grow to any area of the model. */
+ /* TODO: This can be optimized by filtering the nodes after calculating the chain. */
+ return true;
+ }
+
+ if (brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) {
+ /* Boundary needs all nodes because it is not possible to know where the boundary
+ * deformation is going to be propagated before calculating it. */
+ /* TODO: after calculating the boudnary info in the first iteration, it should be
+ * possible to get the nodes that have vertices included in any boundary deformation
+ * and cache them. */
+ return true;
+ }
+
+ if (brush->sculpt_tool == SCULPT_TOOL_SNAKE_HOOK &&
+ brush->snake_hook_deform_type == BRUSH_SNAKE_HOOK_DEFORM_ELASTIC) {
+ /* Snake hook in elastic deform type has same requirements as the elastic deform tool. */
+ return true;
+ }
+ return false;
+}
+
/* Pose Brush. */
void SCULPT_do_pose_brush(struct Sculpt *sd,
struct Object *ob,
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
index f0047448a8d..39320f3f558 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
@@ -220,6 +220,9 @@ static void do_sample_wet_paint_task_cb(void *__restrict userdata,
SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
ss, &test, data->brush->falloff_shape);
+ test.radius *= data->brush->wet_paint_radius_factor;
+ test.radius_squared = test.radius * test.radius;
+
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c
index 4b318a05591..1bf9ba60073 100644
--- a/source/blender/editors/sculpt_paint/sculpt_pose.c
+++ b/source/blender/editors/sculpt_paint/sculpt_pose.c
@@ -1197,7 +1197,7 @@ void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
quat_to_mat4(ik_chain->segments[i].trans_mat[symm_it], symm_rot);
}
- /* Apply segement scale to the transform. */
+ /* Apply segment scale to the transform. */
for (int scale_i = 0; scale_i < 3; scale_i++) {
mul_v3_fl(ik_chain->segments[i].trans_mat[symm_it][scale_i],
ik_chain->segments[i].scale[scale_i]);
diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.c b/source/blender/editors/sculpt_paint/sculpt_transform.c
index 88585745467..f74d59e1987 100644
--- a/source/blender/editors/sculpt_paint/sculpt_transform.c
+++ b/source/blender/editors/sculpt_paint/sculpt_transform.c
@@ -212,8 +212,8 @@ static void sculpt_transform_all_vertices(Sculpt *sd, Object *ob)
sculpt_transform_matrices_init(
ss, symm, ss->filter_cache->transform_displacement_mode, data.transform_mats);
- /* Regular transform applies all symmetry passes at once as it is split by symmetry areas (each
- * vertex can only be transformed once by the transform matix of its area). */
+ /* Regular transform applies all symmetry passes at once as it is split by symmetry areas
+ * (each vertex can only be transformed once by the transform matrix of its area). */
TaskParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
BLI_task_parallel_range(
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index c6961cc9d4b..8dac90c2346 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -518,27 +518,27 @@ static bool sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr),
static void sound_mixdown_draw(bContext *C, wmOperator *op)
{
static const EnumPropertyItem pcm_format_items[] = {
- {AUD_FORMAT_U8, "U8", 0, "U8", "8 bit unsigned"},
- {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
+ {AUD_FORMAT_U8, "U8", 0, "U8", "8-bit unsigned"},
+ {AUD_FORMAT_S16, "S16", 0, "S16", "16-bit signed"},
# ifdef WITH_SNDFILE
- {AUD_FORMAT_S24, "S24", 0, "S24", "24 bit signed"},
+ {AUD_FORMAT_S24, "S24", 0, "S24", "24-bit signed"},
# endif
- {AUD_FORMAT_S32, "S32", 0, "S32", "32 bit signed"},
- {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32 bit floating point"},
- {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64 bit floating point"},
+ {AUD_FORMAT_S32, "S32", 0, "S32", "32-bit signed"},
+ {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32-bit floating-point"},
+ {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64-bit floating-point"},
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem mp3_format_items[] = {
- {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
- {AUD_FORMAT_S32, "S32", 0, "S32", "32 bit signed"},
+ {AUD_FORMAT_S16, "S16", 0, "S16", "16-bit signed"},
+ {AUD_FORMAT_S32, "S32", 0, "S32", "32-bit signed"},
{0, NULL, 0, NULL, NULL},
};
# ifdef WITH_SNDFILE
static const EnumPropertyItem flac_format_items[] = {
- {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
- {AUD_FORMAT_S24, "S24", 0, "S24", "24 bit signed"},
+ {AUD_FORMAT_S16, "S16", 0, "S16", "16-bit signed"},
+ {AUD_FORMAT_S24, "S24", 0, "S24", "24-bit signed"},
{0, NULL, 0, NULL, NULL},
};
# endif
@@ -672,12 +672,12 @@ static void SOUND_OT_mixdown(wmOperatorType *ot)
{
#ifdef WITH_AUDASPACE
static const EnumPropertyItem format_items[] = {
- {AUD_FORMAT_U8, "U8", 0, "U8", "8 bit unsigned"},
- {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"},
- {AUD_FORMAT_S24, "S24", 0, "S24", "24 bit signed"},
- {AUD_FORMAT_S32, "S32", 0, "S32", "32 bit signed"},
- {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32 bit floating point"},
- {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64 bit floating point"},
+ {AUD_FORMAT_U8, "U8", 0, "U8", "8-bit unsigned"},
+ {AUD_FORMAT_S16, "S16", 0, "S16", "16-bit signed"},
+ {AUD_FORMAT_S24, "S24", 0, "S24", "24-bit signed"},
+ {AUD_FORMAT_S32, "S32", 0, "S32", "32-bit signed"},
+ {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32-bit floating-point"},
+ {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64-bit floating-point"},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/editors/space_action/action_data.c b/source/blender/editors/space_action/action_data.c
index e20be9c8328..3a584a7f0cb 100644
--- a/source/blender/editors/space_action/action_data.c
+++ b/source/blender/editors/space_action/action_data.c
@@ -240,7 +240,7 @@ static int action_new_exec(bContext *C, wmOperator *UNUSED(op))
/* Perform stashing operation - But only if there is an action */
if (adt && oldact) {
/* stash the action */
- if (BKE_nla_action_stash(adt)) {
+ if (BKE_nla_action_stash(adt, ID_IS_OVERRIDE_LIBRARY(ptr.owner_id))) {
/* The stash operation will remove the user already
* (and unlink the action from the AnimData action slot).
* Hence, we must unset the ref to the action in the
@@ -339,7 +339,8 @@ static int action_pushdown_exec(bContext *C, wmOperator *op)
}
/* action can be safely added */
- BKE_nla_action_pushdown(adt);
+ const Object *ob = CTX_data_active_object(C);
+ BKE_nla_action_pushdown(adt, ID_IS_OVERRIDE_LIBRARY(ob));
/* Stop displaying this action in this editor
* NOTE: The editor itself doesn't set a user...
@@ -384,7 +385,8 @@ static int action_stash_exec(bContext *C, wmOperator *op)
}
/* stash the action */
- if (BKE_nla_action_stash(adt)) {
+ Object *ob = CTX_data_active_object(C);
+ if (BKE_nla_action_stash(adt, ID_IS_OVERRIDE_LIBRARY(ob))) {
/* The stash operation will remove the user already,
* so the flushing step later shouldn't double up
* the user-count fixes. Hence, we must unset this ref
@@ -486,7 +488,8 @@ static int action_stash_create_exec(bContext *C, wmOperator *op)
}
/* stash the action */
- if (BKE_nla_action_stash(adt)) {
+ Object *ob = CTX_data_active_object(C);
+ if (BKE_nla_action_stash(adt, ID_IS_OVERRIDE_LIBRARY(ob))) {
bAction *new_action = NULL;
/* Create new action not based on the old one
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 4b277435f63..e3bdda7c480 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -400,11 +400,12 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C);
ARegion *region = CTX_wm_region(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- BLI_join_dirfile(orgname, sizeof(orgname), sfile->params->dir, oldname);
- BLI_strncpy(filename, sfile->params->renamefile, sizeof(filename));
+ BLI_join_dirfile(orgname, sizeof(orgname), params->dir, oldname);
+ BLI_strncpy(filename, params->renamefile, sizeof(filename));
BLI_filename_make_safe(filename);
- BLI_join_dirfile(newname, sizeof(newname), sfile->params->dir, filename);
+ BLI_join_dirfile(newname, sizeof(newname), params->dir, filename);
if (!STREQ(orgname, newname)) {
if (!BLI_exists(newname)) {
@@ -415,8 +416,8 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
}
else {
/* If rename is successful, scroll to newly renamed entry. */
- BLI_strncpy(sfile->params->renamefile, filename, sizeof(sfile->params->renamefile));
- sfile->params->rename_flag = FILE_PARAMS_RENAME_POSTSCROLL_PENDING;
+ BLI_strncpy(params->renamefile, filename, sizeof(params->renamefile));
+ params->rename_flag = FILE_PARAMS_RENAME_POSTSCROLL_PENDING;
if (sfile->smoothscroll_timer != NULL) {
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer);
@@ -688,7 +689,7 @@ static void draw_details_columns(const FileSelectParams *params,
void file_draw_list(const bContext *C, ARegion *region)
{
SpaceFile *sfile = CTX_wm_space_file(C);
- FileSelectParams *params = ED_fileselect_get_params(sfile);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
FileLayout *layout = ED_fileselect_get_layout(sfile, region);
View2D *v2d = &region->v2d;
struct FileList *files = sfile->files;
@@ -847,26 +848,25 @@ void file_draw_list(const bContext *C, ARegion *region)
}
if (file_selflag & FILE_SEL_EDITING) {
- uiBut *but;
const short width = (params->display == FILE_IMGDISPLAY) ?
textwidth :
layout->attribute_columns[COLUMN_NAME].width -
ATTRIBUTE_COLUMN_PADDING;
- but = uiDefBut(block,
- UI_BTYPE_TEXT,
- 1,
- "",
- sx + icon_ofs,
- sy - layout->tile_h - 0.15f * UI_UNIT_X,
- width - icon_ofs,
- textheight,
- sfile->params->renamefile,
- 1.0f,
- (float)sizeof(sfile->params->renamefile),
- 0,
- 0,
- "");
+ uiBut *but = uiDefBut(block,
+ UI_BTYPE_TEXT,
+ 1,
+ "",
+ sx + icon_ofs,
+ sy - layout->tile_h - 0.15f * UI_UNIT_X,
+ width - icon_ofs,
+ textheight,
+ params->renamefile,
+ 1.0f,
+ (float)sizeof(params->renamefile),
+ 0,
+ 0,
+ "");
UI_but_func_rename_set(but, renamebutton_cb, file);
UI_but_flag_enable(but, UI_BUT_NO_UTF8); /* allow non utf8 names */
UI_but_flag_disable(but, UI_BUT_UNDO);
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 93367ad3d3c..b98348307f3 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -188,7 +188,7 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen)
Main *bmain = CTX_data_main(C);
FileSelect retval = FILE_SELECT_NOTHING;
SpaceFile *sfile = CTX_wm_space_file(C);
- FileSelectParams *params = ED_fileselect_get_params(sfile);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
int numfiles = filelist_files_ensure(sfile->files);
const FileDirEntry *file;
@@ -302,10 +302,10 @@ static FileSelect file_select(
bContext *C, const rcti *rect, FileSelType select, bool fill, bool do_diropen)
{
SpaceFile *sfile = CTX_wm_space_file(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
FileSelect retval = FILE_SELECT_NOTHING;
FileSelection sel = file_selection_get(C, rect, fill); /* get the selection */
- const FileCheckType check_type = (sfile->params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS :
- CHECK_ALL;
+ const FileCheckType check_type = (params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_ALL;
/* flag the files as selected in the filelist */
filelist_entries_select_index_range_set(
@@ -325,7 +325,7 @@ static FileSelect file_select(
}
if (select != FILE_SEL_ADD && !file_is_any_selected(sfile->files)) {
- sfile->params->active_file = -1;
+ params->active_file = -1;
}
else if (sel.last >= 0) {
ARegion *region = CTX_wm_region(C);
@@ -390,7 +390,7 @@ static int file_box_select_modal(bContext *C, wmOperator *op, const wmEvent *eve
{
ARegion *region = CTX_wm_region(C);
SpaceFile *sfile = CTX_wm_space_file(C);
- FileSelectParams *params = ED_fileselect_get_params(sfile);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
FileSelection sel;
rcti rect;
@@ -521,8 +521,9 @@ static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
}
- if (sfile && sfile->params) {
- int idx = sfile->params->highlight_file;
+ const FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+ if (sfile && params) {
+ int idx = params->highlight_file;
int numfiles = filelist_files_ensure(sfile->files);
if ((idx >= 0) && (idx < numfiles)) {
@@ -613,7 +614,7 @@ static bool file_walk_select_selection_set(wmWindow *win,
const bool extend,
const bool fill)
{
- FileSelectParams *params = sfile->params;
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
struct FileList *files = sfile->files;
const int last_sel = params->active_file; /* store old value */
int active = active_old; /* could use active_old instead, just for readability */
@@ -804,7 +805,7 @@ static bool file_walk_select_do(bContext *C,
static int file_walk_select_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C);
- FileSelectParams *params = sfile->params;
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
const int direction = RNA_enum_get(op->ptr, "direction");
const bool extend = RNA_boolean_get(op->ptr, "extend");
const bool fill = RNA_boolean_get(op->ptr, "fill");
@@ -853,6 +854,7 @@ static int file_select_all_exec(bContext *C, wmOperator *op)
{
ScrArea *area = CTX_wm_area(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
FileSelection sel;
const int numfiles = filelist_files_ensure(sfile->files);
int action = RNA_enum_get(op->ptr, "action");
@@ -870,7 +872,7 @@ static int file_select_all_exec(bContext *C, wmOperator *op)
switch (action) {
case SEL_SELECT:
case SEL_INVERT: {
- check_type = (sfile->params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_FILES;
+ check_type = (params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_FILES;
filesel_type = (action == SEL_INVERT) ? FILE_SEL_TOGGLE : FILE_SEL_ADD;
break;
}
@@ -888,11 +890,11 @@ static int file_select_all_exec(bContext *C, wmOperator *op)
filelist_entries_select_index_range_set(
sfile->files, &sel, filesel_type, FILE_SEL_SELECTED, check_type);
- sfile->params->active_file = -1;
+ params->active_file = -1;
if (action != SEL_DESELECT) {
for (int i = 0; i < numfiles; i++) {
if (filelist_entry_select_index_get(sfile->files, i, check_type)) {
- sfile->params->active_file = i;
+ params->active_file = i;
break;
}
}
@@ -935,8 +937,8 @@ static int bookmark_select_exec(bContext *C, wmOperator *op)
PropertyRNA *prop;
if ((prop = RNA_struct_find_property(op->ptr, "dir"))) {
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
char entry[256];
- FileSelectParams *params = sfile->params;
RNA_property_string_get(op->ptr, prop, entry);
BLI_strncpy(params->dir, entry, sizeof(params->dir));
@@ -978,7 +980,7 @@ static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op))
ScrArea *area = CTX_wm_area(C);
SpaceFile *sfile = CTX_wm_space_file(C);
struct FSMenu *fsmenu = ED_fsmenu_get();
- struct FileSelectParams *params = ED_fileselect_get_params(sfile);
+ struct FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if (params->dir[0] != '\0') {
char name[FILE_MAX];
@@ -1274,7 +1276,7 @@ int file_highlight_set(SpaceFile *sfile, ARegion *region, int mx, int my)
}
numfiles = filelist_files_ensure(sfile->files);
- params = ED_fileselect_get_params(sfile);
+ params = ED_fileselect_get_active_params(sfile);
origfile = params->highlight_file;
@@ -1345,20 +1347,21 @@ static int file_column_sort_ui_context_invoke(bContext *C,
if (file_attribute_column_header_is_inside(
&region->v2d, sfile->layout, event->mval[0], event->mval[1])) {
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
const FileAttributeColumnType column_type = file_attribute_column_type_find_isect(
- &region->v2d, sfile->params, sfile->layout, event->mval[0]);
+ &region->v2d, params, sfile->layout, event->mval[0]);
if (column_type != COLUMN_NONE) {
const FileAttributeColumn *column = &sfile->layout->attribute_columns[column_type];
BLI_assert(column->sort_type != FILE_SORT_DEFAULT);
- if (sfile->params->sort == column->sort_type) {
+ if (params->sort == column->sort_type) {
/* Already sorting by selected column -> toggle sort invert (three state logic). */
- sfile->params->flag ^= FILE_SORT_INVERT;
+ params->flag ^= FILE_SORT_INVERT;
}
else {
- sfile->params->sort = column->sort_type;
- sfile->params->flag &= ~FILE_SORT_INVERT;
+ params->sort = column->sort_type;
+ params->flag &= ~FILE_SORT_INVERT;
}
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
@@ -1433,10 +1436,11 @@ void FILE_OT_cancel(struct wmOperatorType *ot)
void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, char *filepath)
{
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
PropertyRNA *prop;
/* XXX, not real length */
- BLI_join_dirfile(filepath, FILE_MAX, sfile->params->dir, sfile->params->file);
+ BLI_join_dirfile(filepath, FILE_MAX, params->dir, params->file);
if ((prop = RNA_struct_find_property(op->ptr, "relative_path"))) {
if (RNA_property_boolean_get(op->ptr, prop)) {
@@ -1445,10 +1449,10 @@ void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, ch
}
if ((prop = RNA_struct_find_property(op->ptr, "filename"))) {
- RNA_property_string_set(op->ptr, prop, sfile->params->file);
+ RNA_property_string_set(op->ptr, prop, params->file);
}
if ((prop = RNA_struct_find_property(op->ptr, "directory"))) {
- RNA_property_string_set(op->ptr, prop, sfile->params->dir);
+ RNA_property_string_set(op->ptr, prop, params->dir);
}
if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) {
RNA_property_string_set(op->ptr, prop, filepath);
@@ -1479,7 +1483,7 @@ void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, ch
* files selected */
if (0 == num_files) {
RNA_property_collection_add(op->ptr, prop, &itemptr);
- RNA_string_set(&itemptr, "name", sfile->params->file);
+ RNA_string_set(&itemptr, "name", params->file);
}
}
@@ -1500,7 +1504,7 @@ void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, ch
* directory selected */
if (0 == num_dirs) {
RNA_property_collection_add(op->ptr, prop, &itemptr);
- RNA_string_set(&itemptr, "name", sfile->params->dir);
+ RNA_string_set(&itemptr, "name", params->dir);
}
}
}
@@ -1514,30 +1518,28 @@ void file_sfile_to_operator(Main *bmain, wmOperator *op, SpaceFile *sfile)
void file_operator_to_sfile(Main *bmain, SpaceFile *sfile, wmOperator *op)
{
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
PropertyRNA *prop;
/* If neither of the above are set, split the filepath back */
if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) {
char filepath[FILE_MAX];
RNA_property_string_get(op->ptr, prop, filepath);
- BLI_split_dirfile(filepath,
- sfile->params->dir,
- sfile->params->file,
- sizeof(sfile->params->dir),
- sizeof(sfile->params->file));
+ BLI_split_dirfile(
+ filepath, params->dir, params->file, sizeof(params->dir), sizeof(params->file));
}
else {
if ((prop = RNA_struct_find_property(op->ptr, "filename"))) {
- RNA_property_string_get(op->ptr, prop, sfile->params->file);
+ RNA_property_string_get(op->ptr, prop, params->file);
}
if ((prop = RNA_struct_find_property(op->ptr, "directory"))) {
- RNA_property_string_get(op->ptr, prop, sfile->params->dir);
+ RNA_property_string_get(op->ptr, prop, params->dir);
}
}
/* we could check for relative_path property which is used when converting
* in the other direction but doesn't hurt to do this every time */
- BLI_path_abs(sfile->params->dir, BKE_main_blendfile_path(bmain));
+ BLI_path_abs(params->dir, BKE_main_blendfile_path(bmain));
/* XXX, files and dirs updates missing, not really so important though */
}
@@ -1547,21 +1549,19 @@ void file_operator_to_sfile(Main *bmain, SpaceFile *sfile, wmOperator *op)
*/
void file_sfile_filepath_set(SpaceFile *sfile, const char *filepath)
{
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
BLI_assert(BLI_exists(filepath));
if (BLI_is_dir(filepath)) {
- BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir));
+ BLI_strncpy(params->dir, filepath, sizeof(params->dir));
}
else {
- if ((sfile->params->flag & FILE_DIRSEL_ONLY) == 0) {
- BLI_split_dirfile(filepath,
- sfile->params->dir,
- sfile->params->file,
- sizeof(sfile->params->dir),
- sizeof(sfile->params->file));
+ if ((params->flag & FILE_DIRSEL_ONLY) == 0) {
+ BLI_split_dirfile(
+ filepath, params->dir, params->file, sizeof(params->dir), sizeof(params->file));
}
else {
- BLI_split_dir_part(filepath, sfile->params->dir, sizeof(sfile->params->dir));
+ BLI_split_dir_part(filepath, params->dir, sizeof(params->dir));
}
}
}
@@ -1605,9 +1605,10 @@ void file_draw_check_cb(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
bool file_draw_check_exists(SpaceFile *sfile)
{
if (sfile->op) { /* fails on reload */
- if (sfile->params && (sfile->params->flag & FILE_CHECK_EXISTING)) {
+ const FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+ if (params && (params->flag & FILE_CHECK_EXISTING)) {
char filepath[FILE_MAX];
- BLI_join_dirfile(filepath, sizeof(filepath), sfile->params->dir, sfile->params->file);
+ BLI_join_dirfile(filepath, sizeof(filepath), params->dir, params->file);
if (BLI_is_file(filepath)) {
return true;
}
@@ -1628,21 +1629,22 @@ static int file_exec(bContext *C, wmOperator *exec_op)
Main *bmain = CTX_data_main(C);
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
- struct FileDirEntry *file = filelist_file(sfile->files, sfile->params->active_file);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+ struct FileDirEntry *file = filelist_file(sfile->files, params->active_file);
char filepath[FILE_MAX];
if (file && file->redirection_path) {
/* redirection_path is an absolute path that takes precedence
- * over using sfile->params->dir + sfile->params->file. */
+ * over using params->dir + params->file. */
BLI_split_dirfile(file->redirection_path,
- sfile->params->dir,
- sfile->params->file,
- sizeof(sfile->params->dir),
- sizeof(sfile->params->file));
+ params->dir,
+ params->file,
+ sizeof(params->dir),
+ sizeof(params->file));
/* Update relpath with redirected filename as well so that the alternative
- * combination of sfile->params->dir + relpath remains valid as well. */
+ * combination of params->dir + relpath remains valid as well. */
MEM_freeN(file->relpath);
- file->relpath = BLI_strdup(sfile->params->file);
+ file->relpath = BLI_strdup(params->file);
}
/* directory change */
@@ -1652,12 +1654,12 @@ static int file_exec(bContext *C, wmOperator *exec_op)
}
if (FILENAME_IS_PARENT(file->relpath)) {
- BLI_path_parent_dir(sfile->params->dir);
+ BLI_path_parent_dir(params->dir);
}
else {
- BLI_path_normalize(BKE_main_blendfile_path(bmain), sfile->params->dir);
- BLI_path_append(sfile->params->dir, sizeof(sfile->params->dir) - 1, file->relpath);
- BLI_path_slash_ensure(sfile->params->dir);
+ BLI_path_normalize(BKE_main_blendfile_path(bmain), params->dir);
+ BLI_path_append(params->dir, sizeof(params->dir) - 1, file->relpath);
+ BLI_path_slash_ensure(params->dir);
}
ED_file_change_dir(C);
}
@@ -1685,10 +1687,10 @@ static int file_exec(bContext *C, wmOperator *exec_op)
file_sfile_to_operator_ex(bmain, op, sfile, filepath);
- if (BLI_exists(sfile->params->dir)) {
+ if (BLI_exists(params->dir)) {
fsmenu_insert_entry(ED_fsmenu_get(),
FS_CATEGORY_RECENT,
- sfile->params->dir,
+ params->dir,
NULL,
ICON_FILE_FOLDER,
FS_INSERT_SAVE | FS_INSERT_FIRST);
@@ -1792,15 +1794,16 @@ static int file_parent_exec(bContext *C, wmOperator *UNUSED(unused))
{
Main *bmain = CTX_data_main(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- if (sfile->params) {
- if (BLI_path_parent_dir(sfile->params->dir)) {
- BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), sfile->params->dir);
+ if (params) {
+ if (BLI_path_parent_dir(params->dir)) {
+ BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir);
ED_file_change_dir(C);
- if (sfile->params->recursion_level > 1) {
+ if (params->recursion_level > 1) {
/* Disable 'dirtree' recursion when going up in tree. */
- sfile->params->recursion_level = 0;
- filelist_setrecursion(sfile->files, sfile->params->recursion_level);
+ params->recursion_level = 0;
+ filelist_setrecursion(sfile->files, params->recursion_level);
}
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
@@ -1830,15 +1833,16 @@ void FILE_OT_parent(struct wmOperatorType *ot)
static int file_previous_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceFile *sfile = CTX_wm_space_file(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- if (sfile->params) {
+ if (params) {
if (!sfile->folders_next) {
sfile->folders_next = folderlist_new();
}
- folderlist_pushdir(sfile->folders_next, sfile->params->dir);
- folderlist_popdir(sfile->folders_prev, sfile->params->dir);
- folderlist_pushdir(sfile->folders_next, sfile->params->dir);
+ folderlist_pushdir(sfile->folders_next, params->dir);
+ folderlist_popdir(sfile->folders_prev, params->dir);
+ folderlist_pushdir(sfile->folders_next, params->dir);
ED_file_change_dir(C);
}
@@ -1868,16 +1872,17 @@ void FILE_OT_previous(struct wmOperatorType *ot)
static int file_next_exec(bContext *C, wmOperator *UNUSED(unused))
{
SpaceFile *sfile = CTX_wm_space_file(C);
- if (sfile->params) {
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+ if (params) {
if (!sfile->folders_next) {
sfile->folders_next = folderlist_new();
}
- folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
- folderlist_popdir(sfile->folders_next, sfile->params->dir);
+ folderlist_pushdir(sfile->folders_prev, params->dir);
+ folderlist_popdir(sfile->folders_next, params->dir);
/* update folders_prev so we can check for it in #folderlist_clear_next() */
- folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
+ folderlist_pushdir(sfile->folders_prev, params->dir);
ED_file_change_dir(C);
}
@@ -1923,7 +1928,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
/* Due to async nature of file listing, we may execute this code before `file_refresh()`
* editing entry is available in our listing,
* so we also have to handle switching to rename mode here. */
- FileSelectParams *params = ED_fileselect_get_params(sfile);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
if ((params->rename_flag &
(FILE_PARAMS_RENAME_PENDING | FILE_PARAMS_RENAME_POSTSCROLL_PENDING)) != 0) {
file_params_renamefile_activate(sfile, params);
@@ -2175,9 +2180,10 @@ static int file_directory_new_exec(bContext *C, wmOperator *op)
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
const bool do_diropen = RNA_boolean_get(op->ptr, "open");
- if (!sfile->params) {
+ if (!params) {
BKE_report(op->reports, RPT_WARNING, "No parent directory given");
return OPERATOR_CANCELLED;
}
@@ -2193,7 +2199,7 @@ static int file_directory_new_exec(bContext *C, wmOperator *op)
if (generate_name) {
/* create a new, non-existing folder name */
- if (!new_folder_path(sfile->params->dir, path, name)) {
+ if (!new_folder_path(params->dir, path, name)) {
BKE_report(op->reports, RPT_ERROR, "Could not create new folder name");
return OPERATOR_CANCELLED;
}
@@ -2226,8 +2232,8 @@ static int file_directory_new_exec(bContext *C, wmOperator *op)
/* If we don't enter the directory directly, remember file to jump into editing. */
if (do_diropen == false) {
- BLI_strncpy(sfile->params->renamefile, name, FILE_MAXFILE);
- sfile->params->rename_flag = FILE_PARAMS_RENAME_PENDING;
+ BLI_strncpy(params->renamefile, name, FILE_MAXFILE);
+ params->rename_flag = FILE_PARAMS_RENAME_PENDING;
}
/* set timer to smoothly view newly generated file */
@@ -2242,7 +2248,7 @@ static int file_directory_new_exec(bContext *C, wmOperator *op)
ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
if (do_diropen) {
- BLI_strncpy(sfile->params->dir, path, sizeof(sfile->params->dir));
+ BLI_strncpy(params->dir, path, sizeof(params->dir));
ED_file_change_dir(C);
}
@@ -2284,38 +2290,37 @@ static void file_expand_directory(bContext *C)
{
Main *bmain = CTX_data_main(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- if (sfile->params) {
- if (BLI_path_is_rel(sfile->params->dir)) {
+ if (params) {
+ if (BLI_path_is_rel(params->dir)) {
/* Use of 'default' folder here is just to avoid an error message on '//' prefix. */
- BLI_path_abs(sfile->params->dir,
+ BLI_path_abs(params->dir,
G.relbase_valid ? BKE_main_blendfile_path(bmain) : BKE_appdir_folder_default());
}
- else if (sfile->params->dir[0] == '~') {
- char tmpstr[sizeof(sfile->params->dir) - 1];
- BLI_strncpy(tmpstr, sfile->params->dir + 1, sizeof(tmpstr));
- BLI_join_dirfile(
- sfile->params->dir, sizeof(sfile->params->dir), BKE_appdir_folder_default(), tmpstr);
+ else if (params->dir[0] == '~') {
+ char tmpstr[sizeof(params->dir) - 1];
+ BLI_strncpy(tmpstr, params->dir + 1, sizeof(tmpstr));
+ BLI_join_dirfile(params->dir, sizeof(params->dir), BKE_appdir_folder_default(), tmpstr);
}
- else if (sfile->params->dir[0] == '\0')
+ else if (params->dir[0] == '\0')
#ifndef WIN32
{
- sfile->params->dir[0] = '/';
- sfile->params->dir[1] = '\0';
+ params->dir[0] = '/';
+ params->dir[1] = '\0';
}
#else
{
- BLI_windows_get_default_root_dir(sfile->params->dir);
+ BLI_windows_get_default_root_dir(params->dir);
}
/* change "C:" --> "C:\", T28102. */
- else if ((isalpha(sfile->params->dir[0]) && (sfile->params->dir[1] == ':')) &&
- (sfile->params->dir[2] == '\0')) {
- sfile->params->dir[2] = '\\';
- sfile->params->dir[3] = '\0';
+ else if ((isalpha(params->dir[0]) && (params->dir[1] == ':')) && (params->dir[2] == '\0')) {
+ params->dir[2] = '\\';
+ params->dir[3] = '\0';
}
- else if (BLI_path_is_unc(sfile->params->dir)) {
- BLI_path_normalize_unc(sfile->params->dir, FILE_MAX_LIBEXTRA);
+ else if (BLI_path_is_unc(params->dir)) {
+ BLI_path_normalize_unc(params->dir, FILE_MAX_LIBEXTRA);
}
#endif
}
@@ -2343,46 +2348,44 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN
{
Main *bmain = CTX_data_main(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- if (sfile->params) {
- char old_dir[sizeof(sfile->params->dir)];
+ if (params) {
+ char old_dir[sizeof(params->dir)];
- BLI_strncpy(old_dir, sfile->params->dir, sizeof(old_dir));
+ BLI_strncpy(old_dir, params->dir, sizeof(old_dir));
file_expand_directory(C);
/* special case, user may have pasted a filepath into the directory */
- if (!filelist_is_dir(sfile->files, sfile->params->dir)) {
+ if (!filelist_is_dir(sfile->files, params->dir)) {
char tdir[FILE_MAX_LIBEXTRA];
char *group, *name;
- if (BLI_is_file(sfile->params->dir)) {
- char path[sizeof(sfile->params->dir)];
- BLI_strncpy(path, sfile->params->dir, sizeof(path));
- BLI_split_dirfile(path,
- sfile->params->dir,
- sfile->params->file,
- sizeof(sfile->params->dir),
- sizeof(sfile->params->file));
+ if (BLI_is_file(params->dir)) {
+ char path[sizeof(params->dir)];
+ BLI_strncpy(path, params->dir, sizeof(path));
+ BLI_split_dirfile(
+ path, params->dir, params->file, sizeof(params->dir), sizeof(params->file));
}
- else if (BLO_library_path_explode(sfile->params->dir, tdir, &group, &name)) {
+ else if (BLO_library_path_explode(params->dir, tdir, &group, &name)) {
if (group) {
BLI_path_append(tdir, sizeof(tdir), group);
}
- BLI_strncpy(sfile->params->dir, tdir, sizeof(sfile->params->dir));
+ BLI_strncpy(params->dir, tdir, sizeof(params->dir));
if (name) {
- BLI_strncpy(sfile->params->file, name, sizeof(sfile->params->file));
+ BLI_strncpy(params->file, name, sizeof(params->file));
}
else {
- sfile->params->file[0] = '\0';
+ params->file[0] = '\0';
}
}
}
- BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), sfile->params->dir);
+ BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir);
- if (filelist_is_dir(sfile->files, sfile->params->dir)) {
- if (!STREQ(sfile->params->dir, old_dir)) { /* Avoids flickering when nothing's changed. */
+ if (filelist_is_dir(sfile->files, params->dir)) {
+ if (!STREQ(params->dir, old_dir)) { /* Avoids flickering when nothing's changed. */
/* if directory exists, enter it immediately */
ED_file_change_dir(C);
}
@@ -2392,10 +2395,10 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN
/* UI_textbutton_activate_but(C, but); */
}
#if defined(WIN32)
- else if (!can_create_dir(sfile->params->dir)) {
+ else if (!can_create_dir(params->dir)) {
const char *lastdir = folderlist_peeklastdir(sfile->folders_prev);
if (lastdir) {
- BLI_strncpy(sfile->params->dir, lastdir, sizeof(sfile->params->dir));
+ BLI_strncpy(params->dir, lastdir, sizeof(params->dir));
}
}
#endif
@@ -2405,21 +2408,21 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN
/* If we are 'inside' a blend library, we cannot do anything... */
if (lastdir && BLO_library_path_explode(lastdir, tdir, NULL, NULL)) {
- BLI_strncpy(sfile->params->dir, lastdir, sizeof(sfile->params->dir));
+ BLI_strncpy(params->dir, lastdir, sizeof(params->dir));
}
else {
/* if not, ask to create it and enter if confirmed */
wmOperatorType *ot = WM_operatortype_find("FILE_OT_directory_new", false);
PointerRNA ptr;
WM_operator_properties_create_ptr(&ptr, ot);
- RNA_string_set(&ptr, "directory", sfile->params->dir);
+ RNA_string_set(&ptr, "directory", params->dir);
RNA_boolean_set(&ptr, "open", true);
/* Enable confirmation prompt, else it's too easy
* to accidentally create new directories. */
RNA_boolean_set(&ptr, "confirm", true);
if (lastdir) {
- BLI_strncpy(sfile->params->dir, lastdir, sizeof(sfile->params->dir));
+ BLI_strncpy(params->dir, lastdir, sizeof(params->dir));
}
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr);
@@ -2435,39 +2438,39 @@ void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg
{
Main *bmain = CTX_data_main(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
uiBut *but = arg_but;
char matched_file[FILE_MAX];
- char filepath[sizeof(sfile->params->dir)];
- if (sfile->params) {
+ if (params) {
+ char filepath[sizeof(params->dir)];
int matches;
matched_file[0] = '\0';
filepath[0] = '\0';
file_expand_directory(C);
- matches = file_select_match(sfile, sfile->params->file, matched_file);
+ matches = file_select_match(sfile, params->file, matched_file);
/* *After* file_select_match! */
- BLI_filename_make_safe(sfile->params->file);
+ BLI_filename_make_safe(params->file);
if (matches) {
/* replace the pattern (or filename that the user typed in,
* with the first selected file of the match */
- BLI_strncpy(sfile->params->file, matched_file, sizeof(sfile->params->file));
+ BLI_strncpy(params->file, matched_file, sizeof(params->file));
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
}
if (matches == 1) {
- BLI_join_dirfile(
- filepath, sizeof(sfile->params->dir), sfile->params->dir, sfile->params->file);
+ BLI_join_dirfile(filepath, sizeof(params->dir), params->dir, params->file);
/* if directory, open it and empty filename field */
if (filelist_is_dir(sfile->files, filepath)) {
BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), filepath);
- BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir));
- sfile->params->file[0] = '\0';
+ BLI_strncpy(params->dir, filepath, sizeof(params->dir));
+ params->file[0] = '\0';
ED_file_change_dir(C);
UI_textbutton_activate_but(C, but);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
@@ -2489,9 +2492,10 @@ static int file_hidedot_exec(bContext *C, wmOperator *UNUSED(unused))
{
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- if (sfile->params) {
- sfile->params->flag ^= FILE_HIDE_DOT;
+ if (params) {
+ params->flag ^= FILE_HIDE_DOT;
ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
@@ -2525,7 +2529,8 @@ static bool file_filenum_poll(bContext *C)
return false;
}
- return sfile->params && (sfile->params->flag & FILE_CHECK_EXISTING);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+ return params && (params->flag & FILE_CHECK_EXISTING);
}
/**
@@ -2563,11 +2568,12 @@ static void filenum_newname(char *name, size_t name_size, int add)
static int file_filenum_exec(bContext *C, wmOperator *op)
{
SpaceFile *sfile = CTX_wm_space_file(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
ScrArea *area = CTX_wm_area(C);
int inc = RNA_int_get(op->ptr, "increment");
- if (sfile->params && (inc != 0)) {
- filenum_newname(sfile->params->file, sizeof(sfile->params->file), inc);
+ if (params && (inc != 0)) {
+ filenum_newname(params->file, sizeof(params->file), inc);
ED_area_tag_redraw(area);
file_draw_check(C);
// WM_event_add_notifier(C, NC_WINDOW, NULL);
@@ -2606,12 +2612,14 @@ static void file_rename_state_activate(SpaceFile *sfile, int file_idx, bool requ
if ((require_selected == false) ||
(filelist_entry_select_get(sfile->files, file, CHECK_ALL) & FILE_SEL_SELECTED)) {
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+
filelist_entry_select_index_set(
sfile->files, file_idx, FILE_SEL_ADD, FILE_SEL_EDITING, CHECK_ALL);
- BLI_strncpy(sfile->params->renamefile, file->relpath, FILE_MAXFILE);
+ BLI_strncpy(params->renamefile, file->relpath, FILE_MAXFILE);
/* We can skip the pending state,
* as we can directly set FILE_SEL_EDITING on the expected entry here. */
- sfile->params->rename_flag = FILE_PARAMS_RENAME_ACTIVE;
+ params->rename_flag = FILE_PARAMS_RENAME_ACTIVE;
}
}
}
@@ -2620,9 +2628,10 @@ static int file_rename_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent
{
ScrArea *area = CTX_wm_area(C);
SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- if (sfile->params) {
- file_rename_state_activate(sfile, sfile->params->active_file, true);
+ if (params) {
+ file_rename_state_activate(sfile, params->active_file, true);
ED_area_tag_redraw(area);
}
@@ -2633,9 +2642,10 @@ static int file_rename_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *area = CTX_wm_area(C);
SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- if (sfile->params) {
- file_rename_state_activate(sfile, sfile->params->highlight_file, false);
+ if (params) {
+ file_rename_state_activate(sfile, params->highlight_file, false);
ED_area_tag_redraw(area);
}
@@ -2665,8 +2675,9 @@ static bool file_delete_poll(bContext *C)
{
bool poll = ED_operator_file_active(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- if (sfile && sfile->params) {
+ if (sfile && params) {
char dir[FILE_MAX_LIBEXTRA];
int numfiles = filelist_files_ensure(sfile->files);
int i;
@@ -2695,6 +2706,7 @@ static int file_delete_exec(bContext *C, wmOperator *op)
{
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
int numfiles = filelist_files_ensure(sfile->files);
const char *error_message = NULL;
@@ -2704,7 +2716,7 @@ static int file_delete_exec(bContext *C, wmOperator *op)
if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL)) {
FileDirEntry *file = filelist_file(sfile->files, i);
char str[FILE_MAX];
- BLI_join_dirfile(str, sizeof(str), sfile->params->dir, file->relpath);
+ BLI_join_dirfile(str, sizeof(str), params->dir, file->relpath);
if (BLI_delete_soft(str, &error_message) != 0 || BLI_exists(str)) {
report_error = true;
}
@@ -2752,11 +2764,12 @@ static int file_start_filter_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *area = CTX_wm_area(C);
ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_UI);
- SpaceFile *sf = CTX_wm_space_file(C);
+ SpaceFile *sfile = CTX_wm_space_file(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
ARegion *region_ctx = CTX_wm_region(C);
CTX_wm_region_set(C, region);
- UI_textbutton_activate_rna(C, region, sf->params, "filter_search");
+ UI_textbutton_activate_rna(C, region, params, "filter_search");
CTX_wm_region_set(C, region_ctx);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c
index 22d206c0a70..afa85d183d8 100644
--- a/source/blender/editors/space_file/file_panels.c
+++ b/source/blender/editors/space_file/file_panels.c
@@ -132,7 +132,7 @@ static void file_panel_execution_buttons_draw(const bContext *C, Panel *panel)
{
bScreen *screen = CTX_wm_screen(C);
SpaceFile *sfile = CTX_wm_space_file(C);
- FileSelectParams *params = ED_fileselect_get_params(sfile);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
uiBlock *block = uiLayoutGetBlock(panel->layout);
uiBut *but;
uiLayout *row;
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 9e51b6ca4ba..e87142a7096 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -149,6 +149,7 @@ const char *folderlist_peeklastdir(ListBase *folderlist)
int folderlist_clear_next(struct SpaceFile *sfile)
{
+ const FileSelectParams *params = ED_fileselect_get_active_params(sfile);
struct FolderList *folder;
/* if there is no folder_next there is nothing we can clear */
@@ -159,7 +160,7 @@ int folderlist_clear_next(struct SpaceFile *sfile)
/* if previous_folder, next_folder or refresh_folder operators are executed
* it doesn't clear folder_next */
folder = sfile->folders_prev->last;
- if ((!folder) || (BLI_path_cmp(folder->foldername, sfile->params->dir) == 0)) {
+ if ((!folder) || (BLI_path_cmp(folder->foldername, params->dir) == 0)) {
return 0;
}
@@ -629,7 +630,7 @@ void filelist_setsorting(struct FileList *filelist, const short sort, bool inver
/* ********** Filter helpers ********** */
/* True if filename is meant to be hidden, eg. starting with period. */
-static bool is_hidden_dot_filename(const char *filename, FileListInternEntry *file)
+static bool is_hidden_dot_filename(const char *filename, const FileListInternEntry *file)
{
if (filename[0] == '.' && !ELEM(filename[1], '.', '\0')) {
return true; /* ignore .file */
@@ -670,8 +671,8 @@ static bool is_hidden_dot_filename(const char *filename, FileListInternEntry *fi
/* True if should be hidden, based on current filtering. */
static bool is_filtered_hidden(const char *filename,
- FileListFilter *filter,
- FileListInternEntry *file)
+ const FileListFilter *filter,
+ const FileListInternEntry *file)
{
if ((filename[0] == '.') && (filename[1] == '\0')) {
return true; /* Ignore . */
@@ -2620,7 +2621,7 @@ static int filelist_readjob_list_lib(const char *root, ListBase *entries, const
nbr_entries++;
}
- BLI_linklist_free(names, free);
+ BLI_linklist_freeN(names);
return nbr_entries;
}
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 15c6972c5f5..6e933e53a8f 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -77,18 +77,20 @@
#define VERTLIST_MAJORCOLUMN_WIDTH (25 * UI_UNIT_X)
-FileSelectParams *ED_fileselect_get_params(struct SpaceFile *sfile)
+FileSelectParams *ED_fileselect_get_active_params(const SpaceFile *sfile)
{
- if (!sfile->params) {
- ED_fileselect_set_params(sfile);
+ if (!sfile) {
+ /* Sometimes called in poll before space type was checked. */
+ return NULL;
}
+
return sfile->params;
}
/**
* \note RNA_struct_property_is_set_ex is used here because we want
* the previously used settings to be used here rather than overriding them */
-short ED_fileselect_set_params(SpaceFile *sfile)
+static FileSelectParams *fileselect_ensure_updated_file_params(SpaceFile *sfile)
{
FileSelectParams *params;
wmOperator *op = sfile->op;
@@ -136,20 +138,17 @@ short ED_fileselect_set_params(SpaceFile *sfile)
RNA_string_get(op->ptr, "filepath", name);
if (params->type == FILE_LOADLIB) {
BLI_strncpy(params->dir, name, sizeof(params->dir));
- sfile->params->file[0] = '\0';
+ params->file[0] = '\0';
}
else {
- BLI_split_dirfile(name,
- sfile->params->dir,
- sfile->params->file,
- sizeof(sfile->params->dir),
- sizeof(sfile->params->file));
+ BLI_split_dirfile(
+ name, params->dir, params->file, sizeof(params->dir), sizeof(params->file));
}
}
else {
if (is_directory && RNA_struct_property_is_set_ex(op->ptr, "directory", false)) {
RNA_string_get(op->ptr, "directory", params->dir);
- sfile->params->file[0] = '\0';
+ params->file[0] = '\0';
}
if (is_filename && RNA_struct_property_is_set_ex(op->ptr, "filename", false)) {
@@ -306,26 +305,34 @@ short ED_fileselect_set_params(SpaceFile *sfile)
sfile->folders_prev = folderlist_new();
}
- if (!sfile->params->dir[0]) {
+ if (!params->dir[0]) {
if (blendfile_path[0] != '\0') {
- BLI_split_dir_part(blendfile_path, sfile->params->dir, sizeof(sfile->params->dir));
+ BLI_split_dir_part(blendfile_path, params->dir, sizeof(params->dir));
}
else {
const char *doc_path = BKE_appdir_folder_default();
if (doc_path) {
- BLI_strncpy(sfile->params->dir, doc_path, sizeof(sfile->params->dir));
+ BLI_strncpy(params->dir, doc_path, sizeof(params->dir));
}
}
}
- folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
+ folderlist_pushdir(sfile->folders_prev, params->dir);
/* Switching thumbnails needs to recalc layout T28809. */
if (sfile->layout) {
sfile->layout->dirty = true;
}
- return 1;
+ return params;
+}
+
+FileSelectParams *ED_fileselect_ensure_active_params(SpaceFile *sfile)
+{
+ if (!sfile->params) {
+ fileselect_ensure_updated_file_params(sfile);
+ }
+ return sfile->params;
}
/* The subset of FileSelectParams.flag items we store into preferences. Note that FILE_SORT_ALPHA
@@ -364,28 +371,26 @@ void ED_fileselect_set_params_from_userdef(SpaceFile *sfile)
wmOperator *op = sfile->op;
UserDef_FileSpaceData *sfile_udata = &U.file_space_data;
- ED_fileselect_set_params(sfile);
-
+ FileSelectParams *params = fileselect_ensure_updated_file_params(sfile);
if (!op) {
return;
}
- sfile->params->thumbnail_size = sfile_udata->thumbnail_size;
- sfile->params->details_flags = sfile_udata->details_flags;
- sfile->params->filter_id = sfile_udata->filter_id;
+ params->thumbnail_size = sfile_udata->thumbnail_size;
+ params->details_flags = sfile_udata->details_flags;
+ params->filter_id = sfile_udata->filter_id;
/* Combine flags we take from params with the flags we take from userdef. */
- sfile->params->flag = (sfile->params->flag & ~PARAMS_FLAGS_REMEMBERED) |
- (sfile_udata->flag & PARAMS_FLAGS_REMEMBERED);
+ params->flag = (params->flag & ~PARAMS_FLAGS_REMEMBERED) |
+ (sfile_udata->flag & PARAMS_FLAGS_REMEMBERED);
if (file_select_use_default_display_type(sfile)) {
- sfile->params->display = sfile_udata->display_type;
+ params->display = sfile_udata->display_type;
}
if (file_select_use_default_sort_type(sfile)) {
- sfile->params->sort = sfile_udata->sort_type;
+ params->sort = sfile_udata->sort_type;
/* For the default sorting, also take invert flag from userdef. */
- sfile->params->flag = (sfile->params->flag & ~FILE_SORT_INVERT) |
- (sfile_udata->flag & FILE_SORT_INVERT);
+ params->flag = (params->flag & ~FILE_SORT_INVERT) | (sfile_udata->flag & FILE_SORT_INVERT);
}
}
@@ -400,25 +405,26 @@ void ED_fileselect_params_to_userdef(SpaceFile *sfile,
const int temp_win_size[2],
const bool is_maximized)
{
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
UserDef_FileSpaceData *sfile_udata_new = &U.file_space_data;
UserDef_FileSpaceData sfile_udata_old = U.file_space_data;
- sfile_udata_new->thumbnail_size = sfile->params->thumbnail_size;
- sfile_udata_new->details_flags = sfile->params->details_flags;
- sfile_udata_new->flag = sfile->params->flag & PARAMS_FLAGS_REMEMBERED;
- sfile_udata_new->filter_id = sfile->params->filter_id;
+ sfile_udata_new->thumbnail_size = params->thumbnail_size;
+ sfile_udata_new->details_flags = params->details_flags;
+ sfile_udata_new->flag = params->flag & PARAMS_FLAGS_REMEMBERED;
+ sfile_udata_new->filter_id = params->filter_id;
/* In some rare cases, operators ask for a specific display or sort type (e.g. chronological
* sorting for "Recover Auto Save"). So the settings are optimized for a specific operation.
* Don't let that change the userdef memory for more general cases. */
if (file_select_use_default_display_type(sfile)) {
- sfile_udata_new->display_type = sfile->params->display;
+ sfile_udata_new->display_type = params->display;
}
if (file_select_use_default_sort_type(sfile)) {
- sfile_udata_new->sort_type = sfile->params->sort;
+ sfile_udata_new->sort_type = params->sort;
/* In this case also remember the invert flag. */
sfile_udata_new->flag = (sfile_udata_new->flag & ~FILE_SORT_INVERT) |
- (sfile->params->flag & FILE_SORT_INVERT);
+ (params->flag & FILE_SORT_INVERT);
}
if (temp_win_size && !is_maximized) {
@@ -434,10 +440,11 @@ void ED_fileselect_params_to_userdef(SpaceFile *sfile,
void ED_fileselect_reset_params(SpaceFile *sfile)
{
- sfile->params->type = FILE_UNIX;
- sfile->params->flag = 0;
- sfile->params->title[0] = '\0';
- sfile->params->active_file = -1;
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+ params->type = FILE_UNIX;
+ params->flag = 0;
+ params->title[0] = '\0';
+ params->active_file = -1;
}
/**
@@ -447,7 +454,8 @@ void fileselect_file_set(SpaceFile *sfile, const int index)
{
const struct FileDirEntry *file = filelist_file(sfile->files, index);
if (file && file->relpath && file->relpath[0] && !(file->typeflag & FILE_TYPE_DIR)) {
- BLI_strncpy(sfile->params->file, file->relpath, FILE_MAXFILE);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+ BLI_strncpy(params->file, file->relpath, FILE_MAXFILE);
}
}
@@ -759,7 +767,7 @@ static void file_attribute_columns_init(const FileSelectParams *params, FileLayo
void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *region)
{
- FileSelectParams *params = ED_fileselect_get_params(sfile);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
FileLayout *layout = NULL;
View2D *v2d = &region->v2d;
int numfiles;
@@ -873,7 +881,8 @@ void ED_file_change_dir_ex(bContext *C, bScreen *screen, ScrArea *area)
return;
}
SpaceFile *sfile = area->spacedata.first;
- if (sfile->params) {
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+ if (params) {
wmWindowManager *wm = CTX_wm_manager(C);
Scene *scene = WM_windows_scene_get_from_screen(wm, screen);
if (LIKELY(scene != NULL)) {
@@ -882,20 +891,20 @@ void ED_file_change_dir_ex(bContext *C, bScreen *screen, ScrArea *area)
/* Clear search string, it is very rare to want to keep that filter while changing dir,
* and usually very annoying to keep it actually! */
- sfile->params->filter_search[0] = '\0';
- sfile->params->active_file = -1;
+ params->filter_search[0] = '\0';
+ params->active_file = -1;
- if (!filelist_is_dir(sfile->files, sfile->params->dir)) {
- BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), sizeof(sfile->params->dir));
+ if (!filelist_is_dir(sfile->files, params->dir)) {
+ BLI_strncpy(params->dir, filelist_dir(sfile->files), sizeof(params->dir));
/* could return but just refresh the current dir */
}
- filelist_setdir(sfile->files, sfile->params->dir);
+ filelist_setdir(sfile->files, params->dir);
if (folderlist_clear_next(sfile)) {
folderlist_free(sfile->folders_next);
}
- folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
+ folderlist_pushdir(sfile->folders_prev, params->dir);
file_draw_check_ex(C, area);
}
@@ -1010,7 +1019,8 @@ void ED_fileselect_clear(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfi
filelist_clear(sfile->files);
}
- sfile->params->highlight_file = -1;
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+ params->highlight_file = -1;
WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 6ffe553e076..c72ca58abba 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -270,7 +270,7 @@ static void file_refresh(const bContext *C, ScrArea *area)
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
SpaceFile *sfile = CTX_wm_space_file(C);
- FileSelectParams *params = ED_fileselect_get_params(sfile);
+ FileSelectParams *params = ED_fileselect_ensure_active_params(sfile);
struct FSMenu *fsmenu = ED_fsmenu_get();
if (!sfile->folders_prev) {
@@ -413,7 +413,7 @@ static void file_main_region_message_subscribe(const struct bContext *UNUSED(C),
struct wmMsgBus *mbus)
{
SpaceFile *sfile = area->spacedata.first;
- FileSelectParams *params = ED_fileselect_get_params(sfile);
+ FileSelectParams *params = ED_fileselect_ensure_active_params(sfile);
/* This is a bit odd that a region owns the subscriber for an area,
* keep for now since all subscribers for WM are regions.
* May be worth re-visiting later. */
@@ -446,7 +446,7 @@ static void file_main_region_draw(const bContext *C, ARegion *region)
{
/* draw entirely, view changes should be handled here */
SpaceFile *sfile = CTX_wm_space_file(C);
- FileSelectParams *params = ED_fileselect_get_params(sfile);
+ FileSelectParams *params = ED_fileselect_ensure_active_params(sfile);
View2D *v2d = &region->v2d;
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 1647fd4a6a6..c3e4eceef6e 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -72,7 +72,9 @@
/* ************************************************************************** */
/* INSERT DUPLICATE AND BAKE KEYFRAMES */
-/* ******************** Insert Keyframes Operator ************************* */
+/* -------------------------------------------------------------------- */
+/** \name Insert Keyframes Operator
+ * \{ */
/* Mode defines for insert keyframes tool. */
typedef enum eGraphKeys_InsertKey_Types {
@@ -290,7 +292,11 @@ void GRAPH_OT_keyframe_insert(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_insertkey_types, 0, "Type", "");
}
-/* ******************** Click-Insert Keyframes Operator ************************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Click-Insert Keyframes Operator
+ * \{ */
static int graphkeys_click_insert_exec(bContext *C, wmOperator *op)
{
@@ -444,8 +450,13 @@ void GRAPH_OT_click_insert(wmOperatorType *ot)
"Extend selection instead of deselecting everything first");
}
-/* ******************** Copy/Paste Keyframes Operator ************************* */
-/* NOTE: the backend code for this is shared with the dopesheet editor */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Copy/Paste Keyframes Operator
+ *
+ * \note the back-end code for this is shared with the dope-sheet editor.
+ * \{ */
static short copy_graph_keys(bAnimContext *ac)
{
@@ -605,7 +616,11 @@ void GRAPH_OT_paste(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
-/* ******************** Duplicate Keyframes Operator ************************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Duplicate Keyframes Operator
+ * \{ */
static void duplicate_graph_keys(bAnimContext *ac)
{
@@ -667,7 +682,11 @@ void GRAPH_OT_duplicate(wmOperatorType *ot)
RNA_def_enum(ot->srna, "mode", rna_enum_transform_mode_types, TFM_TRANSLATION, "Mode", "");
}
-/* ******************** Delete Keyframes Operator ************************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Delete Keyframes Operator
+ * \{ */
static bool delete_graph_keys(bAnimContext *ac)
{
@@ -746,7 +765,11 @@ void GRAPH_OT_delete(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ******************** Clean Keyframes Operator ************************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Clean Keyframes Operator
+ * \{ */
static void clean_graph_keys(bAnimContext *ac, float thresh, bool clean_chan)
{
@@ -816,8 +839,13 @@ void GRAPH_OT_clean(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "channels", false, "Channels", "");
}
-/* ******************** Bake F-Curve Operator *********************** */
-/* This operator bakes the data of the selected F-Curves to F-Points */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Bake F-Curve Operator
+ *
+ * This operator bakes the data of the selected F-Curves to F-Points.
+ * \{ */
/* Bake each F-Curve into a set of samples. */
static void bake_graph_curves(bAnimContext *ac, int start, int end)
@@ -899,8 +927,13 @@ void GRAPH_OT_bake(wmOperatorType *ot)
/* TODO: add props for start/end frames (Joshua Leung 2009) */
}
-/* ******************** Un-Bake F-Curve Operator *********************** */
-/* This operator unbakes the data of the selected F-Points to F-Curves. */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Un-Bake F-Curve Operator
+ *
+ * This operator un-bakes the data of the selected F-Points to F-Curves.
+ * \{ */
/* Un-Bake F-Points into F-Curves. */
static void unbake_graph_curves(bAnimContext *ac, int start, int end)
@@ -970,8 +1003,13 @@ void GRAPH_OT_unbake(wmOperatorType *ot)
#ifdef WITH_AUDASPACE
-/* ******************** Sound Bake F-Curve Operator *********************** */
-/* This operator bakes the given sound to the selected F-Curves */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Sound Bake F-Curve Operator
+ *
+ * This operator bakes the given sound to the selected F-Curves.
+ * \{ */
/* ------------------- */
@@ -1204,10 +1242,14 @@ void GRAPH_OT_sound_bake(wmOperatorType *ot)
0.1);
}
-/* ******************** Sample Keyframes Operator *********************** */
-/* This operator 'bakes' the values of the curve into new keyframes between pairs
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Sample Keyframes Operator
+ *
+ * This operator 'bakes' the values of the curve into new keyframes between pairs
* of selected keyframes. It is useful for creating keyframes for tweaking overlap.
- */
+ * \{ */
/* Evaluates the curves between each selected keyframe on each frame, and keys the value. */
static void sample_graph_keys(bAnimContext *ac)
@@ -1267,10 +1309,14 @@ void GRAPH_OT_sample(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
/* ************************************************************************** */
/* EXTRAPOLATION MODE AND KEYFRAME HANDLE SETTINGS */
-/* ******************** Set Extrapolation-Type Operator *********************** */
+/* -------------------------------------------------------------------- */
+/** \name Set Extrapolation-Type Operator
+ * \{ */
/* Defines for make/clear cyclic extrapolation tools. */
#define MAKE_CYCLIC_EXPO -1
@@ -1400,7 +1446,11 @@ void GRAPH_OT_extrapolation_type(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_expo_types, 0, "Type", "");
}
-/* ******************** Set Interpolation-Type Operator *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Set Interpolation-Type Operator
+ * \{ */
/* This function is responsible for setting interpolation mode for keyframes. */
static void setipo_graph_keys(bAnimContext *ac, short mode)
@@ -1474,7 +1524,11 @@ void GRAPH_OT_interpolation_type(wmOperatorType *ot)
ot->srna, "type", rna_enum_beztriple_interpolation_mode_items, 0, "Type", "");
}
-/* ******************** Set Easing Operator *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Set Easing Operator
+ * \{ */
static void seteasing_graph_keys(bAnimContext *ac, short mode)
{
@@ -1545,7 +1599,11 @@ void GRAPH_OT_easing_type(wmOperatorType *ot)
ot->srna, "type", rna_enum_beztriple_interpolation_easing_items, 0, "Type", "");
}
-/* ******************** Set Handle-Type Operator *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Set Handle-Type Operator
+ * \{ */
/* This function is responsible for setting handle-type of selected keyframes. */
static void sethandles_graph_keys(bAnimContext *ac, short mode)
@@ -1624,15 +1682,19 @@ void GRAPH_OT_handle_type(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_keyframe_handle_type_items, 0, "Type", "");
}
+/** \} */
+
/* ************************************************************************** */
/* EULER FILTER */
-/* ***************** 'Euler Filter' Operator **************************** */
-/* Euler filter tools (as seen in Maya), are necessary for working with 'baked'
+/* -------------------------------------------------------------------- */
+/** \name 'Euler Filter' Operator
+ *
+ * Euler filter tools (as seen in Maya), are necessary for working with 'baked'
* rotation curves (with Euler rotations). The main purpose of such tools is to
* resolve any discontinuities that may arise in the curves due to the clamping
* of values to -180 degrees to 180 degrees.
- */
+ * \{ */
/* Set of three euler-rotation F-Curves. */
typedef struct tEulerFilter {
@@ -1903,7 +1965,7 @@ static int graphkeys_euler_filter_exec(bContext *C, wmOperator *op)
if (curves_seen < 3) {
/* Showing the entire error message makes no sense when the artist is only trying to filter
* one or two curves. */
- BKE_report(op->reports, RPT_WARNING, "No Euler Rotations could be corrected.");
+ BKE_report(op->reports, RPT_WARNING, "No Euler Rotations could be corrected");
}
else {
BKE_report(op->reports,
@@ -1919,15 +1981,15 @@ static int graphkeys_euler_filter_exec(bContext *C, wmOperator *op)
BLI_assert(curves_filtered < curves_seen);
BKE_reportf(op->reports,
RPT_INFO,
- "%d of %d rotation channels were filtered. See the Info window for details.",
+ "%d of %d rotation channels were filtered (see the Info window for details)",
curves_filtered,
curves_seen);
}
else if (curves_seen == 1) {
- BKE_report(op->reports, RPT_INFO, "The rotation channel was filtered.");
+ BKE_report(op->reports, RPT_INFO, "The rotation channel was filtered");
}
else {
- BKE_reportf(op->reports, RPT_INFO, "All %d rotation channels were filtered.", curves_seen);
+ BKE_reportf(op->reports, RPT_INFO, "All %d rotation channels were filtered", curves_seen);
}
/* Set notifier that keyframes have changed. */
@@ -1955,10 +2017,14 @@ void GRAPH_OT_euler_filter(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
/* ************************************************************************** */
/* SNAPPING */
-/* ***************** Jump to Selected Frames Operator *********************** */
+/* -------------------------------------------------------------------- */
+/** \name Jump to Selected Frames Operator
+ * \{ */
static bool graphkeys_framejump_poll(bContext *C)
{
@@ -2110,7 +2176,11 @@ void GRAPH_OT_snap_cursor_value(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ******************** Snap Keyframes Operator *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Snap Keyframes Operator
+ * \{ */
/* Defines for snap keyframes tool. */
static const EnumPropertyItem prop_graphkeys_snap_types[] = {
@@ -2262,7 +2332,11 @@ void GRAPH_OT_snap(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_snap_types, 0, "Type", "");
}
-/* ******************** Mirror Keyframes Operator *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Mirror Keyframes Operator
+ * \{ */
/* Defines for mirror keyframes tool. */
static const EnumPropertyItem prop_graphkeys_mirror_types[] = {
@@ -2421,7 +2495,11 @@ void GRAPH_OT_mirror(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_mirror_types, 0, "Type", "");
}
-/* ******************** Smooth Keyframes Operator *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Smooth Keyframes Operator
+ * \{ */
static int graphkeys_smooth_exec(bContext *C, wmOperator *UNUSED(op))
{
@@ -2475,10 +2553,14 @@ void GRAPH_OT_smooth(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
/* ************************************************************************** */
/* F-CURVE MODIFIERS */
-/* ******************** Add F-Modifier Operator *********************** */
+/* -------------------------------------------------------------------- */
+/** \name Add F-Modifier Operator
+ * \{ */
static const EnumPropertyItem *graph_fmodifier_itemf(bContext *C,
PointerRNA *UNUSED(ptr),
@@ -2596,7 +2678,11 @@ void GRAPH_OT_fmodifier_add(wmOperatorType *ot)
ot->srna, "only_active", 1, "Only Active", "Only add F-Modifier to active F-Curve");
}
-/* ******************** Copy F-Modifiers Operator *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Copy F-Modifiers Operator
+ * \{ */
static int graph_fmodifier_copy_exec(bContext *C, wmOperator *op)
{
@@ -2658,7 +2744,11 @@ void GRAPH_OT_fmodifier_copy(wmOperatorType *ot)
#endif
}
-/* ******************** Paste F-Modifiers Operator *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Paste F-Modifiers Operator
+ * \{ */
static int graph_fmodifier_paste_exec(bContext *C, wmOperator *op)
{
@@ -2746,10 +2836,14 @@ void GRAPH_OT_fmodifier_paste(wmOperatorType *ot)
"Replace existing F-Modifiers, instead of just appending to the end of the existing list");
}
+/** \} */
+
/* ************************************************************************** */
/* Drivers */
-/* ******************** Copy Driver Vars Operator *********************** */
+/* -------------------------------------------------------------------- */
+/** \name Copy Driver Variables Operator
+ * \{ */
static int graph_driver_vars_copy_exec(bContext *C, wmOperator *op)
{
@@ -2786,7 +2880,11 @@ void GRAPH_OT_driver_variables_copy(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ******************** Paste Driver Vars Operator *********************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Paste Driver Variables Operator
+ * \{ */
static int graph_driver_vars_paste_exec(bContext *C, wmOperator *op)
{
@@ -2838,7 +2936,11 @@ void GRAPH_OT_driver_variables_paste(wmOperatorType *ot)
"existing list");
}
-/* ************************************************************************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Delete Invalid Drivers Operator
+ * \{ */
static int graph_driver_delete_invalid_exec(bContext *C, wmOperator *op)
{
@@ -2926,3 +3028,5 @@ void GRAPH_OT_driver_delete_invalid(wmOperatorType *ot)
/* Flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+
+/** \} */
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 007f99e3ce5..12035ab6b61 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -501,7 +501,6 @@ void GRAPH_OT_select_all(wmOperatorType *ot)
* The selection backend is also reused for the Lasso and Circle select operators.
*/
-
static rctf initialize_box_select_coords(const bAnimContext *ac, const rctf *rectf_view)
{
const View2D *v2d = &ac->region->v2d;
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 0fa48059cdc..a2c0819dc60 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -2649,7 +2649,7 @@ void IMAGE_OT_new(wmOperatorType *ot)
"Generated Type",
"Fill the image with a grid for UV map testing");
RNA_def_boolean(
- ot->srna, "float", 0, "32 bit Float", "Create image with 32 bit floating point bit depth");
+ ot->srna, "float", 0, "32-bit Float", "Create image with 32-bit floating-point bit depth");
RNA_def_property_flag(prop, PROP_HIDDEN);
prop = RNA_def_boolean(
ot->srna, "use_stereo_3d", 0, "Stereo 3D", "Create an image with left and right views");
@@ -3737,7 +3737,7 @@ static void def_fill_tile(StructOrFunctionRNA *srna)
/* Only needed when filling the first tile. */
RNA_def_boolean(
- srna, "float", 0, "32 bit Float", "Create image with 32 bit floating point bit depth");
+ srna, "float", 0, "32-bit Float", "Create image with 32-bit floating-point bit depth");
RNA_def_boolean(srna, "alpha", 1, "Alpha", "Create an image with an alpha channel");
}
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 890bb8a64bc..ffac5c982d6 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -559,12 +559,23 @@ static void get_stats_string(
stats_fmt->totgpstroke,
stats_fmt->totgppoint);
}
- else if (stats_is_object_dynamic_topology_sculpt(ob)) {
- *ofs += BLI_snprintf(info + *ofs,
- len - *ofs,
- TIP_("Verts:%s | Tris:%s"),
- stats_fmt->totvert,
- stats_fmt->tottri);
+ else if (ob && (object_mode & OB_MODE_SCULPT)) {
+ if (stats_is_object_dynamic_topology_sculpt(ob)) {
+ *ofs += BLI_snprintf(info + *ofs,
+ len - *ofs,
+ TIP_("Verts:%s | Tris:%s"),
+ stats_fmt->totvert,
+ stats_fmt->tottri);
+ }
+ else {
+ *ofs += BLI_snprintf(info + *ofs,
+ len - *ofs,
+ TIP_("Verts:%s/%s | Faces:%s/%s"),
+ stats_fmt->totvertsculpt,
+ stats_fmt->totvert,
+ stats_fmt->totfacesculpt,
+ stats_fmt->totface);
+ }
}
else {
*ofs += BLI_snprintf(info + *ofs,
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index 561de5e82a6..9832ca975cf 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -292,7 +292,7 @@ static int mouse_nla_channels(
/* TODO: make this use the operator instead of calling the function directly
* however, calling the operator requires that we supply the args,
* and that works with proper buttons only */
- BKE_nla_action_pushdown(adt);
+ BKE_nla_action_pushdown(adt, ID_IS_OVERRIDE_LIBRARY(ale->id));
}
else {
/* when in tweakmode, this button becomes the toggle for mapped editing */
@@ -516,7 +516,7 @@ static int nlachannels_pushdown_exec(bContext *C, wmOperator *op)
}
/* 'push-down' action - only usable when not in TweakMode */
- BKE_nla_action_pushdown(adt);
+ BKE_nla_action_pushdown(adt, ID_IS_OVERRIDE_LIBRARY(id));
struct Main *bmain = CTX_data_main(C);
DEG_id_tag_update_ex(bmain, id, ID_RECALC_ANIMATION);
@@ -648,19 +648,21 @@ bool nlaedit_add_tracks_existing(bAnimContext *ac, bool above_sel)
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
+ const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id);
+
/* check if just adding a new track above this one,
* or whether we're adding a new one to the top of the stack that this one belongs to
*/
if (above_sel) {
/* just add a new one above this one */
- BKE_nlatrack_add(adt, nlt);
+ BKE_nlatrack_add(adt, nlt, is_liboverride);
ale->update = ANIM_UPDATE_DEPS;
added = true;
}
else if ((lastAdt == NULL) || (adt != lastAdt)) {
/* add one track to the top of the owning AnimData's stack,
* then don't add anymore to this stack */
- BKE_nlatrack_add(adt, NULL);
+ BKE_nlatrack_add(adt, NULL, is_liboverride);
lastAdt = adt;
ale->update = ANIM_UPDATE_DEPS;
added = true;
@@ -698,7 +700,7 @@ bool nlaedit_add_tracks_empty(bAnimContext *ac)
/* ensure it is empty */
if (BLI_listbase_is_empty(&adt->nla_tracks)) {
/* add new track to this AnimData block then */
- BKE_nlatrack_add(adt, NULL);
+ BKE_nlatrack_add(adt, NULL, ID_IS_OVERRIDE_LIBRARY(ale->id));
ale->update = ANIM_UPDATE_DEPS;
added = true;
}
@@ -796,6 +798,11 @@ static int nlaedit_delete_tracks_exec(bContext *C, wmOperator *UNUSED(op))
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
+ if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) {
+ /* No deletion of non-local tracks of override data. */
+ continue;
+ }
+
/* if track is currently 'solo', then AnimData should have its
* 'has solo' flag disabled
*/
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index ed8e5ad76e9..3fa1b614a03 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -649,6 +649,7 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op)
NlaTrack *nlt = (NlaTrack *)ale->data;
AnimData *adt = ale->adt;
NlaStrip *strip = NULL;
+ const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id);
/* Sanity check: only apply actions of the right type for this ID.
* NOTE: in the case that this hasn't been set,
@@ -671,12 +672,12 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op)
strip->start = cfra;
/* firstly try adding strip to our current track, but if that fails, add to a new track */
- if (BKE_nlatrack_add_strip(nlt, strip) == 0) {
+ if (BKE_nlatrack_add_strip(nlt, strip, is_liboverride) == 0) {
/* trying to add to the current failed (no space),
* so add a new track to the stack, and add to that...
*/
- nlt = BKE_nlatrack_add(adt, NULL);
- BKE_nlatrack_add_strip(nlt, strip);
+ nlt = BKE_nlatrack_add(adt, NULL, is_liboverride);
+ BKE_nlatrack_add_strip(nlt, strip, is_liboverride);
}
/* auto-name it */
@@ -886,6 +887,7 @@ static int nlaedit_add_sound_exec(bContext *C, wmOperator *UNUSED(op))
AnimData *adt = ale->adt;
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
+ const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id);
/* does this belong to speaker - assumed to live on Object level only */
if ((GS(ale->id->name) != ID_OB) || (ob->type != OB_SPEAKER)) {
@@ -899,12 +901,12 @@ static int nlaedit_add_sound_exec(bContext *C, wmOperator *UNUSED(op))
strip->end += cfra;
/* firstly try adding strip to our current track, but if that fails, add to a new track */
- if (BKE_nlatrack_add_strip(nlt, strip) == 0) {
+ if (BKE_nlatrack_add_strip(nlt, strip, is_liboverride) == 0) {
/* trying to add to the current failed (no space),
* so add a new track to the stack, and add to that...
*/
- nlt = BKE_nlatrack_add(adt, NULL);
- BKE_nlatrack_add_strip(nlt, strip);
+ nlt = BKE_nlatrack_add(adt, NULL, is_liboverride);
+ BKE_nlatrack_add_strip(nlt, strip, is_liboverride);
}
/* auto-name it */
@@ -966,6 +968,11 @@ static int nlaedit_add_meta_exec(bContext *C, wmOperator *UNUSED(op))
AnimData *adt = ale->adt;
NlaStrip *strip;
+ if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) {
+ /* No making metastrips in non-local tracks of override data. */
+ continue;
+ }
+
/* create meta-strips from the continuous chains of selected strips */
BKE_nlastrips_make_metas(&nlt->strips, 0);
@@ -1030,6 +1037,11 @@ static int nlaedit_remove_meta_exec(bContext *C, wmOperator *UNUSED(op))
for (ale = anim_data.first; ale; ale = ale->next) {
NlaTrack *nlt = (NlaTrack *)ale->data;
+ if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) {
+ /* No removing metastrips from non-local tracks of override data. */
+ continue;
+ }
+
/* clear all selected meta-strips, regardless of whether they are temporary or not */
BKE_nlastrips_clear_metas(&nlt->strips, 1, 0);
@@ -1096,6 +1108,11 @@ static int nlaedit_duplicate_exec(bContext *C, wmOperator *op)
NlaStrip *strip, *nstrip, *next;
NlaTrack *track;
+ /* Note: We allow this operator in override context because it is almost always (from possible
+ * default user interactions) paired with the transform one, which will ensure that the new
+ * strip ends up in a valid (local) track. */
+
+ const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id);
for (strip = nlt->strips.first; strip; strip = next) {
next = strip->next;
@@ -1106,13 +1123,13 @@ static int nlaedit_duplicate_exec(bContext *C, wmOperator *op)
/* in case there's no space in the track above,
* or we haven't got a reference to it yet, try adding */
- if (BKE_nlatrack_add_strip(nlt->next, nstrip) == 0) {
+ if (BKE_nlatrack_add_strip(nlt->next, nstrip, is_liboverride) == 0) {
/* need to add a new track above the one above the current one
* - if the current one is the last one, nlt->next will be NULL, which defaults to adding
* at the top of the stack anyway...
*/
- track = BKE_nlatrack_add(adt, nlt->next);
- BKE_nlatrack_add_strip(track, nstrip);
+ track = BKE_nlatrack_add(adt, nlt->next, is_liboverride);
+ BKE_nlatrack_add_strip(track, nstrip, is_liboverride);
}
/* deselect the original and the active flag */
@@ -1209,6 +1226,11 @@ static int nlaedit_delete_exec(bContext *C, wmOperator *UNUSED(op))
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip, *nstrip;
+ if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) {
+ /* No deletion of strips in non-local tracks of override data. */
+ continue;
+ }
+
for (strip = nlt->strips.first; strip; strip = nstrip) {
nstrip = strip->next;
@@ -1359,6 +1381,11 @@ static int nlaedit_split_exec(bContext *C, wmOperator *UNUSED(op))
AnimData *adt = ale->adt;
NlaStrip *strip, *next;
+ if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) {
+ /* No splitting of strips in non-local tracks of override data. */
+ continue;
+ }
+
for (strip = nlt->strips.first; strip; strip = next) {
next = strip->next;
@@ -1502,6 +1529,12 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op)
NlaStrip *strip, *stripN = NULL;
NlaStrip *area = NULL, *sb = NULL;
+ const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id);
+
+ if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) {
+ /* No re-ordering of strips whithin non-local tracks of override data. */
+ continue;
+ }
/* make temporary metastrips so that entire islands of selections can be moved around */
BKE_nlastrips_make_metas(&nlt->strips, 1);
@@ -1610,8 +1643,8 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op)
}
/* add strips back to track now */
- BKE_nlatrack_add_strip(nlt, area);
- BKE_nlatrack_add_strip(nlt, sb);
+ BKE_nlatrack_add_strip(nlt, area, is_liboverride);
+ BKE_nlatrack_add_strip(nlt, sb, is_liboverride);
}
/* clear (temp) metastrips */
@@ -1674,11 +1707,19 @@ static int nlaedit_move_up_exec(bContext *C, wmOperator *UNUSED(op))
NlaTrack *nltn = nlt->next;
NlaStrip *strip, *stripn;
+ const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id);
+
/* if this track has no tracks after it, skip for now... */
if (nltn == NULL) {
continue;
}
+ if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt) ||
+ BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nltn)) {
+ /* No moving of strips in non-local tracks of override data. */
+ continue;
+ }
+
/* for every selected strip, try to move */
for (strip = nlt->strips.first; strip; strip = stripn) {
stripn = strip->next;
@@ -1689,7 +1730,7 @@ static int nlaedit_move_up_exec(bContext *C, wmOperator *UNUSED(op))
/* remove from its current track, and add to the one above
* (it 'should' work, so no need to worry) */
BLI_remlink(&nlt->strips, strip);
- BKE_nlatrack_add_strip(nltn, strip);
+ BKE_nlatrack_add_strip(nltn, strip, is_liboverride);
}
}
}
@@ -1751,11 +1792,19 @@ static int nlaedit_move_down_exec(bContext *C, wmOperator *UNUSED(op))
NlaTrack *nltp = nlt->prev;
NlaStrip *strip, *stripn;
+ const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id);
+
/* if this track has no tracks before it, skip for now... */
if (nltp == NULL) {
continue;
}
+ if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt) ||
+ BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nltp)) {
+ /* No moving of strips in non-local tracks of override data. */
+ continue;
+ }
+
/* for every selected strip, try to move */
for (strip = nlt->strips.first; strip; strip = stripn) {
stripn = strip->next;
@@ -1766,7 +1815,7 @@ static int nlaedit_move_down_exec(bContext *C, wmOperator *UNUSED(op))
/* remove from its current track, and add to the one above
* (it 'should' work, so no need to worry) */
BLI_remlink(&nlt->strips, strip);
- BKE_nlatrack_add_strip(nltp, strip);
+ BKE_nlatrack_add_strip(nltp, strip, is_liboverride);
}
}
}
@@ -2023,11 +2072,11 @@ static int nlaedit_apply_scale_exec(bContext *C, wmOperator *UNUSED(op))
/* strip must be selected, and must be action-clip only
* (transitions don't have scale) */
if ((strip->flag & NLASTRIP_FLAG_SELECT) && (strip->type == NLASTRIP_TYPE_CLIP)) {
- /* if the referenced action is used by other strips,
- * make this strip use its own copy */
- if (strip->act == NULL) {
+ if (strip->act == NULL || ID_IS_OVERRIDE_LIBRARY(strip->act) || ID_IS_LINKED(strip->act)) {
continue;
}
+ /* if the referenced action is used by other strips,
+ * make this strip use its own copy */
if (strip->act->id.us > 1) {
/* make a copy of the Action to work on */
bAction *act = (bAction *)BKE_id_copy(bmain, &strip->act->id);
@@ -2200,6 +2249,8 @@ static int nlaedit_snap_exec(bContext *C, wmOperator *op)
NlaStrip *strip, *stripn;
NlaTrack *track;
+ const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id);
+
/* create meta-strips from the continuous chains of selected strips */
BKE_nlastrips_make_metas(&nlt->strips, 1);
@@ -2255,10 +2306,10 @@ static int nlaedit_snap_exec(bContext *C, wmOperator *op)
BLI_remlink(&tmp_strips, strip);
/* in case there's no space in the current track, try adding */
- if (BKE_nlatrack_add_strip(nlt, strip) == 0) {
+ if (BKE_nlatrack_add_strip(nlt, strip, is_liboverride) == 0) {
/* need to add a new track above the current one */
- track = BKE_nlatrack_add(adt, nlt);
- BKE_nlatrack_add_strip(track, strip);
+ track = BKE_nlatrack_add(adt, nlt, is_liboverride);
+ BKE_nlatrack_add_strip(track, strip, is_liboverride);
/* clear temp meta-strips on this new track,
* as we may not be able to get back to it */
@@ -2375,6 +2426,11 @@ static int nla_fmodifier_add_exec(bContext *C, wmOperator *op)
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
+ if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) {
+ /* No adding f-modifiers to strips in non-local tracks of override data. */
+ continue;
+ }
+
for (strip = nlt->strips.first; strip; strip = strip->next) {
/* can F-Modifier be added to the current strip? */
if (active_only) {
@@ -2552,6 +2608,11 @@ static int nla_fmodifier_paste_exec(bContext *C, wmOperator *op)
NlaTrack *nlt = (NlaTrack *)ale->data;
NlaStrip *strip;
+ if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) {
+ /* No pasting in non-local tracks of override data. */
+ continue;
+ }
+
for (strip = nlt->strips.first; strip; strip = strip->next) {
/* can F-Modifier be added to the current strip? */
if (active_only) {
diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt
index 996570fae25..74f99540bee 100644
--- a/source/blender/editors/space_outliner/CMakeLists.txt
+++ b/source/blender/editors/space_outliner/CMakeLists.txt
@@ -48,10 +48,23 @@ set(SRC
tree/tree_display.cc
tree/tree_display_libraries.cc
tree/tree_display_view_layer.cc
+ tree/tree_display_sequencer.cc
+ tree/tree_display_orphaned.cc
+ tree/tree_display_scenes.cc
+ tree/tree_display_data.cc
+ tree/tree_element.cc
+ tree/tree_element_anim_data.cc
+ tree/tree_element_driver_base.cc
+ tree/tree_element_nla.cc
outliner_intern.h
tree/tree_display.h
tree/tree_display.hh
+ tree/tree_element.h
+ tree/tree_element.hh
+ tree/tree_element_anim_data.hh
+ tree/tree_element_driver_base.hh
+ tree/tree_element_nla.hh
)
set(LIB
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c
index 865e06bf0b6..d3da7b80765 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.c
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.c
@@ -854,7 +854,8 @@ static bool datastack_drop_poll(bContext *C,
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
ARegion *region = CTX_wm_region(C);
- bool changed = outliner_flag_set(&space_outliner->tree, TSE_HIGHLIGHTED | TSE_DRAG_ANY, false);
+ bool changed = outliner_flag_set(
+ &space_outliner->tree, TSE_HIGHLIGHTED_ANY | TSE_DRAG_ANY, false);
StackDropData *drop_data = drag->poin;
if (!drop_data) {
@@ -1173,7 +1174,8 @@ static bool collection_drop_poll(bContext *C,
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
ARegion *region = CTX_wm_region(C);
- bool changed = outliner_flag_set(&space_outliner->tree, TSE_HIGHLIGHTED | TSE_DRAG_ANY, false);
+ bool changed = outliner_flag_set(
+ &space_outliner->tree, TSE_HIGHLIGHTED_ANY | TSE_DRAG_ANY, false);
CollectionDrop data;
if (!event->shift && collection_drop_init(C, drag, event, &data)) {
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index ea2e3ce2565..6364fbc0a87 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -2782,7 +2782,7 @@ static void outliner_draw_iconrow_doit(uiBlock *block,
icon_border);
}
- if (tselem->flag & TSE_HIGHLIGHTED) {
+ if (tselem->flag & TSE_HIGHLIGHTED_ICON) {
alpha_fac += 0.5;
}
tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, alpha_fac, false);
@@ -3078,8 +3078,14 @@ static void outliner_draw_tree_element(bContext *C,
/* datatype icon */
if (!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE))) {
- tselem_draw_icon(
- block, xmax, (float)startx + offsx, (float)*starty, tselem, te, alpha_fac, true);
+ tselem_draw_icon(block,
+ xmax,
+ (float)startx + offsx,
+ (float)*starty,
+ tselem,
+ te,
+ (tselem->flag & TSE_HIGHLIGHTED_ICON) ? alpha_fac + 0.5f : alpha_fac,
+ true);
offsx += UI_UNIT_X + 4 * ufac;
}
else {
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index bf94e9e04a4..a1ff6193cd0 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -117,19 +117,27 @@ static int outliner_highlight_update(bContext *C, wmOperator *UNUSED(op), const
TreeElement *hovered_te = outliner_find_item_at_y(
space_outliner, &space_outliner->tree, view_mval[1]);
- bool is_over_icon;
+ TreeElement *icon_te = NULL;
+ bool is_over_icon = false;
if (hovered_te) {
- hovered_te = outliner_find_item_at_x_in_row(
+ icon_te = outliner_find_item_at_x_in_row(
space_outliner, hovered_te, view_mval[0], NULL, &is_over_icon);
}
+
bool changed = false;
- if (!hovered_te || !(hovered_te->store_elem->flag & TSE_HIGHLIGHTED)) {
- changed = outliner_flag_set(&space_outliner->tree, TSE_HIGHLIGHTED | TSE_DRAG_ANY, false);
+ if (!hovered_te || !is_over_icon || !(hovered_te->store_elem->flag & TSE_HIGHLIGHTED) ||
+ !(icon_te->store_elem->flag & TSE_HIGHLIGHTED_ICON)) {
+ /* Clear highlights when nothing is hovered or when a new item is hovered. */
+ changed = outliner_flag_set(&space_outliner->tree, TSE_HIGHLIGHTED_ANY | TSE_DRAG_ANY, false);
if (hovered_te) {
hovered_te->store_elem->flag |= TSE_HIGHLIGHTED;
changed = true;
}
+ if (is_over_icon) {
+ icon_te->store_elem->flag |= TSE_HIGHLIGHTED_ICON;
+ changed = true;
+ }
}
if (changed) {
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index aefba929c5e..0294b4836c8 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -47,10 +47,13 @@ struct wmKeyConfig;
struct wmOperatorType;
typedef struct SpaceOutliner_Runtime {
- /**
- * Internal C++ object to create and manage the tree for a specific display type (View Layers,
- * Scenes, Blender File, etc.). */
+ /** Internal C++ object to create and manage the tree for a specific display type (View Layers,
+ * Scenes, Blender File, etc.). */
struct TreeDisplay *tree_display;
+
+ /** Pointers to tree-store elements, grouped by `(id, type, nr)`
+ * in hash-table for faster searching. */
+ struct GHash *treehash;
} SpaceOutliner_Runtime;
typedef enum TreeElementInsertType {
@@ -72,6 +75,14 @@ typedef TreeTraversalAction (*TreeTraversalFunc)(struct TreeElement *te, void *c
typedef struct TreeElement {
struct TreeElement *next, *prev, *parent;
+
+ /**
+ * Handle to the new C++ object (a derived type of base #AbstractTreeElement) that should replace
+ * #TreeElement. Step by step, data should be moved to it and operations based on the type should
+ * become virtual methods of the class hierarchy.
+ */
+ struct TreeElementType *type;
+
ListBase subtree;
int xs, ys; /* Do selection. */
TreeStoreElem *store_elem; /* Element in tree store. */
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 159511546be..7308b161d18 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -80,12 +80,11 @@
#include "RNA_access.h"
-#include "SEQ_sequencer.h"
-
#include "UI_interface.h"
#include "outliner_intern.h"
#include "tree/tree_display.h"
+#include "tree/tree_element.h"
#ifdef WIN32
# include "BLI_math_base.h" /* M_PI */
@@ -132,9 +131,9 @@ static void outliner_storage_cleanup(SpaceOutliner *space_outliner)
if (BLI_mempool_len(ts) == unused) {
BLI_mempool_destroy(ts);
space_outliner->treestore = NULL;
- if (space_outliner->treehash) {
- BKE_outliner_treehash_free(space_outliner->treehash);
- space_outliner->treehash = NULL;
+ if (space_outliner->runtime->treehash) {
+ BKE_outliner_treehash_free(space_outliner->runtime->treehash);
+ space_outliner->runtime->treehash = NULL;
}
}
else {
@@ -150,16 +149,16 @@ static void outliner_storage_cleanup(SpaceOutliner *space_outliner)
}
BLI_mempool_destroy(ts);
space_outliner->treestore = new_ts;
- if (space_outliner->treehash) {
+ if (space_outliner->runtime->treehash) {
/* update hash table to fix broken pointers */
- BKE_outliner_treehash_rebuild_from_treestore(space_outliner->treehash,
+ BKE_outliner_treehash_rebuild_from_treestore(space_outliner->runtime->treehash,
space_outliner->treestore);
}
}
}
}
- else if (space_outliner->treehash) {
- BKE_outliner_treehash_clear_used(space_outliner->treehash);
+ else if (space_outliner->runtime->treehash) {
+ BKE_outliner_treehash_clear_used(space_outliner->runtime->treehash);
}
}
}
@@ -174,14 +173,14 @@ static void check_persistent(
space_outliner->treestore = BLI_mempool_create(
sizeof(TreeStoreElem), 1, 512, BLI_MEMPOOL_ALLOW_ITER);
}
- if (space_outliner->treehash == NULL) {
- space_outliner->treehash = BKE_outliner_treehash_create_from_treestore(
+ if (space_outliner->runtime->treehash == NULL) {
+ space_outliner->runtime->treehash = BKE_outliner_treehash_create_from_treestore(
space_outliner->treestore);
}
/* find any unused tree element in treestore and mark it as used
* (note that there may be multiple unused elements in case of linked objects) */
- tselem = BKE_outliner_treehash_lookup_unused(space_outliner->treehash, type, nr, id);
+ tselem = BKE_outliner_treehash_lookup_unused(space_outliner->runtime->treehash, type, nr, id);
if (tselem) {
te->store_elem = tselem;
tselem->used = 1;
@@ -196,7 +195,7 @@ static void check_persistent(
tselem->used = 0;
tselem->flag = TSE_CLOSED;
te->store_elem = tselem;
- BKE_outliner_treehash_add_element(space_outliner->treehash, tselem);
+ BKE_outliner_treehash_add_element(space_outliner->runtime->treehash, tselem);
}
/* ********************************************************* */
@@ -232,6 +231,7 @@ void outliner_free_tree_element(TreeElement *element, ListBase *parent_subtree)
if (element->flag & TE_FREE_NAME) {
MEM_freeN((void *)element->name);
}
+ outliner_tree_element_type_free(&element->type);
MEM_freeN(element);
}
@@ -961,13 +961,18 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
te->parent = parent;
te->index = index; /* For data arrays. */
+
+ /* New C++ based type handle (`TreeElementType` in C, `AbstractTreeElement` in C++). Only some
+ * support this, eventually this should replace `TreeElement` entirely. */
+ te->type = outliner_tree_element_type_create(type, te, idv);
+
if (ELEM(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) {
/* pass */
}
else if (ELEM(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
/* pass */
}
- else if (type == TSE_ANIM_DATA) {
+ else if (ELEM(type, TSE_ANIM_DATA, TSE_NLA, TSE_NLA_TRACK, TSE_DRIVER_BASE)) {
/* pass */
}
else if (type == TSE_GP_LAYER) {
@@ -979,7 +984,13 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
else if (type == TSE_ID_BASE) {
/* pass */
}
+ else if (ELEM(type, TSE_KEYMAP, TSE_KEYMAP_ITEM)) {
+ /* pass */
+ }
else {
+ /* Other cases must be caught above. */
+ BLI_assert(TSE_IS_REAL_ID(tselem));
+
/* do here too, for blend file viewer, own ID_LI then shows file name */
if (GS(id->name) == ID_LI) {
te->name = ((Library *)id)->filepath;
@@ -990,7 +1001,10 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
te->idcode = GS(id->name);
}
- if (type == 0) {
+ if (te->type) {
+ outliner_tree_element_type_expand(te->type, space_outliner);
+ }
+ else if (type == 0) {
TreeStoreElem *tsepar = parent ? TREESTORE(parent) : NULL;
/* ID data-block. */
@@ -998,73 +1012,9 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
outliner_add_id_contents(space_outliner, te, tselem, id);
}
}
- else if (type == TSE_ANIM_DATA) {
- IdAdtTemplate *iat = (IdAdtTemplate *)idv;
- AnimData *adt = (AnimData *)iat->adt;
-
- /* this element's info */
- te->name = IFACE_("Animation");
- te->directdata = adt;
-
- /* Action */
- outliner_add_element(space_outliner, &te->subtree, adt->action, te, 0, 0);
-
- /* Drivers */
- if (adt->drivers.first) {
- TreeElement *ted = outliner_add_element(
- space_outliner, &te->subtree, adt, te, TSE_DRIVER_BASE, 0);
- ID *lastadded = NULL;
- FCurve *fcu;
-
- ted->name = IFACE_("Drivers");
-
- for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
- if (fcu->driver && fcu->driver->variables.first) {
- ChannelDriver *driver = fcu->driver;
- DriverVar *dvar;
-
- for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
- /* loop over all targets used here */
- DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
- if (lastadded != dtar->id) {
- /* XXX this lastadded check is rather lame, and also fails quite badly... */
- outliner_add_element(
- space_outliner, &ted->subtree, dtar->id, ted, TSE_LINKED_OB, 0);
- lastadded = dtar->id;
- }
- }
- DRIVER_TARGETS_LOOPER_END;
- }
- }
- }
- }
-
- /* NLA Data */
- if (adt->nla_tracks.first) {
- TreeElement *tenla = outliner_add_element(space_outliner, &te->subtree, adt, te, TSE_NLA, 0);
- NlaTrack *nlt;
- int a = 0;
-
- tenla->name = IFACE_("NLA Tracks");
-
- for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
- TreeElement *tenlt = outliner_add_element(
- space_outliner, &tenla->subtree, nlt, tenla, TSE_NLA_TRACK, a);
- NlaStrip *strip;
- TreeElement *ten;
- int b = 0;
-
- tenlt->name = nlt->name;
-
- for (strip = nlt->strips.first; strip; strip = strip->next, b++) {
- ten = outliner_add_element(
- space_outliner, &tenlt->subtree, strip->act, tenlt, TSE_NLA_ACTION, b);
- if (ten) {
- ten->directdata = strip;
- }
- }
- }
- }
+ else if (ELEM(type, TSE_ANIM_DATA, TSE_DRIVER_BASE, TSE_NLA, TSE_NLA_ACTION, TSE_NLA_TRACK)) {
+ /* Should already use new AbstractTreeElement design. */
+ BLI_assert(0);
}
else if (type == TSE_GP_LAYER) {
bGPDlayer *gpl = (bGPDlayer *)idv;
@@ -1314,125 +1264,6 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
/* ======================================================= */
-/* Sequencer mode tree building */
-
-/* Helped function to put duplicate sequence in the same tree. */
-static int need_add_seq_dup(Sequence *seq)
-{
- Sequence *p;
-
- if ((!seq->strip) || (!seq->strip->stripdata)) {
- return 1;
- }
-
- /*
- * First check backward, if we found a duplicate
- * sequence before this, don't need it, just return.
- */
- p = seq->prev;
- while (p) {
- if ((!p->strip) || (!p->strip->stripdata)) {
- p = p->prev;
- continue;
- }
-
- if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
- return 2;
- }
- p = p->prev;
- }
-
- p = seq->next;
- while (p) {
- if ((!p->strip) || (!p->strip->stripdata)) {
- p = p->next;
- continue;
- }
-
- if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
- return 0;
- }
- p = p->next;
- }
- return 1;
-}
-
-static void outliner_add_seq_dup(SpaceOutliner *space_outliner,
- Sequence *seq,
- TreeElement *te,
- short index)
-{
- /* TreeElement *ch; */ /* UNUSED */
- Sequence *p;
-
- p = seq;
- while (p) {
- if ((!p->strip) || (!p->strip->stripdata) || (p->strip->stripdata->name[0] == '\0')) {
- p = p->next;
- continue;
- }
-
- if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
- /* ch = */ /* UNUSED */ outliner_add_element(
- space_outliner, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
- }
- p = p->next;
- }
-}
-
-/* ----------------------------------------------- */
-
-static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOutliner *space_outliner)
-{
- TreeElement *ten;
- ListBase *lbarray[MAX_LIBARRAY];
- int a, tot;
- short filter_id_type = (space_outliner->filter & SO_FILTER_ID_TYPE) ?
- space_outliner->filter_id_type :
- 0;
-
- if (filter_id_type) {
- lbarray[0] = which_libbase(mainvar, space_outliner->filter_id_type);
- tot = 1;
- }
- else {
- tot = set_listbasepointers(mainvar, lbarray);
- }
-
- for (a = 0; a < tot; a++) {
- if (lbarray[a] && lbarray[a]->first) {
- ID *id = lbarray[a]->first;
-
- /* check if there are any data-blocks of this type which are orphans */
- for (; id; id = id->next) {
- if (ID_REAL_USERS(id) <= 0) {
- break;
- }
- }
-
- if (id) {
- /* header for this type of data-block */
- if (filter_id_type) {
- ten = NULL;
- }
- else {
- ten = outliner_add_element(
- space_outliner, &space_outliner->tree, lbarray[a], NULL, TSE_ID_BASE, 0);
- ten->directdata = lbarray[a];
- ten->name = outliner_idcode_to_plural(GS(id->name));
- }
-
- /* add the orphaned data-blocks - these will not be added with any subtrees attached */
- for (id = lbarray[a]->first; id; id = id->next) {
- if (ID_REAL_USERS(id) <= 0) {
- outliner_add_element(
- space_outliner, (ten) ? &ten->subtree : &space_outliner->tree, id, ten, 0, 0);
- }
- }
- }
- }
- }
-}
BLI_INLINE void outliner_add_collection_init(TreeElement *te, Collection *collection)
{
@@ -2175,18 +2006,12 @@ static void outliner_filter_tree(SpaceOutliner *space_outliner, ViewLayer *view_
/* Main Tree Building API */
/* Main entry point for building the tree data-structure that the outliner represents. */
-/* TODO: split each mode into its own function? */
void outliner_build_tree(Main *mainvar,
Scene *scene,
ViewLayer *view_layer,
SpaceOutliner *space_outliner,
ARegion *region)
{
- TreeElement *te = NULL, *ten;
- TreeStoreElem *tselem;
- /* on first view, we open scenes */
- int show_opened = !space_outliner->treestore || !BLI_mempool_len(space_outliner->treestore);
-
/* Are we looking for something - we want to tag parents to filter child matches
* - NOT in data-blocks view - searching all data-blocks takes way too long to be useful
* - this variable is only set once per tree build */
@@ -2197,12 +2022,12 @@ void outliner_build_tree(Main *mainvar,
space_outliner->search_flags &= ~SO_SEARCH_RECURSIVE;
}
- if (space_outliner->treehash && (space_outliner->storeflag & SO_TREESTORE_REBUILD) &&
+ if (space_outliner->runtime->treehash && (space_outliner->storeflag & SO_TREESTORE_REBUILD) &&
space_outliner->treestore) {
- space_outliner->storeflag &= ~SO_TREESTORE_REBUILD;
- BKE_outliner_treehash_rebuild_from_treestore(space_outliner->treehash,
+ BKE_outliner_treehash_rebuild_from_treestore(space_outliner->runtime->treehash,
space_outliner->treestore);
}
+ space_outliner->storeflag &= ~SO_TREESTORE_REBUILD;
if (region->do_draw & RGN_DRAW_NO_REBUILD) {
return;
@@ -2217,82 +2042,13 @@ void outliner_build_tree(Main *mainvar,
space_outliner->runtime->tree_display = outliner_tree_display_create(space_outliner->outlinevis,
space_outliner);
- if (space_outliner->runtime->tree_display) {
- TreeSourceData source_data = {.bmain = mainvar, .scene = scene, .view_layer = view_layer};
- space_outliner->tree = outliner_tree_display_build_tree(space_outliner->runtime->tree_display,
- &source_data);
- }
- if (space_outliner->runtime->tree_display) {
- /* Skip if there's a tree-display that's responsible for adding all elements. */
- }
- /* options */
- else if (space_outliner->outlinevis == SO_LIBRARIES) {
- /* Ported to new tree-display, should be built there already. */
- BLI_assert(false);
- }
- else if (space_outliner->outlinevis == SO_SCENES) {
- Scene *sce;
- for (sce = mainvar->scenes.first; sce; sce = sce->id.next) {
- te = outliner_add_element(space_outliner, &space_outliner->tree, sce, NULL, 0, 0);
- tselem = TREESTORE(te);
-
- /* New scene elements open by default */
- if ((sce == scene && show_opened) || !tselem->used) {
- tselem->flag &= ~TSE_CLOSED;
- }
-
- outliner_make_object_parent_hierarchy(&te->subtree);
- }
- }
- else if (space_outliner->outlinevis == SO_SEQUENCE) {
- Sequence *seq;
- Editing *ed = BKE_sequencer_editing_get(scene, false);
- int op;
-
- if (ed == NULL) {
- return;
- }
-
- seq = ed->seqbasep->first;
- if (!seq) {
- return;
- }
-
- while (seq) {
- op = need_add_seq_dup(seq);
- if (op == 1) {
- /* ten = */ outliner_add_element(
- space_outliner, &space_outliner->tree, (void *)seq, NULL, TSE_SEQUENCE, 0);
- }
- else if (op == 0) {
- ten = outliner_add_element(
- space_outliner, &space_outliner->tree, (void *)seq, NULL, TSE_SEQUENCE_DUP, 0);
- outliner_add_seq_dup(space_outliner, seq, ten, 0);
- }
- seq = seq->next;
- }
- }
- else if (space_outliner->outlinevis == SO_DATA_API) {
- PointerRNA mainptr;
+ /* All tree displays should be created as sub-classes of AbstractTreeDisplay. */
+ BLI_assert(space_outliner->runtime->tree_display != NULL);
- RNA_main_pointer_create(mainvar, &mainptr);
-
- ten = outliner_add_element(
- space_outliner, &space_outliner->tree, (void *)&mainptr, NULL, TSE_RNA_STRUCT, -1);
-
- if (show_opened) {
- tselem = TREESTORE(ten);
- tselem->flag &= ~TSE_CLOSED;
- }
- }
- else if (space_outliner->outlinevis == SO_ID_ORPHANS) {
- outliner_add_orphaned_datablocks(mainvar, space_outliner);
- }
- else if (space_outliner->outlinevis == SO_VIEW_LAYER) {
- /* Ported to new tree-display, should be built there already. */
- BLI_assert(false);
- }
+ TreeSourceData source_data = {.bmain = mainvar, .scene = scene, .view_layer = view_layer};
+ space_outliner->tree = outliner_tree_display_build_tree(space_outliner->runtime->tree_display,
+ &source_data);
if ((space_outliner->flag & SO_SKIP_SORT_ALPHA) == 0) {
outliner_sort(&space_outliner->tree);
diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c
index 3328f3169c3..e0d63dfcf81 100644
--- a/source/blender/editors/space_outliner/outliner_utils.c
+++ b/source/blender/editors/space_outliner/outliner_utils.c
@@ -212,7 +212,8 @@ TreeElement *outliner_find_tse(SpaceOutliner *space_outliner, const TreeStoreEle
}
/* check if 'tse' is in treestore */
- tselem = BKE_outliner_treehash_lookup_any(space_outliner->treehash, tse->type, tse->nr, tse->id);
+ tselem = BKE_outliner_treehash_lookup_any(
+ space_outliner->runtime->treehash, tse->type, tse->nr, tse->id);
if (tselem) {
return outliner_find_tree_element(&space_outliner->tree, tselem);
}
@@ -509,7 +510,7 @@ Base *ED_outliner_give_base_under_cursor(bContext *C, const int mval[2])
te = outliner_find_item_at_y(space_outliner, &space_outliner->tree, view_mval[1]);
if (te) {
TreeStoreElem *tselem = TREESTORE(te);
- if (tselem->type == 0) {
+ if ((tselem->type == 0) && (te->idcode == ID_OB)) {
Object *ob = (Object *)tselem->id;
base = (te->directdata) ? (Base *)te->directdata : BKE_view_layer_base_find(view_layer, ob);
}
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 5ec55eee7fb..3d675fdd9e4 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -349,12 +349,12 @@ static void outliner_free(SpaceLink *sl)
if (space_outliner->treestore) {
BLI_mempool_destroy(space_outliner->treestore);
}
- if (space_outliner->treehash) {
- BKE_outliner_treehash_free(space_outliner->treehash);
- }
if (space_outliner->runtime) {
outliner_tree_display_destroy(&space_outliner->runtime->tree_display);
+ if (space_outliner->runtime->treehash) {
+ BKE_outliner_treehash_free(space_outliner->runtime->treehash);
+ }
MEM_freeN(space_outliner->runtime);
}
}
@@ -377,13 +377,13 @@ static SpaceLink *outliner_duplicate(SpaceLink *sl)
BLI_listbase_clear(&space_outliner_new->tree);
space_outliner_new->treestore = NULL;
- space_outliner_new->treehash = NULL;
space_outliner_new->sync_select_dirty = WM_OUTLINER_SYNC_SELECT_FROM_ALL;
if (space_outliner->runtime) {
space_outliner_new->runtime = MEM_dupallocN(space_outliner->runtime);
space_outliner_new->runtime->tree_display = NULL;
+ space_outliner_new->runtime->treehash = NULL;
}
return (SpaceLink *)space_outliner_new;
@@ -414,7 +414,10 @@ static void outliner_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_i
changed = true;
}
}
- if (space_outliner->treehash && changed) {
+
+ /* Note that the Outliner may not be the active editor of the area, and hence not initialized.
+ * So runtime data might not have been created yet. */
+ if (space_outliner->runtime && space_outliner->runtime->treehash && changed) {
/* rebuild hash table, because it depends on ids too */
/* postpone a full rebuild because this can be called many times on-free */
space_outliner->storeflag |= SO_TREESTORE_REBUILD;
@@ -426,7 +429,7 @@ static void outliner_deactivate(struct ScrArea *area)
{
/* Remove hover highlights */
SpaceOutliner *space_outliner = area->spacedata.first;
- outliner_flag_set(&space_outliner->tree, TSE_HIGHLIGHTED, false);
+ outliner_flag_set(&space_outliner->tree, TSE_HIGHLIGHTED_ANY, false);
ED_region_tag_redraw_no_rebuild(BKE_area_find_region_type(area, RGN_TYPE_WINDOW));
}
diff --git a/source/blender/editors/space_outliner/tree/tree_display.cc b/source/blender/editors/space_outliner/tree/tree_display.cc
index 12599733275..d2070fb9b1c 100644
--- a/source/blender/editors/space_outliner/tree/tree_display.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display.cc
@@ -32,13 +32,19 @@ TreeDisplay *outliner_tree_display_create(eSpaceOutliner_Mode mode, SpaceOutline
switch (mode) {
case SO_SCENES:
+ tree_display = new TreeDisplayScenes(*space_outliner);
break;
case SO_LIBRARIES:
tree_display = new TreeDisplayLibraries(*space_outliner);
break;
case SO_SEQUENCE:
+ tree_display = new TreeDisplaySequencer(*space_outliner);
+ break;
case SO_DATA_API:
+ tree_display = new TreeDisplayDataAPI(*space_outliner);
+ break;
case SO_ID_ORPHANS:
+ tree_display = new TreeDisplayIDOrphans(*space_outliner);
break;
case SO_VIEW_LAYER:
tree_display = new TreeDisplayViewLayer(*space_outliner);
diff --git a/source/blender/editors/space_outliner/tree/tree_display.hh b/source/blender/editors/space_outliner/tree/tree_display.hh
index a3d9a626d1d..b6183050e82 100644
--- a/source/blender/editors/space_outliner/tree/tree_display.hh
+++ b/source/blender/editors/space_outliner/tree/tree_display.hh
@@ -110,4 +110,70 @@ class TreeDisplayLibraries final : public AbstractTreeDisplay {
short id_filter_get() const;
};
+/* -------------------------------------------------------------------- */
+/* Video Sequencer Tree-Display */
+
+enum SequenceAddOp {
+ SEQUENCE_DUPLICATE_NOOP = 0,
+ SEQUENCE_DUPLICATE_ADD,
+ SEQUENCE_DUPLICATE_NONE
+};
+
+/**
+ * \brief Tree-Display for the Video Sequencer display mode
+ */
+class TreeDisplaySequencer final : public AbstractTreeDisplay {
+ public:
+ TreeDisplaySequencer(SpaceOutliner &space_outliner);
+
+ ListBase buildTree(const TreeSourceData &source_data) override;
+
+ private:
+ TreeElement *add_sequencer_contents() const;
+ SequenceAddOp need_add_seq_dup(Sequence *seq) const;
+ void add_seq_dup(Sequence *seq, TreeElement *te, short index) const;
+};
+
+/* -------------------------------------------------------------------- */
+/* Orphaned Data Tree-Display */
+
+/**
+ * \brief Tree-Display for the Orphaned Data display mode
+ */
+class TreeDisplayIDOrphans final : public AbstractTreeDisplay {
+ public:
+ TreeDisplayIDOrphans(SpaceOutliner &space_outliner);
+
+ ListBase buildTree(const TreeSourceData &source_data) override;
+
+ private:
+ bool datablock_has_orphans(ListBase &) const;
+};
+
+/* -------------------------------------------------------------------- */
+/* Scenes Tree-Display */
+
+/**
+ * \brief Tree-Display for the Scenes display mode
+ */
+class TreeDisplayScenes final : public AbstractTreeDisplay {
+ public:
+ TreeDisplayScenes(SpaceOutliner &space_outliner);
+
+ ListBase buildTree(const TreeSourceData &source_data) override;
+};
+
+/* -------------------------------------------------------------------- */
+/* Data API Tree-Display */
+
+/**
+ * \brief Tree-Display for the Scenes display mode
+ */
+class TreeDisplayDataAPI final : public AbstractTreeDisplay {
+ public:
+ TreeDisplayDataAPI(SpaceOutliner &space_outliner);
+
+ ListBase buildTree(const TreeSourceData &source_data) override;
+};
+
} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_display_data.cc b/source/blender/editors/space_outliner/tree/tree_display_data.cc
new file mode 100644
index 00000000000..8a5c2e7d9f3
--- /dev/null
+++ b/source/blender/editors/space_outliner/tree/tree_display_data.cc
@@ -0,0 +1,56 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup spoutliner
+ */
+
+#include "BLI_listbase.h"
+#include "BLI_mempool.h"
+
+#include "RNA_access.h"
+
+#include "../outliner_intern.h"
+#include "tree_display.hh"
+
+namespace blender::ed::outliner {
+
+TreeDisplayDataAPI::TreeDisplayDataAPI(SpaceOutliner &space_outliner)
+ : AbstractTreeDisplay(space_outliner)
+{
+}
+
+ListBase TreeDisplayDataAPI::buildTree(const TreeSourceData &source_data)
+{
+ ListBase tree = {nullptr};
+
+ PointerRNA mainptr;
+ RNA_main_pointer_create(source_data.bmain, &mainptr);
+
+ TreeElement *te = outliner_add_element(
+ &space_outliner_, &tree, (void *)&mainptr, nullptr, TSE_RNA_STRUCT, -1);
+
+ /* On first view open parent data elements */
+ const int show_opened = !space_outliner_.treestore ||
+ !BLI_mempool_len(space_outliner_.treestore);
+ if (show_opened) {
+ TreeStoreElem *tselem = TREESTORE(te);
+ tselem->flag &= ~TSE_CLOSED;
+ }
+ return tree;
+}
+
+} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_display_orphaned.cc b/source/blender/editors/space_outliner/tree/tree_display_orphaned.cc
new file mode 100644
index 00000000000..0b17ea98831
--- /dev/null
+++ b/source/blender/editors/space_outliner/tree/tree_display_orphaned.cc
@@ -0,0 +1,97 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup spoutliner
+ */
+
+#include "DNA_ID.h"
+
+#include "BLI_listbase.h"
+#include "BLI_listbase_wrapper.hh"
+#include "BLI_utildefines.h"
+
+#include "BKE_main.h"
+
+#include "../outliner_intern.h"
+#include "tree_display.hh"
+
+namespace blender::ed::outliner {
+
+/* Convenience/readability. */
+template<typename T> using List = ListBaseWrapper<T>;
+
+TreeDisplayIDOrphans::TreeDisplayIDOrphans(SpaceOutliner &space_outliner)
+ : AbstractTreeDisplay(space_outliner)
+{
+}
+
+ListBase TreeDisplayIDOrphans::buildTree(const TreeSourceData &source_data)
+{
+ ListBase tree = {nullptr};
+ ListBase *lbarray[MAX_LIBARRAY];
+ short filter_id_type = (space_outliner_.filter & SO_FILTER_ID_TYPE) ?
+ space_outliner_.filter_id_type :
+ 0;
+
+ int tot;
+ if (filter_id_type) {
+ lbarray[0] = which_libbase(source_data.bmain, filter_id_type);
+ tot = 1;
+ }
+ else {
+ tot = set_listbasepointers(source_data.bmain, lbarray);
+ }
+
+ for (int a = 0; a < tot; a++) {
+ if (BLI_listbase_is_empty(lbarray[a])) {
+ continue;
+ }
+ if (!datablock_has_orphans(*lbarray[a])) {
+ continue;
+ }
+
+ /* Header for this type of data-block. */
+ TreeElement *te = nullptr;
+ if (!filter_id_type) {
+ ID *id = (ID *)lbarray[a]->first;
+ te = outliner_add_element(&space_outliner_, &tree, lbarray[a], nullptr, TSE_ID_BASE, 0);
+ te->directdata = lbarray[a];
+ te->name = outliner_idcode_to_plural(GS(id->name));
+ }
+
+ /* Add the orphaned data-blocks - these will not be added with any subtrees attached. */
+ for (ID *id : List<ID>(lbarray[a])) {
+ if (ID_REAL_USERS(id) <= 0) {
+ outliner_add_element(&space_outliner_, (te) ? &te->subtree : &tree, id, te, 0, 0);
+ }
+ }
+ }
+
+ return tree;
+}
+
+bool TreeDisplayIDOrphans::datablock_has_orphans(ListBase &lb) const
+{
+ for (ID *id : List<ID>(lb)) {
+ if (ID_REAL_USERS(id) <= 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_display_scenes.cc b/source/blender/editors/space_outliner/tree/tree_display_scenes.cc
new file mode 100644
index 00000000000..f377512d81e
--- /dev/null
+++ b/source/blender/editors/space_outliner/tree/tree_display_scenes.cc
@@ -0,0 +1,63 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup spoutliner
+ */
+
+#include "BLI_listbase.h"
+#include "BLI_listbase_wrapper.hh"
+#include "BLI_mempool.h"
+
+#include "BKE_main.h"
+
+#include "../outliner_intern.h"
+#include "tree_display.hh"
+
+namespace blender::ed::outliner {
+
+/* Convenience/readability. */
+template<typename T> using List = ListBaseWrapper<T>;
+
+TreeDisplayScenes::TreeDisplayScenes(SpaceOutliner &space_outliner)
+ : AbstractTreeDisplay(space_outliner)
+{
+}
+
+ListBase TreeDisplayScenes::buildTree(const TreeSourceData &source_data)
+{
+ /* On first view we open scenes. */
+ const int show_opened = !space_outliner_.treestore ||
+ !BLI_mempool_len(space_outliner_.treestore);
+ ListBase tree = {nullptr};
+
+ for (ID *id : List<ID>(source_data.bmain->scenes)) {
+ Scene *scene = reinterpret_cast<Scene *>(id);
+ TreeElement *te = outliner_add_element(&space_outliner_, &tree, scene, nullptr, 0, 0);
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ /* New scene elements open by default */
+ if ((scene == source_data.scene && show_opened) || !tselem->used) {
+ tselem->flag &= ~TSE_CLOSED;
+ }
+
+ outliner_make_object_parent_hierarchy(&te->subtree);
+ }
+
+ return tree;
+}
+
+} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_display_sequencer.cc b/source/blender/editors/space_outliner/tree/tree_display_sequencer.cc
new file mode 100644
index 00000000000..48f0322ccb9
--- /dev/null
+++ b/source/blender/editors/space_outliner/tree/tree_display_sequencer.cc
@@ -0,0 +1,122 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup spoutliner
+ */
+
+#include <cstring>
+
+#include "BLI_listbase.h"
+#include "BLI_listbase_wrapper.hh"
+#include "BLI_utildefines.h"
+
+#include "SEQ_sequencer.h"
+
+#include "../outliner_intern.h"
+#include "tree_display.hh"
+
+namespace blender::ed::outliner {
+
+/* Convenience/readability. */
+template<typename T> using List = ListBaseWrapper<T>;
+
+TreeDisplaySequencer::TreeDisplaySequencer(SpaceOutliner &space_outliner)
+ : AbstractTreeDisplay(space_outliner)
+{
+}
+
+ListBase TreeDisplaySequencer::buildTree(const TreeSourceData &source_data)
+{
+ ListBase tree = {nullptr};
+
+ Editing *ed = BKE_sequencer_editing_get(source_data.scene, false);
+ if (ed == nullptr) {
+ return tree;
+ }
+
+ for (Sequence *seq : List<Sequence>(ed->seqbasep)) {
+ SequenceAddOp op = need_add_seq_dup(seq);
+ if (op == SEQUENCE_DUPLICATE_NONE) {
+ outliner_add_element(&space_outliner_, &tree, seq, nullptr, TSE_SEQUENCE, 0);
+ }
+ else if (op == SEQUENCE_DUPLICATE_ADD) {
+ TreeElement *te = outliner_add_element(
+ &space_outliner_, &tree, seq, nullptr, TSE_SEQUENCE_DUP, 0);
+ add_seq_dup(seq, te, 0);
+ }
+ }
+
+ return tree;
+}
+
+/* Helped function to put duplicate sequence in the same tree. */
+SequenceAddOp TreeDisplaySequencer::need_add_seq_dup(Sequence *seq) const
+{
+ if ((!seq->strip) || (!seq->strip->stripdata)) {
+ return SEQUENCE_DUPLICATE_NONE;
+ }
+
+ /*
+ * First check backward, if we found a duplicate
+ * sequence before this, don't need it, just return.
+ */
+ Sequence *p = seq->prev;
+ while (p) {
+ if ((!p->strip) || (!p->strip->stripdata)) {
+ p = p->prev;
+ continue;
+ }
+
+ if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
+ return SEQUENCE_DUPLICATE_NOOP;
+ }
+ p = p->prev;
+ }
+
+ p = seq->next;
+ while (p) {
+ if ((!p->strip) || (!p->strip->stripdata)) {
+ p = p->next;
+ continue;
+ }
+
+ if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
+ return SEQUENCE_DUPLICATE_ADD;
+ }
+ p = p->next;
+ }
+
+ return SEQUENCE_DUPLICATE_NONE;
+}
+
+void TreeDisplaySequencer::add_seq_dup(Sequence *seq, TreeElement *te, short index) const
+{
+ Sequence *p = seq;
+ while (p) {
+ if ((!p->strip) || (!p->strip->stripdata) || (p->strip->stripdata->name[0] == '\0')) {
+ p = p->next;
+ continue;
+ }
+
+ if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) {
+ outliner_add_element(&space_outliner_, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
+ }
+ p = p->next;
+ }
+}
+
+} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_element.cc b/source/blender/editors/space_outliner/tree/tree_element.cc
new file mode 100644
index 00000000000..ce2a8fa634d
--- /dev/null
+++ b/source/blender/editors/space_outliner/tree/tree_element.cc
@@ -0,0 +1,88 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup spoutliner
+ */
+
+#include "DNA_listBase.h"
+
+#include "../outliner_intern.h"
+
+#include "tree_element_anim_data.hh"
+#include "tree_element_driver_base.hh"
+#include "tree_element_nla.hh"
+
+#include "tree_element.h"
+#include "tree_element.hh"
+
+namespace blender::ed::outliner {
+
+static AbstractTreeElement *tree_element_create(int type, TreeElement &legacy_te, void *idv)
+{
+ /* Would be nice to get rid of void * here, can we somehow expect the right type right away?
+ * Perfect forwarding maybe, once the API is C++ only? */
+ ID &id = *static_cast<ID *>(idv);
+
+ switch (type) {
+ case TSE_ANIM_DATA:
+ return new TreeElementAnimData(legacy_te, id);
+ case TSE_DRIVER_BASE:
+ return new TreeElementDriverBase(legacy_te, *static_cast<AnimData *>(idv));
+ case TSE_NLA:
+ return new TreeElementNLA(legacy_te, *static_cast<AnimData *>(idv));
+ case TSE_NLA_TRACK:
+ return new TreeElementNLATrack(legacy_te, *static_cast<NlaTrack *>(idv));
+ case TSE_NLA_ACTION:
+ return new TreeElementNLAAction(legacy_te);
+ default:
+ break;
+ }
+
+ return nullptr;
+}
+
+static void tree_element_free(AbstractTreeElement **tree_element)
+{
+ delete *tree_element;
+ *tree_element = nullptr;
+}
+
+static void tree_element_expand(AbstractTreeElement &tree_element, SpaceOutliner &space_outliner)
+{
+ tree_element.expand(space_outliner);
+}
+
+} // namespace blender::ed::outliner
+
+namespace outliner = blender::ed::outliner;
+
+TreeElementType *outliner_tree_element_type_create(int type, TreeElement *legacy_te, void *idv)
+{
+ outliner::AbstractTreeElement *element = outliner::tree_element_create(type, *legacy_te, idv);
+ return reinterpret_cast<TreeElementType *>(element);
+}
+
+void outliner_tree_element_type_expand(TreeElementType *type, SpaceOutliner *space_outliner)
+{
+ outliner::tree_element_expand(reinterpret_cast<outliner::AbstractTreeElement &>(*type),
+ *space_outliner);
+}
+
+void outliner_tree_element_type_free(TreeElementType **type)
+{
+ outliner::tree_element_free(reinterpret_cast<outliner::AbstractTreeElement **>(type));
+}
diff --git a/source/blender/editors/space_outliner/tree/tree_element.h b/source/blender/editors/space_outliner/tree/tree_element.h
new file mode 100644
index 00000000000..d88c37180b3
--- /dev/null
+++ b/source/blender/editors/space_outliner/tree/tree_element.h
@@ -0,0 +1,45 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup spoutliner
+ *
+ * C-API for the Tree-Element types.
+ * This API shouldn't stay for long. All tree building should eventually be done through C++ types,
+ * with more type safety and an easier to reason about design.
+ */
+
+#pragma once
+
+#include "DNA_space_types.h"
+
+struct TreeElement;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** C alias for an #AbstractTreeElement handle. */
+typedef struct TreeElementType TreeElementType;
+
+TreeElementType *outliner_tree_element_type_create(int type, TreeElement *legacy_te, void *idv);
+void outliner_tree_element_type_free(TreeElementType **type);
+
+void outliner_tree_element_type_expand(TreeElementType *type, SpaceOutliner *space_outliner);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/editors/space_outliner/tree/tree_element.hh b/source/blender/editors/space_outliner/tree/tree_element.hh
new file mode 100644
index 00000000000..8a1ebb51eae
--- /dev/null
+++ b/source/blender/editors/space_outliner/tree/tree_element.hh
@@ -0,0 +1,53 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup spoutliner
+ */
+
+#pragma once
+
+#include "tree_element.h"
+
+namespace blender::ed::outliner {
+
+/* -------------------------------------------------------------------- */
+/* Tree-Display Interface */
+
+class AbstractTreeElement {
+ protected:
+ /**
+ * Reference back to the owning legacy TreeElement.
+ * Most concrete types need access to this, so storing here. Eventually the type should be
+ * replaced by AbstractTreeElement and derived types.
+ */
+ TreeElement &legacy_te_;
+
+ public:
+ AbstractTreeElement(TreeElement &legacy_te) : legacy_te_(legacy_te)
+ {
+ }
+ virtual ~AbstractTreeElement() = default;
+
+ /**
+ * Let the type add its own children.
+ */
+ virtual void expand(SpaceOutliner &) const
+ {
+ }
+};
+
+} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_element_anim_data.cc b/source/blender/editors/space_outliner/tree/tree_element_anim_data.cc
new file mode 100644
index 00000000000..13a25800800
--- /dev/null
+++ b/source/blender/editors/space_outliner/tree/tree_element_anim_data.cc
@@ -0,0 +1,70 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup spoutliner
+ */
+
+#include "BLI_listbase_wrapper.hh"
+
+#include "DNA_anim_types.h"
+#include "DNA_listBase.h"
+
+#include "BLT_translation.h"
+
+#include "../outliner_intern.h"
+#include "tree_display.h"
+
+#include "tree_element_anim_data.hh"
+
+namespace blender::ed::outliner {
+
+TreeElementAnimData::TreeElementAnimData(TreeElement &legacy_te, ID &id)
+ : AbstractTreeElement(legacy_te), anim_data_(*reinterpret_cast<IdAdtTemplate &>(id).adt)
+{
+ BLI_assert(legacy_te.store_elem->type == TSE_ANIM_DATA);
+ /* this element's info */
+ legacy_te.name = IFACE_("Animation");
+ legacy_te.directdata = &anim_data_;
+}
+
+void TreeElementAnimData::expand(SpaceOutliner &space_outliner) const
+{
+ /* Animation data-block itself. */
+ outliner_add_element(&space_outliner, &legacy_te_.subtree, anim_data_.action, &legacy_te_, 0, 0);
+
+ expand_drivers(space_outliner);
+ expand_NLA_tracks(space_outliner);
+}
+
+void TreeElementAnimData::expand_drivers(SpaceOutliner &space_outliner) const
+{
+ if (BLI_listbase_is_empty(&anim_data_.drivers)) {
+ return;
+ }
+ outliner_add_element(
+ &space_outliner, &legacy_te_.subtree, &anim_data_, &legacy_te_, TSE_DRIVER_BASE, 0);
+}
+
+void TreeElementAnimData::expand_NLA_tracks(SpaceOutliner &space_outliner) const
+{
+ if (BLI_listbase_is_empty(&anim_data_.nla_tracks)) {
+ return;
+ }
+ outliner_add_element(&space_outliner, &legacy_te_.subtree, &anim_data_, &legacy_te_, TSE_NLA, 0);
+}
+
+} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_element_anim_data.hh b/source/blender/editors/space_outliner/tree/tree_element_anim_data.hh
new file mode 100644
index 00000000000..8114277b6d6
--- /dev/null
+++ b/source/blender/editors/space_outliner/tree/tree_element_anim_data.hh
@@ -0,0 +1,42 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup spoutliner
+ */
+
+#pragma once
+
+#include "tree_element.hh"
+
+struct TreeElement;
+
+namespace blender::ed::outliner {
+
+class TreeElementAnimData final : public AbstractTreeElement {
+ AnimData &anim_data_;
+
+ public:
+ TreeElementAnimData(TreeElement &legacy_te, ID &id);
+
+ void expand(SpaceOutliner &space_outliner) const override;
+
+ private:
+ void expand_drivers(SpaceOutliner &space_outliner) const;
+ void expand_NLA_tracks(SpaceOutliner &space_outliner) const;
+};
+
+} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_element_driver_base.cc b/source/blender/editors/space_outliner/tree/tree_element_driver_base.cc
new file mode 100644
index 00000000000..a01a3c42531
--- /dev/null
+++ b/source/blender/editors/space_outliner/tree/tree_element_driver_base.cc
@@ -0,0 +1,68 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup spoutliner
+ */
+
+#include "BLI_listbase_wrapper.hh"
+
+#include "BKE_fcurve_driver.h"
+
+#include "DNA_anim_types.h"
+#include "DNA_listBase.h"
+
+#include "BLT_translation.h"
+
+#include "../outliner_intern.h"
+#include "tree_display.h"
+
+#include "tree_element_driver_base.hh"
+
+namespace blender::ed::outliner {
+
+TreeElementDriverBase::TreeElementDriverBase(TreeElement &legacy_te, AnimData &anim_data)
+ : AbstractTreeElement(legacy_te), anim_data_(anim_data)
+{
+ BLI_assert(legacy_te.store_elem->type == TSE_DRIVER_BASE);
+ legacy_te.name = IFACE_("Drivers");
+}
+
+void TreeElementDriverBase::expand(SpaceOutliner &space_outliner) const
+{
+ ID *lastadded = nullptr;
+
+ for (FCurve *fcu : blender::ListBaseWrapper<FCurve>(anim_data_.drivers)) {
+ if (fcu->driver && fcu->driver->variables.first) {
+ ChannelDriver *driver = fcu->driver;
+
+ for (DriverVar *dvar : blender::ListBaseWrapper<DriverVar>(driver->variables)) {
+ /* loop over all targets used here */
+ DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
+ if (lastadded != dtar->id) {
+ /* XXX this lastadded check is rather lame, and also fails quite badly... */
+ outliner_add_element(
+ &space_outliner, &legacy_te_.subtree, dtar->id, &legacy_te_, TSE_LINKED_OB, 0);
+ lastadded = dtar->id;
+ }
+ }
+ DRIVER_TARGETS_LOOPER_END;
+ }
+ }
+ }
+}
+
+} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_element_driver_base.hh b/source/blender/editors/space_outliner/tree/tree_element_driver_base.hh
new file mode 100644
index 00000000000..1925e3570be
--- /dev/null
+++ b/source/blender/editors/space_outliner/tree/tree_element_driver_base.hh
@@ -0,0 +1,38 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup spoutliner
+ */
+
+#pragma once
+
+#include "tree_element.hh"
+
+struct TreeElement;
+
+namespace blender::ed::outliner {
+
+class TreeElementDriverBase final : public AbstractTreeElement {
+ AnimData &anim_data_;
+
+ public:
+ TreeElementDriverBase(TreeElement &legacy_te, AnimData &anim_data);
+
+ void expand(SpaceOutliner &space_outliner) const override;
+};
+
+} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_element_nla.cc b/source/blender/editors/space_outliner/tree/tree_element_nla.cc
new file mode 100644
index 00000000000..5d4ec53e60c
--- /dev/null
+++ b/source/blender/editors/space_outliner/tree/tree_element_nla.cc
@@ -0,0 +1,78 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup spoutliner
+ */
+
+#include "BLI_listbase_wrapper.hh"
+
+#include "DNA_anim_types.h"
+#include "DNA_listBase.h"
+
+#include "BLT_translation.h"
+
+#include "../outliner_intern.h"
+#include "tree_display.h"
+
+#include "tree_element_nla.hh"
+
+namespace blender::ed::outliner {
+
+TreeElementNLA::TreeElementNLA(TreeElement &legacy_te, AnimData &anim_data)
+ : AbstractTreeElement(legacy_te), anim_data_(anim_data)
+{
+ BLI_assert(legacy_te.store_elem->type == TSE_NLA);
+ legacy_te.name = IFACE_("NLA Tracks");
+ legacy_te.directdata = &anim_data;
+}
+
+void TreeElementNLA::expand(SpaceOutliner &space_outliner) const
+{
+ int a = 0;
+ for (NlaTrack *nlt : ListBaseWrapper<NlaTrack>(anim_data_.nla_tracks)) {
+ outliner_add_element(&space_outliner, &legacy_te_.subtree, nlt, &legacy_te_, TSE_NLA_TRACK, a);
+ a++;
+ }
+}
+
+/* -------------------------------------------------------------------- */
+
+TreeElementNLATrack::TreeElementNLATrack(TreeElement &legacy_te, NlaTrack &track)
+ : AbstractTreeElement(legacy_te), track_(track)
+{
+ BLI_assert(legacy_te.store_elem->type == TSE_NLA_TRACK);
+ legacy_te.name = track.name;
+}
+
+void TreeElementNLATrack::expand(SpaceOutliner &space_outliner) const
+{
+ int a = 0;
+ for (NlaStrip *strip : ListBaseWrapper<NlaStrip>(track_.strips)) {
+ outliner_add_element(
+ &space_outliner, &legacy_te_.subtree, strip->act, &legacy_te_, TSE_NLA_ACTION, a);
+ a++;
+ }
+}
+
+/* -------------------------------------------------------------------- */
+
+TreeElementNLAAction::TreeElementNLAAction(TreeElement &legacy_te) : AbstractTreeElement(legacy_te)
+{
+ BLI_assert(legacy_te.store_elem->type == TSE_NLA_ACTION);
+}
+
+} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_element_nla.hh b/source/blender/editors/space_outliner/tree/tree_element_nla.hh
new file mode 100644
index 00000000000..3ca62b13bd8
--- /dev/null
+++ b/source/blender/editors/space_outliner/tree/tree_element_nla.hh
@@ -0,0 +1,53 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup spoutliner
+ */
+
+#pragma once
+
+#include "tree_element.hh"
+
+struct NlaTrack;
+struct NlaStrip;
+
+namespace blender::ed::outliner {
+
+class TreeElementNLA final : public AbstractTreeElement {
+ AnimData &anim_data_;
+
+ public:
+ TreeElementNLA(TreeElement &legacy_te, AnimData &anim_data);
+
+ void expand(SpaceOutliner &space_outliner) const override;
+};
+
+class TreeElementNLATrack final : public AbstractTreeElement {
+ NlaTrack &track_;
+
+ public:
+ TreeElementNLATrack(TreeElement &legacy_te, NlaTrack &track);
+
+ void expand(SpaceOutliner &space_outliner) const override;
+};
+
+class TreeElementNLAAction final : public AbstractTreeElement {
+ public:
+ TreeElementNLAAction(TreeElement &legacy_te);
+};
+
+} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 2c9ea1d6afa..849766851aa 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -886,7 +886,7 @@ static void calc_text_rcts(SpaceText *st, ARegion *region, rcti *scroll, rcti *b
scroll->ymin = pix_top_margin;
scroll->ymax = pix_available;
- /* when re-sizing a view-port with the bar at the bottom to a greater height
+ /* when re-sizing a 2D Viewport with the bar at the bottom to a greater height
* more blank lines will be added */
if (ltexth + blank_lines < st->top + st->runtime.viewlines) {
blank_lines = st->top + st->runtime.viewlines - ltexth;
diff --git a/source/blender/editors/space_text/text_header.c b/source/blender/editors/space_text/text_header.c
index c583634f440..84b7a6f6831 100644
--- a/source/blender/editors/space_text/text_header.c
+++ b/source/blender/editors/space_text/text_header.c
@@ -108,101 +108,3 @@ void TEXT_OT_start_find(wmOperatorType *ot)
ot->exec = text_text_search_exec;
ot->poll = text_properties_poll;
}
-
-/******************** XXX popup menus *******************/
-
-#if 0
-{
- /* RMB */
-
- uiPopupMenu *pup;
-
- if (text) {
- pup = UI_popup_menu_begin(C, IFACE_("Text"), ICON_NONE);
- if (txt_has_sel(text)) {
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_cut");
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_copy");
- }
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_paste");
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_new");
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_open");
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_save");
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_save_as");
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_run_script");
- UI_popup_menu_end(C, pup);
- }
- else {
- pup = UI_popup_menu_begin(C, IFACE_("File"), ICON_NONE);
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_new");
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_open");
- UI_popup_menu_end(C, pup);
- }
-}
-
-{
- /* Alt+Shift+E */
-
- uiPopupMenu *pup;
-
- pup = UI_popup_menu_begin(C, IFACE_("Edit"), ICON_NONE);
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_cut");
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_copy");
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_paste");
- UI_popup_menu_end(C, pup);
-}
-
-{
- /* Alt+Shift+F */
-
- uiPopupMenu *pup;
-
- if (text) {
- pup = UI_popup_menu_begin(C, IFACE_("Text"), ICON_NONE);
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_new");
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_open");
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_save");
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_save_as");
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_run_script");
- UI_popup_menu_end(C, pup);
- }
- else {
- pup = UI_popup_menu_begin(C, IFACE_("File"), ICON_NONE);
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_new");
- uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_open");
- UI_popup_menu_end(C, pup);
- }
-}
-
-{
- /* Alt+Shift+V */
-
- uiPopupMenu *pup;
-
- pup = UI_popup_menu_begin(C, IFACE_("Text"), ICON_NONE);
- uiItemEnumO(layout,
- "TEXT_OT_move",
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Top of File"),
- 0,
- "type",
- FILE_TOP);
- uiItemEnumO(layout,
- "TEXT_OT_move",
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Bottom of File"),
- 0,
- "type",
- FILE_BOTTOM);
- uiItemEnumO(layout,
- "TEXT_OT_move",
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Page Up"),
- 0,
- "type",
- PREV_PAGE);
- uiItemEnumO(layout,
- "TEXT_OT_move",
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Page Down"),
- 0,
- "type",
- NEXT_PAGE);
- UI_popup_menu_end(C, pup);
-}
-#endif
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 3b5dc3f57b9..797c7d73df3 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -848,7 +848,7 @@ void ED_view3d_draw_depth(Depsgraph *depsgraph, ARegion *region, View3D *v3d, bo
/* get surface depth without bias */
rv3d->rflag |= RV3D_ZOFFSET_DISABLED;
- /* Needed in cases the view-port isn't already setup. */
+ /* Needed in cases the 3D Viewport isn't already setup. */
WM_draw_region_viewport_ensure(region, SPACE_VIEW3D);
WM_draw_region_viewport_bind(region);
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index f9de462813f..9429da342a6 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -222,7 +222,7 @@ typedef struct ViewOpsData {
/** Current state. */
struct {
/** Working copy of #RegionView3D.viewquat, needed for rotation calculation
- * so we can apply snap to the view-port while keeping the unsnapped rotation
+ * so we can apply snap to the 3D Viewport while keeping the unsnapped rotation
* here to use when snap is disabled and for continued calculation. */
float viewquat[4];
} curr;
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
index fdba74ed3a6..9b0ce27b1e3 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
@@ -315,8 +315,6 @@ static bool view3d_ruler_item_mousemove(struct Depsgraph *depsgraph,
const float eps_bias = 0.0002f;
float dist_px = MVAL_MAX_PX_DIST * U.pixelsize; /* snap dist */
- WM_gizmo_set_flag(snap_gizmo, WM_GIZMO_HIDDEN, true);
-
if (ruler_item) {
RulerInteraction *inter = ruler_item->gz.interaction_data;
float *co = ruler_item->co[inter->co_index];
@@ -388,12 +386,8 @@ static bool view3d_ruler_item_mousemove(struct Depsgraph *depsgraph,
snap_gizmo->ptr, ruler_info->snap_data.prop_prevpoint, prev_point);
}
- short snap_elem = ED_gizmotypes_snap_3d_update(
+ ED_gizmotypes_snap_3d_update(
snap_gizmo, depsgraph, ruler_info->region, v3d, ruler_info->wm, mval_fl, co, NULL);
-
- if (snap_elem) {
- WM_gizmo_set_flag(snap_gizmo, WM_GIZMO_HIDDEN, false);
- }
}
return true;
}
@@ -1074,7 +1068,6 @@ static void gizmo_ruler_exit(bContext *C, wmGizmo *gz, const bool cancel)
if (!cancel) {
if (ruler_info->state == RULER_STATE_DRAG) {
- WM_gizmo_set_flag(ruler_info->snap_data.gizmo, WM_GIZMO_HIDDEN, false);
RNA_property_unset(ruler_info->snap_data.gizmo->ptr, ruler_info->snap_data.prop_prevpoint);
ruler_state_set(ruler_info, RULER_STATE_NORMAL);
}
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 0815850d694..118ec2425fc 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -171,7 +171,7 @@ bool ED_view3d_boundbox_clip_ex(const RegionView3D *rv3d,
bool ED_view3d_boundbox_clip(RegionView3D *rv3d, const struct BoundBox *bb);
/**
- * Parameters for setting the new view-port state.
+ * Parameters for setting the new 3D Viewport state.
*
* Each of the struct members may be NULL to signify they aren't to be adjusted.
*/
diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c
index 6d10aa5f957..bd71a768c0f 100644
--- a/source/blender/editors/space_view3d/view3d_placement.c
+++ b/source/blender/editors/space_view3d/view3d_placement.c
@@ -72,7 +72,7 @@ static void preview_plane_cursor_visible_set(wmGizmoGroup *gzgroup, bool do_draw
* In this case we can't usefully project the mouse cursor onto the plane,
* so use a fall-back plane instead.
*/
-const float eps_view_align = 1e-2f;
+static const float eps_view_align = 1e-2f;
/* -------------------------------------------------------------------- */
/** \name Local Types
@@ -1357,7 +1357,6 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
const float mval_fl[2] = {UNPACK2(event->mval)};
/* Calculate the snap location on mouse-move or when toggling snap. */
- bool is_snap_found_prev = ipd->is_snap_found;
ipd->is_snap_found = false;
if (ipd->use_snap) {
if (ipd->snap_gizmo != NULL) {
@@ -1366,7 +1365,7 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
CTX_data_ensure_evaluated_depsgraph(C),
ipd->region,
ipd->v3d,
- NULL,
+ G_MAIN->wm.first,
mval_fl,
ipd->snap_co,
NULL)) {
@@ -1376,12 +1375,6 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
}
}
- /* Workaround because test_select doesn't run at the same time as the modal operator. */
- if (is_snap_found_prev != ipd->is_snap_found) {
- wmGizmoMap *gzmap = ipd->region->gizmo_map;
- WM_gizmo_highlight_set(gzmap, ipd->is_snap_found ? ipd->snap_gizmo : NULL);
- }
-
if (ipd->step_index == STEP_BASE) {
if (ipd->is_snap_found) {
closest_to_plane_normalized_v3(
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index a70e74665c5..1be9bd27c7a 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -574,11 +574,11 @@ bool ED_view3d_persp_ensure(const Depsgraph *depsgraph, View3D *v3d, ARegion *re
/* -------------------------------------------------------------------- */
/** \name Camera Lock API
*
- * Lock the camera to the view-port, allowing view manipulation to transform the camera.
+ * Lock the camera to the 3D Viewport, allowing view manipulation to transform the camera.
* \{ */
/**
- * \return true when the view-port is locked to its camera.
+ * \return true when the 3D Viewport is locked to its camera.
*/
bool ED_view3d_camera_lock_check(const View3D *v3d, const RegionView3D *rv3d)
{
@@ -587,8 +587,8 @@ bool ED_view3d_camera_lock_check(const View3D *v3d, const RegionView3D *rv3d)
}
/**
- * Apply the camera object transformation to the view-port.
- * (needed so we can use regular view-port manipulation operators, that sync back to the camera).
+ * Apply the camera object transformation to the 3D Viewport.
+ * (needed so we can use regular 3D Viewport manipulation operators, that sync back to the camera).
*/
void ED_view3d_camera_lock_init_ex(const Depsgraph *depsgraph,
View3D *v3d,
@@ -612,7 +612,7 @@ void ED_view3d_camera_lock_init(const Depsgraph *depsgraph, View3D *v3d, RegionV
}
/**
- * Apply the view-port transformation back to the camera object.
+ * Apply the 3D Viewport transformation back to the camera object.
*
* \return true if the camera is moved.
*/
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 356ad8643f8..2b56b30be90 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -599,7 +599,8 @@ static bool transform_modal_item_poll(const wmOperator *op, int value)
case TFM_MODAL_AXIS_Z:
case TFM_MODAL_PLANE_X:
case TFM_MODAL_PLANE_Y:
- case TFM_MODAL_PLANE_Z: {
+ case TFM_MODAL_PLANE_Z:
+ case TFM_MODAL_AUTOCONSTRAINTPLANE: {
if (t->flag & T_NO_CONSTRAINT) {
return false;
}
@@ -636,6 +637,14 @@ static bool transform_modal_item_poll(const wmOperator *op, int value)
}
break;
}
+ case TFM_MODAL_TRANSLATE:
+ case TFM_MODAL_ROTATE:
+ case TFM_MODAL_RESIZE: {
+ if (!transform_mode_is_changeable(t->mode)) {
+ return false;
+ }
+ break;
+ }
}
return true;
}
@@ -713,55 +722,67 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
return keymap;
}
-static void transform_event_xyz_constraint(TransInfo *t, short key_type, bool is_plane)
+static bool transform_event_modal_constraint(TransInfo *t, short modal_type)
{
if (!(t->flag & T_NO_CONSTRAINT)) {
- char cmode = constraintModeToChar(t);
- int constraint_axis, constraint_plane;
- const bool edit_2d = (t->flag & T_2D_EDIT) != 0;
- const char *msg1 = "", *msg2 = "", *msg3 = "";
- char axis;
+ if (t->flag & T_2D_EDIT && ELEM(modal_type, TFM_MODAL_AXIS_Z, TFM_MODAL_PLANE_Z)) {
+ return false;
+ }
+ int constraint_curr = (t->con.mode & CON_APPLY) ?
+ t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2) :
+ -1;
+ int constraint_new;
+ const char *msg_2d = "", *msg_3d = "";
/* Initialize */
- switch (key_type) {
- case EVT_XKEY:
- msg1 = TIP_("along X");
- msg2 = TIP_("along %s X");
- msg3 = TIP_("locking %s X");
- axis = 'X';
- constraint_axis = CON_AXIS0;
+ switch (modal_type) {
+ case TFM_MODAL_AXIS_X:
+ msg_2d = TIP_("along X");
+ msg_3d = TIP_("along %s X");
+ constraint_new = CON_AXIS0;
+ break;
+ case TFM_MODAL_AXIS_Y:
+ msg_2d = TIP_("along Y");
+ msg_3d = TIP_("along %s Y");
+ constraint_new = CON_AXIS1;
+ break;
+ case TFM_MODAL_AXIS_Z:
+ msg_2d = TIP_("along Z");
+ msg_3d = TIP_("along %s Z");
+ constraint_new = CON_AXIS2;
break;
- case EVT_YKEY:
- msg1 = TIP_("along Y");
- msg2 = TIP_("along %s Y");
- msg3 = TIP_("locking %s Y");
- axis = 'Y';
- constraint_axis = CON_AXIS1;
+ case TFM_MODAL_PLANE_X:
+ msg_3d = TIP_("locking %s X");
+ constraint_new = CON_AXIS1 | CON_AXIS2;
break;
- case EVT_ZKEY:
- msg1 = TIP_("along Z");
- msg2 = TIP_("along %s Z");
- msg3 = TIP_("locking %s Z");
- axis = 'Z';
- constraint_axis = CON_AXIS2;
+ case TFM_MODAL_PLANE_Y:
+ msg_3d = TIP_("locking %s Y");
+ constraint_new = CON_AXIS0 | CON_AXIS2;
+ break;
+ case TFM_MODAL_PLANE_Z:
+ msg_3d = TIP_("locking %s Z");
+ constraint_new = CON_AXIS0 | CON_AXIS1;
break;
default:
/* Invalid key */
- return;
+ return false;
}
- constraint_plane = ((CON_AXIS0 | CON_AXIS1 | CON_AXIS2) & (~constraint_axis));
- if (edit_2d && (key_type != EVT_ZKEY)) {
- if (cmode == axis) {
+ if (t->flag & T_2D_EDIT) {
+ BLI_assert(modal_type < TFM_MODAL_PLANE_X);
+ if (constraint_new == CON_AXIS2) {
+ return false;
+ }
+ if (constraint_curr == constraint_new) {
stopConstraint(t);
}
else {
- setUserConstraint(t, constraint_axis, msg1);
+ setUserConstraint(t, constraint_new, msg_2d);
}
}
- else if (!edit_2d) {
+ else {
short orient_index = 1;
- if (t->orient_curr == 0 || ELEM(cmode, '\0', axis)) {
+ if (t->orient_curr == 0 || ELEM(constraint_curr, -1, constraint_new)) {
/* Successive presses on existing axis, cycle orientation modes. */
orient_index = (short)((t->orient_curr + 1) % (int)ARRAY_SIZE(t->orient));
}
@@ -771,16 +792,13 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, bool is
stopConstraint(t);
}
else {
- if (is_plane == false) {
- setUserConstraint(t, constraint_axis, msg2);
- }
- else {
- setUserConstraint(t, constraint_plane, msg3);
- }
+ setUserConstraint(t, constraint_new, msg_3d);
}
}
t->redraw |= TREDRAW_HARD;
+ return true;
}
+ return false;
}
int transformEvent(TransInfo *t, const wmEvent *event)
@@ -818,15 +836,9 @@ int transformEvent(TransInfo *t, const wmEvent *event)
t->redraw |= handleSnapping(t, event);
handled = true;
}
- else if (event->val == t->release_confirm_event_val &&
- event->type == t->release_confirm_event_type) {
- /* Confirm transform if launch key is released after mouse move. */
- BLI_assert(t->flag & T_RELEASE_CONFIRM);
- t->state = TRANS_CONFIRM;
- }
+ /* handle modal keymap first */
+ /* enforce redraw of transform when modifiers are used */
else if (event->type == EVT_MODAL_MAP) {
- /* Handle modal keymap first. */
- /* Enforce redraw of transform when modifiers are used */
switch (event->val) {
case TFM_MODAL_CANCEL:
t->state = TRANS_CANCEL;
@@ -872,11 +884,6 @@ int transformEvent(TransInfo *t, const wmEvent *event)
handled = true;
}
}
- else if (t->mode == TFM_SEQ_SLIDE) {
- t->flag ^= T_ALT_TRANSFORM;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
else if (transform_mode_is_changeable(t->mode)) {
restoreTransObjects(t);
resetTransModal(t);
@@ -918,11 +925,6 @@ int transformEvent(TransInfo *t, const wmEvent *event)
handled = true;
}
}
- else if (t->mode == TFM_SHRINKFATTEN) {
- t->flag ^= T_ALT_TRANSFORM;
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
else if (transform_mode_is_changeable(t->mode)) {
/* Scale isn't normally very useful after extrude along normals, see T39756 */
if ((t->con.mode & CON_APPLY) && (t->orient[t->orient_curr].type == V3D_ORIENT_NORMAL)) {
@@ -955,44 +957,12 @@ int transformEvent(TransInfo *t, const wmEvent *event)
handled = true;
break;
case TFM_MODAL_AXIS_X:
- if (!(t->flag & T_NO_CONSTRAINT)) {
- transform_event_xyz_constraint(t, EVT_XKEY, false);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
case TFM_MODAL_AXIS_Y:
- if ((t->flag & T_NO_CONSTRAINT) == 0) {
- transform_event_xyz_constraint(t, EVT_YKEY, false);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
case TFM_MODAL_AXIS_Z:
- if ((t->flag & (T_NO_CONSTRAINT)) == 0) {
- transform_event_xyz_constraint(t, EVT_ZKEY, false);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
case TFM_MODAL_PLANE_X:
- if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
- transform_event_xyz_constraint(t, EVT_XKEY, true);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
case TFM_MODAL_PLANE_Y:
- if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
- transform_event_xyz_constraint(t, EVT_YKEY, true);
- t->redraw |= TREDRAW_HARD;
- handled = true;
- }
- break;
case TFM_MODAL_PLANE_Z:
- if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
- transform_event_xyz_constraint(t, EVT_ZKEY, true);
- t->redraw |= TREDRAW_HARD;
+ if (transform_event_modal_constraint(t, event->val)) {
handled = true;
}
break;
@@ -1088,7 +1058,12 @@ int transformEvent(TransInfo *t, const wmEvent *event)
break;
case TFM_MODAL_AUTOCONSTRAINT:
case TFM_MODAL_AUTOCONSTRAINTPLANE:
- if ((t->flag & T_NO_CONSTRAINT) == 0) {
+ if ((t->flag & T_RELEASE_CONFIRM) && (event->prevval == KM_RELEASE) &&
+ event->prevtype == t->launch_event) {
+ /* Confirm transform if launch key is released after mouse move. */
+ t->state = TRANS_CONFIRM;
+ }
+ else if ((t->flag & T_NO_CONSTRAINT) == 0) {
if (t->modifiers & (MOD_CONSTRAINT_SELECT | MOD_CONSTRAINT_PLANE)) {
/* Confirm. */
postSelectConstraint(t);
@@ -1128,8 +1103,8 @@ int transformEvent(TransInfo *t, const wmEvent *event)
break;
}
}
+ /* Else do non-mapped events. */
else if (event->val == KM_PRESS) {
- /* Do non-mapped events. */
switch (event->type) {
case EVT_CKEY:
if (event->is_repeat) {
@@ -1217,6 +1192,11 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
break;
}
+
+ /* confirm transform if launch key is released after mouse move */
+ if ((t->flag & T_RELEASE_CONFIRM) && event->type == t->launch_event) {
+ t->state = TRANS_CONFIRM;
+ }
}
/* if we change snap options, get the unsnapped values back */
@@ -1688,6 +1668,17 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->mode = mode;
+ /* Needed to translate tweak events to mouse buttons. */
+ t->launch_event = event ? WM_userdef_event_type_from_keymap_type(event->type) : -1;
+ t->is_launch_event_tweak = event ? ISTWEAK(event->type) : false;
+
+ /* XXX Remove this when wm_operator_call_internal doesn't use window->eventstate
+ * (which can have type = 0) */
+ /* For gizmo only, so assume LEFTMOUSE. */
+ if (t->launch_event == 0) {
+ t->launch_event = LEFTMOUSE;
+ }
+
unit_m3(t->spacemtx);
initTransInfo(C, t, op, event);
@@ -1761,6 +1752,37 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
}
}
+ if (event) {
+ /* keymap for shortcut header prints */
+ t->keymap = WM_keymap_active(CTX_wm_manager(C), op->type->modalkeymap);
+
+ /* Stupid code to have Ctrl-Click on gizmo work ok.
+ *
+ * Do this only for translation/rotation/resize because only these
+ * modes are available from gizmo and doing such check could
+ * lead to keymap conflicts for other modes (see T31584)
+ */
+ if (ELEM(mode, TFM_TRANSLATION, TFM_ROTATION, TFM_RESIZE)) {
+ wmKeyMapItem *kmi;
+
+ for (kmi = t->keymap->items.first; kmi; kmi = kmi->next) {
+ if (kmi->flag & KMI_INACTIVE) {
+ continue;
+ }
+
+ if (kmi->propvalue == TFM_MODAL_SNAP_INV_ON && kmi->val == KM_PRESS) {
+ if ((ELEM(kmi->type, EVT_LEFTCTRLKEY, EVT_RIGHTCTRLKEY) && event->ctrl) ||
+ (ELEM(kmi->type, EVT_LEFTSHIFTKEY, EVT_RIGHTSHIFTKEY) && event->shift) ||
+ (ELEM(kmi->type, EVT_LEFTALTKEY, EVT_RIGHTALTKEY) && event->alt) ||
+ ((kmi->type == EVT_OSKEY) && event->oskey)) {
+ t->modifiers |= MOD_SNAP_INVERT;
+ }
+ break;
+ }
+ }
+ }
+ }
+
initSnapping(t, op); /* Initialize snapping data AFTER mode flags */
initSnapSpatial(t, t->snap_spatial);
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 485d5282a62..227330e8524 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -351,8 +351,7 @@ typedef struct TransInfo {
/*************** NEW STUFF *********************/
/** event type used to launch transform. */
- short release_confirm_event_type;
- short release_confirm_event_val;
+ short launch_event;
/** Is the actual launch event a tweak event? (launch_event above is set to the corresponding
* mouse button then.) */
bool is_launch_event_tweak;
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 5e2a8be8db0..54533bf43e5 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -1127,16 +1127,6 @@ int constraintModeToIndex(const TransInfo *t)
}
}
-char constraintModeToChar(const TransInfo *t)
-{
- int index = constraintModeToIndex(t);
- if (index == -1) {
- return '\0';
- }
- BLI_assert((uint)index < 3);
- return 'X' + index;
-}
-
bool isLockConstraint(TransInfo *t)
{
int mode = t->con.mode;
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index c23ee5b771c..c81c954bd0a 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -1438,7 +1438,7 @@ void animrecord_check_state(TransInfo *t, struct Object *ob)
/* only push down if action is more than 1-2 frames long */
calc_action_range(adt->action, &astart, &aend, 1);
if (aend > astart + 2.0f) {
- NlaStrip *strip = BKE_nlastack_add_strip(adt, adt->action);
+ NlaStrip *strip = BKE_nlastack_add_strip(adt, adt->action, ID_IS_OVERRIDE_LIBRARY(id));
/* clear reference to action now that we've pushed it onto the stack */
id_us_min(&adt->action->id);
diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c
index a7301161570..e9b2273b343 100644
--- a/source/blender/editors/transform/transform_convert_armature.c
+++ b/source/blender/editors/transform/transform_convert_armature.c
@@ -164,21 +164,21 @@ static void autokeyframe_pose(
/* only if bone name matches too...
* NOTE: this will do constraints too, but those are ok to do here too?
*/
- if (pchanName && STREQ(pchanName, pchan->name)) {
- insert_keyframe(bmain,
- reports,
- id,
- act,
- ((fcu->grp) ? (fcu->grp->name) : (NULL)),
- fcu->rna_path,
- fcu->array_index,
- &anim_eval_context,
- ts->keyframe_type,
- &nla_cache,
- flag);
- }
-
if (pchanName) {
+ if (STREQ(pchanName, pchan->name)) {
+ insert_keyframe(bmain,
+ reports,
+ id,
+ act,
+ ((fcu->grp) ? (fcu->grp->name) : (NULL)),
+ fcu->rna_path,
+ fcu->array_index,
+ &anim_eval_context,
+ ts->keyframe_type,
+ &nla_cache,
+ flag);
+ }
+
MEM_freeN(pchanName);
}
}
diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c
index 8f18f6a8c96..fa60a88a45b 100644
--- a/source/blender/editors/transform/transform_convert_nla.c
+++ b/source/blender/editors/transform/transform_convert_nla.c
@@ -462,6 +462,12 @@ void recalcData_nla(TransInfo *t)
* - we need to calculate both,
* as only one may have been altered by transform if only 1 handle moved.
*/
+ /* In LibOverride case, we cannot move strips across tracks that come from the linked data. */
+ const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(tdn->id);
+ if (BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, tdn->nlt)) {
+ continue;
+ }
+
delta_y1 = ((int)tdn->h1[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex);
delta_y2 = ((int)tdn->h2[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex);
@@ -477,10 +483,11 @@ void recalcData_nla(TransInfo *t)
if (delta > 0) {
for (track = tdn->nlt->next, n = 0; (track) && (n < delta); track = track->next, n++) {
/* check if space in this track for the strip */
- if (BKE_nlatrack_has_space(track, strip->start, strip->end)) {
+ if (BKE_nlatrack_has_space(track, strip->start, strip->end) &&
+ !BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, tdn->nlt)) {
/* move strip to this track */
BLI_remlink(&tdn->nlt->strips, strip);
- BKE_nlatrack_add_strip(track, strip);
+ BKE_nlatrack_add_strip(track, strip, is_liboverride);
tdn->nlt = track;
tdn->trackIndex++;
@@ -496,10 +503,11 @@ void recalcData_nla(TransInfo *t)
for (track = tdn->nlt->prev, n = 0; (track) && (n < delta); track = track->prev, n++) {
/* check if space in this track for the strip */
- if (BKE_nlatrack_has_space(track, strip->start, strip->end)) {
+ if (BKE_nlatrack_has_space(track, strip->start, strip->end) &&
+ !BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, tdn->nlt)) {
/* move strip to this track */
BLI_remlink(&tdn->nlt->strips, strip);
- BKE_nlatrack_add_strip(track, strip);
+ BKE_nlatrack_add_strip(track, strip, is_liboverride);
tdn->nlt = track;
tdn->trackIndex--;
diff --git a/source/blender/editors/transform/transform_convert_node.c b/source/blender/editors/transform/transform_convert_node.c
index 38db8708d0c..58ff4db324e 100644
--- a/source/blender/editors/transform/transform_convert_node.c
+++ b/source/blender/editors/transform/transform_convert_node.c
@@ -25,6 +25,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BKE_context.h"
@@ -70,8 +71,6 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node, const
td2d->loc[2] = 0.0f;
td2d->loc2d = td2d->loc; /* current location */
- td->flag = 0;
-
td->loc = td2d->loc;
copy_v3_v3(td->iloc, td->loc);
/* use node center instead of origin (top-left corner) */
@@ -85,8 +84,8 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node, const
td->ext = NULL;
td->val = NULL;
- td->flag |= TD_SELECTED;
- td->dist = 0.0;
+ td->flag = TD_SELECTED;
+ td->dist = 0.0f;
unit_m3(td->mtx);
unit_m3(td->smtx);
@@ -107,10 +106,7 @@ static bool is_node_parent_select(bNode *node)
void createTransNodeData(TransInfo *t)
{
const float dpi_fac = UI_DPI_FAC;
- TransData *td;
- TransData2D *td2d;
SpaceNode *snode = t->area->spacedata.first;
- bNode *node;
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
@@ -124,7 +120,7 @@ void createTransNodeData(TransInfo *t)
t->flag &= ~T_PROP_EDIT_ALL;
/* set transform flags on nodes */
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
if (node->flag & NODE_SELECT && is_node_parent_select(node) == false) {
node->flag |= NODE_TRANSFORM;
tc->data_len++;
@@ -134,10 +130,11 @@ void createTransNodeData(TransInfo *t)
}
}
- td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransNode TransData");
- td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransNode TransData2D");
+ TransData *td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransNode TransData");
+ TransData2D *td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D),
+ "TransNode TransData2D");
- for (node = snode->edittree->nodes.first; node; node = node->next) {
+ LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
if (node->flag & NODE_TRANSFORM) {
NodeToTransData(td++, td2d++, node, dpi_fac);
}
@@ -156,24 +153,21 @@ void flushTransNodes(TransInfo *t)
const float dpi_fac = UI_DPI_FAC;
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- int a;
- TransData *td;
- TransData2D *td2d;
-
applyGridAbsolute(t);
/* flush to 2d vector from internally used 3d vector */
- for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
+ for (int i = 0; i < tc->data_len; i++) {
+ TransData *td = &tc->data[i];
+ TransData2D *td2d = &tc->data_2d[i];
bNode *node = td->extra;
- float locx, locy;
/* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */
#ifdef USE_NODE_CENTER
- locx = (td2d->loc[0] - (BLI_rctf_size_x(&node->totr)) * +0.5f) / dpi_fac;
- locy = (td2d->loc[1] - (BLI_rctf_size_y(&node->totr)) * -0.5f) / dpi_fac;
+ float locx = (td2d->loc[0] - (BLI_rctf_size_x(&node->totr)) * +0.5f) / dpi_fac;
+ float locy = (td2d->loc[1] - (BLI_rctf_size_y(&node->totr)) * -0.5f) / dpi_fac;
#else
- locx = td2d->loc[0] / dpi_fac;
- locy = td2d->loc[1] / dpi_fac;
+ float locx = td2d->loc[0] / dpi_fac;
+ float locy = td2d->loc[1] / dpi_fac;
#endif
/* account for parents (nested nodes) */
@@ -209,9 +203,7 @@ void special_aftertrans_update__node(bContext *C, TransInfo *t)
/* remove selected nodes on cancel */
bNodeTree *ntree = snode->edittree;
if (ntree) {
- bNode *node, *node_next;
- for (node = ntree->nodes.first; node; node = node_next) {
- node_next = node->next;
+ LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
if (node->flag & NODE_SELECT) {
nodeRemoveNode(bmain, ntree, node, true);
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 27346c9e974..5b41f6b51bf 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -593,60 +593,18 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
transform_orientations_current_set(t, (t->con.mode & CON_APPLY) ? 2 : 0);
}
- if (event) {
- t->release_confirm_event_type = WM_userdef_event_type_from_keymap_type(event->type);
- t->is_launch_event_tweak = ISTWEAK(event->type);
-
- /* XXX Remove this when wm_operator_call_internal doesn't use window->eventstate
- * (which can have type = 0) */
- /* For gizmo only, so assume LEFTMOUSE. */
- if (t->release_confirm_event_type == 0) {
- t->release_confirm_event_type = LEFTMOUSE;
- }
- }
- else {
- /* Needed to translate tweak events to mouse buttons. */
- t->release_confirm_event_type = -1;
- }
-
- t->release_confirm_event_val = -2;
-
if (op && ((prop = RNA_struct_find_property(op->ptr, "release_confirm")) &&
RNA_property_is_set(op->ptr, prop))) {
if (RNA_property_boolean_get(op->ptr, prop)) {
t->flag |= T_RELEASE_CONFIRM;
- t->release_confirm_event_val = KM_RELEASE;
}
}
else {
/* Release confirms preference should not affect node editor (T69288, T70504). */
- if (ISMOUSE(t->release_confirm_event_type) &&
+ if (ISMOUSE(t->launch_event) &&
((U.flag & USER_RELEASECONFIRM) || (t->spacetype == SPACE_NODE))) {
/* Global "release confirm" on mouse bindings */
t->flag |= T_RELEASE_CONFIRM;
- t->release_confirm_event_val = KM_RELEASE;
- }
- }
-
- if (op && event) {
- /* Keymap for shortcut header prints. */
- t->keymap = WM_keymap_active(CTX_wm_manager(C), op->type->modalkeymap);
-
- /* Stupid code to have Relase confirm and Ctrl-Click on gizmo work ok. */
- wmKeyMapItem *kmi = WM_event_match_modal_keymap_item(t->keymap, op, event);
- if (kmi) {
- if ((t->flag & T_RELEASE_CONFIRM) && (event->val == KM_PRESS) && (kmi->val != KM_PRESS)) {
- t->release_confirm_event_type = EVT_MODAL_MAP;
- t->release_confirm_event_val = kmi->propvalue;
- }
-
- if ((kmi->propvalue == TFM_MODAL_SNAP_INV_ON) &&
- ELEM(t->mode, TFM_TRANSLATION, TFM_ROTATION, TFM_RESIZE)) {
- /* Do this only for translation/rotation/resize because only these
- * modes are available from gizmo and doing such check could
- * lead to keymap conflicts for other modes (see T31584) */
- t->modifiers |= MOD_SNAP_INVERT;
- }
}
}
diff --git a/source/blender/editors/transform/transform_mode_edge_seq_slide.c b/source/blender/editors/transform/transform_mode_edge_seq_slide.c
index dfa5c164acf..7ccfd0149bd 100644
--- a/source/blender/editors/transform/transform_mode_edge_seq_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_seq_slide.c
@@ -32,6 +32,7 @@
#include "ED_screen.h"
#include "WM_api.h"
+#include "WM_types.h"
#include "UI_interface.h"
@@ -45,6 +46,18 @@
/** \name Transform (Sequencer Slide)
* \{ */
+static eRedrawFlag seq_slide_handleEvent(struct TransInfo *t, const wmEvent *event)
+{
+ BLI_assert(t->mode == TFM_SEQ_SLIDE);
+ wmKeyMapItem *kmi = t->custom.mode.data;
+ if (kmi && event->type == kmi->type && event->val == kmi->val) {
+ /* Allows the 'Expand to fit' effect to be enabled as a toogle. */
+ t->flag ^= T_ALT_TRANSFORM;
+ return TREDRAW_HARD;
+ }
+ return TREDRAW_NOTHING;
+}
+
static void headerSeqSlide(TransInfo *t, const float val[2], char str[UI_MAX_DRAW_STR])
{
char tvec[NUM_STR_REP_LEN * 3];
@@ -60,12 +73,11 @@ static void headerSeqSlide(TransInfo *t, const float val[2], char str[UI_MAX_DRA
ofs += BLI_snprintf(
str + ofs, UI_MAX_DRAW_STR - ofs, TIP_("Sequence Slide: %s%s, ("), &tvec[0], t->con.text);
- if (t->keymap) {
- wmKeyMapItem *kmi = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_TRANSLATE);
- if (kmi) {
- ofs += WM_keymap_item_to_string(kmi, false, str + ofs, UI_MAX_DRAW_STR - ofs);
- }
+ wmKeyMapItem *kmi = t->custom.mode.data;
+ if (kmi) {
+ ofs += WM_keymap_item_to_string(kmi, false, str + ofs, UI_MAX_DRAW_STR - ofs);
}
+
ofs += BLI_snprintf(str + ofs,
UI_MAX_DRAW_STR - ofs,
TIP_(" or Alt) Expand to fit %s"),
@@ -91,7 +103,7 @@ static void applySeqSlideValue(TransInfo *t, const float val[2])
static void applySeqSlide(TransInfo *t, const int mval[2])
{
char str[UI_MAX_DRAW_STR];
- float values_final[2] = {0.0f};
+ float values_final[3] = {0.0f};
snapSequenceBounds(t, mval);
if (applyNumInput(&t->num, values_final)) {
@@ -126,6 +138,7 @@ static void applySeqSlide(TransInfo *t, const int mval[2])
void initSeqSlide(TransInfo *t)
{
t->transform = applySeqSlide;
+ t->handleEvent = seq_slide_handleEvent;
initMouseInputMode(t, &t->mouse, INPUT_VECTOR);
@@ -142,5 +155,10 @@ void initSeqSlide(TransInfo *t)
* (supporting frames in addition to "natural" time...). */
t->num.unit_type[0] = B_UNIT_NONE;
t->num.unit_type[1] = B_UNIT_NONE;
+
+ if (t->keymap) {
+ /* Workaround to use the same key as the modal keymap. */
+ t->custom.mode.data = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_TRANSLATE);
+ }
}
/** \} */
diff --git a/source/blender/editors/transform/transform_mode_shrink_fatten.c b/source/blender/editors/transform/transform_mode_shrink_fatten.c
index cdea388529f..2a5c631df41 100644
--- a/source/blender/editors/transform/transform_mode_shrink_fatten.c
+++ b/source/blender/editors/transform/transform_mode_shrink_fatten.c
@@ -32,6 +32,7 @@
#include "ED_screen.h"
#include "WM_api.h"
+#include "WM_types.h"
#include "UI_interface.h"
@@ -45,6 +46,18 @@
/** \name Transform (Shrink-Fatten)
* \{ */
+static eRedrawFlag shrinkfatten_handleEvent(struct TransInfo *t, const wmEvent *event)
+{
+ BLI_assert(t->mode == TFM_SHRINKFATTEN);
+ wmKeyMapItem *kmi = t->custom.mode.data;
+ if (kmi && event->type == kmi->type && event->val == kmi->val) {
+ /* Allows the 'Even Thickness' effect to be enabled as a toogle. */
+ t->flag ^= T_ALT_TRANSFORM;
+ return TREDRAW_HARD;
+ }
+ return TREDRAW_NOTHING;
+}
+
static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
{
float distance;
@@ -77,12 +90,11 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
}
ofs += BLI_strncpy_rlen(str + ofs, ", (", sizeof(str) - ofs);
- if (t->keymap) {
- wmKeyMapItem *kmi = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE);
- if (kmi) {
- ofs += WM_keymap_item_to_string(kmi, false, str + ofs, sizeof(str) - ofs);
- }
+ wmKeyMapItem *kmi = t->custom.mode.data;
+ if (kmi) {
+ ofs += WM_keymap_item_to_string(kmi, false, str + ofs, sizeof(str) - ofs);
}
+
BLI_snprintf(str + ofs,
sizeof(str) - ofs,
TIP_(" or Alt) Even Thickness %s"),
@@ -121,6 +133,7 @@ void initShrinkFatten(TransInfo *t)
else {
t->mode = TFM_SHRINKFATTEN;
t->transform = applyShrinkFatten;
+ t->handleEvent = shrinkfatten_handleEvent;
initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
@@ -134,6 +147,11 @@ void initShrinkFatten(TransInfo *t)
t->num.unit_type[0] = B_UNIT_LENGTH;
t->flag |= T_NO_CONSTRAINT;
+
+ if (t->keymap) {
+ /* Workaround to use the same key as the modal keymap. */
+ t->custom.mode.data = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE);
+ }
}
}
/** \} */
diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c
index a54de102966..90c1f241338 100644
--- a/source/blender/editors/transform/transform_mode_translate.c
+++ b/source/blender/editors/transform/transform_mode_translate.c
@@ -60,13 +60,18 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_
char autoik[NUM_STR_REP_LEN];
float dist;
+ UnitSettings *unit = NULL;
+ if (!(t->flag & T_2D_EDIT)) {
+ unit = &t->scene->unit;
+ }
+
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec, &t->scene->unit);
dist = len_v3(t->num.val);
}
else {
float dvec[3];
- if (!(t->flag & T_2D_EDIT) && t->con.mode & CON_APPLY) {
+ if (t->con.mode & CON_APPLY) {
int i = 0;
zero_v3(dvec);
if (t->con.mode & CON_AXIS0) {
@@ -81,18 +86,22 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_
}
else {
copy_v3_v3(dvec, vec);
+ }
+
+ if (t->flag & T_2D_EDIT) {
applyAspectRatio(t, dvec);
}
- dist = len_v3(vec);
- if (!(t->flag & T_2D_EDIT) && t->scene->unit.system) {
+ dist = len_v3(dvec);
+
+ if (unit) {
for (int i = 0; i < 3; i++) {
BKE_unit_value_as_string(&tvec[NUM_STR_REP_LEN * i],
NUM_STR_REP_LEN,
- dvec[i] * t->scene->unit.scale_length,
+ dvec[i] * unit->scale_length,
4,
B_UNIT_LENGTH,
- &t->scene->unit,
+ unit,
true);
}
}
@@ -103,14 +112,9 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_
}
}
- if (!(t->flag & T_2D_EDIT) && t->scene->unit.system) {
- BKE_unit_value_as_string(distvec,
- sizeof(distvec),
- dist * t->scene->unit.scale_length,
- 4,
- B_UNIT_LENGTH,
- &t->scene->unit,
- false);
+ if (unit) {
+ BKE_unit_value_as_string(
+ distvec, sizeof(distvec), dist * unit->scale_length, 4, B_UNIT_LENGTH, unit, false);
}
else if (dist > 1e10f || dist < -1e10f) {
/* prevent string buffer overflow */
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 7282c35ea0f..5153fdedcae 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -376,7 +376,7 @@ static int transformops_data(bContext *C, wmOperator *op, const wmEvent *event)
{
int retval = 1;
if (op->customdata == NULL) {
- TransInfo *t = op->customdata = MEM_callocN(sizeof(TransInfo), "TransInfo data2");
+ TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data2");
TransformModeItem *tmode;
int mode = -1;
@@ -396,10 +396,10 @@ static int transformops_data(bContext *C, wmOperator *op, const wmEvent *event)
/* store data */
if (retval) {
G.moving = special_transform_moving(t);
+ op->customdata = t;
}
else {
MEM_freeN(t);
- op->customdata = NULL;
}
}
diff --git a/source/blender/editors/uvedit/uvedit_islands.c b/source/blender/editors/uvedit/uvedit_islands.c
index 8a8259d335a..93948b5ae1b 100644
--- a/source/blender/editors/uvedit/uvedit_islands.c
+++ b/source/blender/editors/uvedit/uvedit_islands.c
@@ -144,18 +144,20 @@ static float (*bm_face_array_calc_unique_uv_coords(
BMEdge *e_first = v_pivot->e;
const BMEdge *e = e_first;
do {
- const BMLoop *l_radial = e->l;
- do {
- if (l_radial->v == l_iter->v) {
- if (BM_elem_flag_test(l_radial, BM_ELEM_TAG)) {
- const MLoopUV *luv_radial = BM_ELEM_CD_GET_VOID_P(l_radial, cd_loop_uv_offset);
- if (equals_v2v2(luv->uv, luv_radial->uv)) {
- /* Don't add this UV when met in another face in `faces`. */
- BM_elem_flag_disable(l_iter, BM_ELEM_TAG);
+ if (e->l != NULL) {
+ const BMLoop *l_radial = e->l;
+ do {
+ if (l_radial->v == l_iter->v) {
+ if (BM_elem_flag_test(l_radial, BM_ELEM_TAG)) {
+ const MLoopUV *luv_radial = BM_ELEM_CD_GET_VOID_P(l_radial, cd_loop_uv_offset);
+ if (equals_v2v2(luv->uv, luv_radial->uv)) {
+ /* Don't add this UV when met in another face in `faces`. */
+ BM_elem_flag_disable(l_iter, BM_ELEM_TAG);
+ }
}
}
- }
- } while ((l_radial = l_radial->radial_next) != e->l);
+ } while ((l_radial = l_radial->radial_next) != e->l);
+ }
} while ((e = BM_DISK_EDGE_NEXT(e, v_pivot)) != e_first);
} while ((l_iter = l_iter->next) != l_first);
}
diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp
index 63612694e65..ddd11729e67 100644
--- a/source/blender/freestyle/intern/application/Controller.cpp
+++ b/source/blender/freestyle/intern/application/Controller.cpp
@@ -22,7 +22,7 @@ extern "C" {
#include <Python.h>
}
-#include <float.h>
+#include <cfloat>
#include <fstream>
#include <string>
@@ -1067,7 +1067,7 @@ void Controller::displayDensityCurves(int x, int y)
}
unsigned int i, j;
- typedef vector<Vec3r> densityCurve;
+ using densityCurve = vector<Vec3r>;
vector<densityCurve> curves(svm->getNumberOfOrientations() + 1);
vector<densityCurve> curvesDirection(svm->getNumberOfPyramidLevels());
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index 8aaffd4dde8..f761b1f6243 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -64,7 +64,7 @@
#include "render_types.h"
-#include <limits.h>
+#include <climits>
namespace Freestyle {
diff --git a/source/blender/freestyle/intern/geometry/FitCurve.cpp b/source/blender/freestyle/intern/geometry/FitCurve.cpp
index 5682ccc9298..5768f88e95f 100644
--- a/source/blender/freestyle/intern/geometry/FitCurve.cpp
+++ b/source/blender/freestyle/intern/geometry/FitCurve.cpp
@@ -20,9 +20,9 @@
* \brief from "Graphics Gems", Academic Press, 1990
*/
+#include <cmath>
+#include <cstdio>
#include <cstdlib> // for malloc and free
-#include <math.h>
-#include <stdio.h>
#include "FitCurve.h"
@@ -30,7 +30,7 @@ using namespace std;
namespace Freestyle {
-typedef Vector2 *BezierCurve;
+using BezierCurve = Vector2 *;
/* Forward declarations */
static double *Reparameterize(Vector2 *d, int first, int last, double *u, BezierCurve bezCurve);
diff --git a/source/blender/freestyle/intern/geometry/GeomCleaner.cpp b/source/blender/freestyle/intern/geometry/GeomCleaner.cpp
index b1d0a6c7e2a..7ec18fb2801 100644
--- a/source/blender/freestyle/intern/geometry/GeomCleaner.cpp
+++ b/source/blender/freestyle/intern/geometry/GeomCleaner.cpp
@@ -29,9 +29,9 @@
# endif
#endif
+#include <cstdio>
#include <list>
#include <map>
-#include <stdio.h>
#include "GeomCleaner.h"
@@ -202,7 +202,7 @@ void GeomCleaner::CleanIndexedVertexArray(const float *iVertices,
unsigned *oVSize,
unsigned **oIndices)
{
- typedef map<Vec3f, unsigned> cleanHashTable;
+ using cleanHashTable = map<Vec3f, unsigned>;
vector<Vec3f> vertices;
unsigned i;
for (i = 0; i < iVSize; i += 3) {
diff --git a/source/blender/freestyle/intern/geometry/Noise.cpp b/source/blender/freestyle/intern/geometry/Noise.cpp
index 7c42c332370..e3ea2ac154f 100644
--- a/source/blender/freestyle/intern/geometry/Noise.cpp
+++ b/source/blender/freestyle/intern/geometry/Noise.cpp
@@ -19,10 +19,10 @@
* \brief Class to define Perlin noise
*/
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <ctime>
#include "BLI_compiler_attrs.h"
#include "BLI_rand.h"
diff --git a/source/blender/freestyle/intern/image/GaussianFilter.cpp b/source/blender/freestyle/intern/image/GaussianFilter.cpp
index 3bbe86ee986..3c8bf5bd3a1 100644
--- a/source/blender/freestyle/intern/image/GaussianFilter.cpp
+++ b/source/blender/freestyle/intern/image/GaussianFilter.cpp
@@ -19,7 +19,7 @@
* \brief Class to perform gaussian filtering operations on an image
*/
-#include <stdlib.h>
+#include <cstdlib>
#include "GaussianFilter.h"
diff --git a/source/blender/freestyle/intern/scene_graph/NodeCamera.cpp b/source/blender/freestyle/intern/scene_graph/NodeCamera.cpp
index 052ae73da43..4fc1f227172 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeCamera.cpp
+++ b/source/blender/freestyle/intern/scene_graph/NodeCamera.cpp
@@ -19,8 +19,8 @@
* \brief Class to represent a light node
*/
-#include <math.h>
-#include <string.h> // for memcpy
+#include <cmath>
+#include <cstring> // for memcpy
#include "NodeCamera.h"
diff --git a/source/blender/freestyle/intern/stroke/Curve.cpp b/source/blender/freestyle/intern/stroke/Curve.cpp
index c3dac81477d..768e9efa15d 100644
--- a/source/blender/freestyle/intern/stroke/Curve.cpp
+++ b/source/blender/freestyle/intern/stroke/Curve.cpp
@@ -19,7 +19,7 @@
* \brief Class to define a container for curves
*/
-#include <stdio.h> /* printf */
+#include <cstdio> /* printf */
#include "Curve.h"
#include "CurveAdvancedIterators.h"
diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
index 7e8937bfe80..9bf00ed7092 100644
--- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
+++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
@@ -19,7 +19,7 @@
* \brief Detects/flags/builds extended features edges on the WXEdge structure
*/
-#include <float.h>
+#include <cfloat>
#include "FEdgeXDetector.h"
diff --git a/source/blender/freestyle/intern/view_map/ViewMap.cpp b/source/blender/freestyle/intern/view_map/ViewMap.cpp
index 60d0e45b9fb..d304c3616d7 100644
--- a/source/blender/freestyle/intern/view_map/ViewMap.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMap.cpp
@@ -19,7 +19,7 @@
* \brief Classes to define a View Map (ViewVertex, ViewEdge, etc.)
*/
-#include <float.h>
+#include <cfloat>
#include "ViewMap.h"
#include "ViewMapAdvancedIterators.h"
diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
index de30ee0460a..cbb5c730b2b 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
@@ -2299,8 +2299,8 @@ struct less_SVertex2D {
}
};
-typedef Segment<FEdge *, Vec3r> segment;
-typedef Intersection<segment> intersection;
+using segment = Segment<FEdge *, Vec3r>;
+using intersection = Intersection<segment>;
struct less_Intersection {
segment *edge;
@@ -2326,7 +2326,7 @@ struct silhouette_binary_rule : public binary_rule<segment, segment> {
{
}
- virtual bool operator()(segment &s1, segment &s2)
+ bool operator()(segment &s1, segment &s2) override
{
FEdge *f1 = s1.edge();
FEdge *f2 = s2.edge();
diff --git a/source/blender/freestyle/intern/view_map/ViewMapIO.cpp b/source/blender/freestyle/intern/view_map/ViewMapIO.cpp
index aed5d6b5adc..774751a2589 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapIO.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapIO.cpp
@@ -19,7 +19,7 @@
* \brief Functions to manage I/O for the view map
*/
-#include <limits.h>
+#include <climits>
#include "ViewMapIO.h"
diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.cpp b/source/blender/freestyle/intern/winged_edge/Curvature.cpp
index 1702a22c678..0ee491a071c 100644
--- a/source/blender/freestyle/intern/winged_edge/Curvature.cpp
+++ b/source/blender/freestyle/intern/winged_edge/Curvature.cpp
@@ -33,7 +33,7 @@
* \brief OGF/Graphite: Geometry and Graphics Programming Library + Utilities
*/
-#include <assert.h>
+#include <cassert>
#include <cstdlib> // for malloc and free
#include <set>
#include <stack>
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 7e2fe753b7b..69a79e2f2ce 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -313,6 +313,7 @@ data_to_c_simple(shaders/material/gpu_shader_material_noise.glsl SRC)
data_to_c_simple(shaders/material/gpu_shader_material_normal.glsl SRC)
data_to_c_simple(shaders/material/gpu_shader_material_normal_map.glsl SRC)
data_to_c_simple(shaders/material/gpu_shader_material_object_info.glsl SRC)
+data_to_c_simple(shaders/material/gpu_shader_material_output_aov.glsl SRC)
data_to_c_simple(shaders/material/gpu_shader_material_output_material.glsl SRC)
data_to_c_simple(shaders/material/gpu_shader_material_output_world.glsl SRC)
data_to_c_simple(shaders/material/gpu_shader_material_particle_info.glsl SRC)
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 67cd1a61aed..312da491a36 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -173,6 +173,7 @@ GPUNodeLink *GPU_uniformbuf_link_out(struct GPUMaterial *mat,
const int index);
void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link);
+void GPU_material_add_output_link_aov(GPUMaterial *material, GPUNodeLink *link, int hash);
void GPU_material_sss_profile_create(GPUMaterial *material,
float radii[3],
diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc
index 3bf1233c000..9dc24c59e22 100644
--- a/source/blender/gpu/intern/gpu_batch.cc
+++ b/source/blender/gpu/intern/gpu_batch.cc
@@ -42,7 +42,7 @@
#include "gpu_batch_private.hh"
-#include <string.h>
+#include <cstring>
using namespace blender::gpu;
@@ -81,8 +81,8 @@ void GPU_batch_init_ex(GPUBatch *batch,
for (int v = 1; v < GPU_BATCH_VBO_MAX_LEN; v++) {
batch->verts[v] = nullptr;
}
- for (int v = 0; v < GPU_BATCH_INST_VBO_MAX_LEN; v++) {
- batch->inst[v] = nullptr;
+ for (auto &v : batch->inst) {
+ v = nullptr;
}
batch->elem = elem;
batch->prim_type = prim_type;
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 3ebe2edc89e..84da95f6fee 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -411,7 +411,7 @@ static void codegen_declare_tmps(DynStr *ds, GPUNodeGraph *graph)
BLI_dynstr_append(ds, "\n");
}
-static void codegen_call_functions(DynStr *ds, GPUNodeGraph *graph, GPUOutput *finaloutput)
+static void codegen_call_functions(DynStr *ds, GPUNodeGraph *graph)
{
LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) {
BLI_dynstr_appendf(ds, " %s(", node->name);
@@ -509,8 +509,11 @@ static void codegen_call_functions(DynStr *ds, GPUNodeGraph *graph, GPUOutput *f
BLI_dynstr_append(ds, ");\n");
}
+}
- BLI_dynstr_appendf(ds, "\n return tmp%d;\n", finaloutput->id);
+static void codegen_final_output(DynStr *ds, GPUOutput *finaloutput)
+{
+ BLI_dynstr_appendf(ds, "return tmp%d;\n", finaloutput->id);
}
static char *code_generate_fragment(GPUMaterial *material,
@@ -593,7 +596,35 @@ static char *code_generate_fragment(GPUMaterial *material,
}
codegen_declare_tmps(ds, graph);
- codegen_call_functions(ds, graph, graph->outlink->output);
+ codegen_call_functions(ds, graph);
+
+ BLI_dynstr_append(ds, " #ifndef VOLUMETRICS\n");
+ BLI_dynstr_append(ds, " if (renderPassAOV) {\n");
+ BLI_dynstr_append(ds, " switch (render_pass_aov_hash()) {\n");
+ GSet *aovhashes_added = BLI_gset_int_new(__func__);
+ LISTBASE_FOREACH (GPUNodeGraphOutputLink *, aovlink, &graph->outlink_aovs) {
+ void *aov_key = POINTER_FROM_INT(aovlink->hash);
+ if (BLI_gset_haskey(aovhashes_added, aov_key)) {
+ continue;
+ }
+ BLI_dynstr_appendf(ds, " case %d: {\n ", aovlink->hash);
+ codegen_final_output(ds, aovlink->outlink->output);
+ BLI_dynstr_append(ds, " }\n");
+ BLI_gset_add(aovhashes_added, aov_key);
+ }
+ BLI_gset_free(aovhashes_added, NULL);
+ BLI_dynstr_append(ds, " default: {\n");
+ BLI_dynstr_append(ds, " Closure no_aov = CLOSURE_DEFAULT;\n");
+ BLI_dynstr_append(ds, " no_aov.holdout = 1.0;\n");
+ BLI_dynstr_append(ds, " return no_aov;\n");
+ BLI_dynstr_append(ds, " }\n");
+ BLI_dynstr_append(ds, " }\n");
+ BLI_dynstr_append(ds, " } else {\n");
+ BLI_dynstr_append(ds, " #else /* VOLUMETRICS */\n");
+ BLI_dynstr_append(ds, " {\n");
+ BLI_dynstr_append(ds, " #endif /* VOLUMETRICS */\n ");
+ codegen_final_output(ds, graph->outlink->output);
+ BLI_dynstr_append(ds, " }\n");
BLI_dynstr_append(ds, "}\n");
diff --git a/source/blender/gpu/intern/gpu_framebuffer.cc b/source/blender/gpu/intern/gpu_framebuffer.cc
index f11f1cea753..d5d7994a154 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.cc
+++ b/source/blender/gpu/intern/gpu_framebuffer.cc
@@ -57,18 +57,18 @@ FrameBuffer::FrameBuffer(const char *name)
dirty_attachments_ = true;
dirty_state_ = true;
- for (int i = 0; i < ARRAY_SIZE(attachments_); i++) {
- attachments_[i].tex = nullptr;
- attachments_[i].mip = -1;
- attachments_[i].layer = -1;
+ for (GPUAttachment &attachment : attachments_) {
+ attachment.tex = nullptr;
+ attachment.mip = -1;
+ attachment.layer = -1;
}
}
FrameBuffer::~FrameBuffer()
{
- for (int i = 0; i < ARRAY_SIZE(attachments_); i++) {
- if (attachments_[i].tex != nullptr) {
- reinterpret_cast<Texture *>(attachments_[i].tex)->detach_from(this);
+ for (GPUAttachment &attachment : attachments_) {
+ if (attachment.tex != nullptr) {
+ reinterpret_cast<Texture *>(attachment.tex)->detach_from(this);
}
}
}
@@ -148,8 +148,8 @@ void FrameBuffer::recursive_downsample(int max_lvl,
for (int mip_lvl = 1; mip_lvl <= max_lvl; mip_lvl++) {
/* Replace attached mip-level for each attachment. */
- for (int att = 0; att < ARRAY_SIZE(attachments_); att++) {
- Texture *tex = reinterpret_cast<Texture *>(attachments_[att].tex);
+ for (GPUAttachment &attachment : attachments_) {
+ Texture *tex = reinterpret_cast<Texture *>(attachment.tex);
if (tex != nullptr) {
/* Some Intel HDXXX have issue with rendering to a mipmap that is below
* the texture GL_TEXTURE_MAX_LEVEL. So even if it not correct, in this case
@@ -158,7 +158,7 @@ void FrameBuffer::recursive_downsample(int max_lvl,
/* Restrict fetches only to previous level. */
tex->mip_range_set(mip_lvl - 1, mip_max);
/* Bind next level. */
- attachments_[att].mip = mip_lvl;
+ attachment.mip = mip_lvl;
}
}
/* Update the internal attachments and viewport size. */
@@ -168,12 +168,12 @@ void FrameBuffer::recursive_downsample(int max_lvl,
callback(userData, mip_lvl);
}
- for (int att = 0; att < ARRAY_SIZE(attachments_); att++) {
- if (attachments_[att].tex != nullptr) {
+ for (GPUAttachment &attachment : attachments_) {
+ if (attachment.tex != nullptr) {
/* Reset mipmap level range. */
- reinterpret_cast<Texture *>(attachments_[att].tex)->mip_range_set(0, max_lvl);
+ reinterpret_cast<Texture *>(attachment.tex)->mip_range_set(0, max_lvl);
/* Reset base level. NOTE: might not be the one bound at the start of this function. */
- attachments_[att].mip = 0;
+ attachment.mip = 0;
}
}
dirty_attachments_ = true;
@@ -525,18 +525,18 @@ static GPUFrameBuffer *gpu_offscreen_fb_get(GPUOffScreen *ofs)
Context *ctx = Context::get();
BLI_assert(ctx);
- for (int i = 0; i < MAX_CTX_FB_LEN; i++) {
- if (ofs->framebuffers[i].fb == nullptr) {
- ofs->framebuffers[i].ctx = ctx;
- GPU_framebuffer_ensure_config(&ofs->framebuffers[i].fb,
+ for (auto &framebuffer : ofs->framebuffers) {
+ if (framebuffer.fb == nullptr) {
+ framebuffer.ctx = ctx;
+ GPU_framebuffer_ensure_config(&framebuffer.fb,
{
GPU_ATTACHMENT_TEXTURE(ofs->depth),
GPU_ATTACHMENT_TEXTURE(ofs->color),
});
}
- if (ofs->framebuffers[i].ctx == ctx) {
- return ofs->framebuffers[i].fb;
+ if (framebuffer.ctx == ctx) {
+ return framebuffer.fb;
}
}
@@ -550,9 +550,9 @@ static GPUFrameBuffer *gpu_offscreen_fb_get(GPUOffScreen *ofs)
"Warning: GPUOffscreen used in more than 3 GPUContext. "
"This may create performance drop.\n");
- for (int i = 0; i < MAX_CTX_FB_LEN; i++) {
- GPU_framebuffer_free(ofs->framebuffers[i].fb);
- ofs->framebuffers[i].fb = nullptr;
+ for (auto &framebuffer : ofs->framebuffers) {
+ GPU_framebuffer_free(framebuffer.fb);
+ framebuffer.fb = nullptr;
}
return gpu_offscreen_fb_get(ofs);
@@ -595,9 +595,9 @@ GPUOffScreen *GPU_offscreen_create(
void GPU_offscreen_free(GPUOffScreen *ofs)
{
- for (int i = 0; i < MAX_CTX_FB_LEN; i++) {
- if (ofs->framebuffers[i].fb) {
- GPU_framebuffer_free(ofs->framebuffers[i].fb);
+ for (auto &framebuffer : ofs->framebuffers) {
+ if (framebuffer.fb) {
+ GPU_framebuffer_free(framebuffer.fb);
}
}
if (ofs->color) {
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index a0fe77598f2..3f22424c7c9 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -597,6 +597,14 @@ void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link)
}
}
+void GPU_material_add_output_link_aov(GPUMaterial *material, GPUNodeLink *link, int hash)
+{
+ GPUNodeGraphOutputLink *aov_link = MEM_callocN(sizeof(GPUNodeGraphOutputLink), __func__);
+ aov_link->outlink = link;
+ aov_link->hash = hash;
+ BLI_addtail(&material->graph.outlink_aovs, aov_link);
+}
+
GPUNodeGraph *gpu_material_node_graph(GPUMaterial *material)
{
return &material->graph;
diff --git a/source/blender/gpu/intern/gpu_material_library.c b/source/blender/gpu/intern/gpu_material_library.c
index e0165e1fa83..496988c4ba9 100644
--- a/source/blender/gpu/intern/gpu_material_library.c
+++ b/source/blender/gpu/intern/gpu_material_library.c
@@ -84,6 +84,7 @@ extern char datatoc_gpu_shader_material_noise_glsl[];
extern char datatoc_gpu_shader_material_normal_glsl[];
extern char datatoc_gpu_shader_material_normal_map_glsl[];
extern char datatoc_gpu_shader_material_object_info_glsl[];
+extern char datatoc_gpu_shader_material_output_aov_glsl[];
extern char datatoc_gpu_shader_material_output_material_glsl[];
extern char datatoc_gpu_shader_material_output_world_glsl[];
extern char datatoc_gpu_shader_material_particle_info_glsl[];
@@ -354,6 +355,11 @@ static GPUMaterialLibrary gpu_shader_material_object_info_library = {
.dependencies = {NULL},
};
+static GPUMaterialLibrary gpu_shader_material_output_aov_library = {
+ .code = datatoc_gpu_shader_material_output_aov_glsl,
+ .dependencies = {NULL},
+};
+
static GPUMaterialLibrary gpu_shader_material_output_material_library = {
.code = datatoc_gpu_shader_material_output_material_glsl,
.dependencies = {NULL},
@@ -619,6 +625,7 @@ static GPUMaterialLibrary *gpu_material_libraries[] = {
&gpu_shader_material_normal_library,
&gpu_shader_material_normal_map_library,
&gpu_shader_material_object_info_library,
+ &gpu_shader_material_output_aov_library,
&gpu_shader_material_output_material_library,
&gpu_shader_material_output_world_library,
&gpu_shader_material_particle_info_library,
diff --git a/source/blender/gpu/intern/gpu_matrix.cc b/source/blender/gpu/intern/gpu_matrix.cc
index dae56e39db6..4ccb28fedbd 100644
--- a/source/blender/gpu/intern/gpu_matrix.cc
+++ b/source/blender/gpu/intern/gpu_matrix.cc
@@ -39,15 +39,15 @@ using namespace blender::gpu;
#define MATRIX_STACK_DEPTH 32
-typedef float Mat4[4][4];
-typedef float Mat3[3][3];
+using Mat4 = float[4][4];
+using Mat3 = float[3][3];
-typedef struct MatrixStack {
+struct MatrixStack {
Mat4 stack[MATRIX_STACK_DEPTH];
uint top;
-} MatrixStack;
+};
-typedef struct GPUMatrixState {
+struct GPUMatrixState {
MatrixStack model_view_stack;
MatrixStack projection_stack;
@@ -59,7 +59,7 @@ typedef struct GPUMatrixState {
* TODO: separate Model from View transform? Batches/objects have model,
* camera/eye has view & projection
*/
-} GPUMatrixState;
+};
#define ModelViewStack Context::get()->matrix_state->model_view_stack
#define ModelView ModelViewStack.stack[ModelViewStack.top]
diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c
index 2a2a51e32b3..08da49c3475 100644
--- a/source/blender/gpu/intern/gpu_node_graph.c
+++ b/source/blender/gpu/intern/gpu_node_graph.c
@@ -805,6 +805,7 @@ void gpu_node_graph_free_nodes(GPUNodeGraph *graph)
/* Free both node graph and requested attributes and textures. */
void gpu_node_graph_free(GPUNodeGraph *graph)
{
+ BLI_freelistN(&graph->outlink_aovs);
gpu_node_graph_free_nodes(graph);
LISTBASE_FOREACH (GPUMaterialVolumeGrid *, grid, &graph->volume_grids) {
@@ -847,6 +848,9 @@ void gpu_node_graph_prune_unused(GPUNodeGraph *graph)
}
gpu_nodes_tag(graph->outlink);
+ LISTBASE_FOREACH (GPUNodeGraphOutputLink *, aovlink, &graph->outlink_aovs) {
+ gpu_nodes_tag(aovlink->outlink);
+ }
for (GPUNode *node = graph->nodes.first, *next = NULL; node; node = next) {
next = node->next;
diff --git a/source/blender/gpu/intern/gpu_node_graph.h b/source/blender/gpu/intern/gpu_node_graph.h
index a0e6298cd92..0ef95d94c0d 100644
--- a/source/blender/gpu/intern/gpu_node_graph.h
+++ b/source/blender/gpu/intern/gpu_node_graph.h
@@ -141,12 +141,20 @@ typedef struct GPUInput {
};
} GPUInput;
+typedef struct GPUNodeGraphOutputLink {
+ struct GPUNodeGraphOutputLink *next, *prev;
+ int hash;
+ GPUNodeLink *outlink;
+} GPUNodeGraphOutputLink;
+
typedef struct GPUNodeGraph {
/* Nodes */
ListBase nodes;
- /* Output. */
+ /* Main Output. */
GPUNodeLink *outlink;
+ /* List of GPUNodeGraphOutputLink */
+ ListBase outlink_aovs;
/* Requested attributes and textures. */
ListBase attributes;
diff --git a/source/blender/gpu/intern/gpu_select_sample_query.cc b/source/blender/gpu/intern/gpu_select_sample_query.cc
index 6ca811895a5..5d8689c0d6a 100644
--- a/source/blender/gpu/intern/gpu_select_sample_query.cc
+++ b/source/blender/gpu/intern/gpu_select_sample_query.cc
@@ -24,7 +24,7 @@
* similar to glRenderMode(GL_SELECT) since the goal is to maintain compatibility.
*/
-#include <stdlib.h>
+#include <cstdlib>
#include "GPU_debug.h"
#include "GPU_framebuffer.h"
@@ -47,7 +47,7 @@
using namespace blender;
using namespace blender::gpu;
-typedef struct GPUSelectQueryState {
+struct GPUSelectQueryState {
/* Tracks whether a query has been issued so that gpu_load_id can end the previous one */
bool query_issued;
/* GPU queries abstraction. Contains an array of queries. */
@@ -68,7 +68,7 @@ typedef struct GPUSelectQueryState {
int scissor[4];
eGPUWriteMask write_mask;
eGPUDepthTest depth_test;
-} GPUSelectQueryState;
+};
static GPUSelectQueryState g_query_state = {false};
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index 827ea06686f..d47ad5e0100 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -470,9 +470,9 @@ struct GPUShader *GPU_shader_create_from_arrays_impl(
GPUShader *sh = GPU_shader_create(
str_dst[0].str, str_dst[1].str, str_dst[2].str, nullptr, str_dst[3].str, name);
- for (int i = 0; i < ARRAY_SIZE(str_dst); i++) {
- if (str_dst[i].is_alloc) {
- MEM_freeN((void *)str_dst[i].str);
+ for (auto &i : str_dst) {
+ if (i.is_alloc) {
+ MEM_freeN((void *)i.str);
}
}
return sh;
diff --git a/source/blender/gpu/intern/gpu_uniform_buffer.cc b/source/blender/gpu/intern/gpu_uniform_buffer.cc
index 89c70c47e4a..3edb090d81c 100644
--- a/source/blender/gpu/intern/gpu_uniform_buffer.cc
+++ b/source/blender/gpu/intern/gpu_uniform_buffer.cc
@@ -22,7 +22,7 @@
*/
#include "MEM_guardedalloc.h"
-#include <string.h>
+#include <cstring>
#include "BLI_blenlib.h"
#include "BLI_math_base.h"
diff --git a/source/blender/gpu/intern/gpu_vertex_format.cc b/source/blender/gpu/intern/gpu_vertex_format.cc
index 3b0aa055588..cd6d78a185d 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.cc
+++ b/source/blender/gpu/intern/gpu_vertex_format.cc
@@ -27,8 +27,8 @@
#include "gpu_shader_private.hh"
#include "gpu_vertex_format_private.h"
-#include <stddef.h>
-#include <string.h>
+#include <cstddef>
+#include <cstring>
#include "BLI_ghash.h"
#include "BLI_string.h"
diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc
index 7e948149a7f..f683a70b4e6 100644
--- a/source/blender/gpu/opengl/gl_backend.cc
+++ b/source/blender/gpu/opengl/gl_backend.cc
@@ -131,19 +131,11 @@ void GLBackend::platform_init()
}
}
- /* Since Blender 2.91 AMD TeraScale 2 GPUs crashes during startup. */
- if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_WIN, GPU_DRIVER_ANY)) {
- if (strstr(renderer, "Radeon HD 4") || strstr(renderer, "Radeon HD 5") ||
- strstr(renderer, "Radeon HD 6") || strstr(renderer, "ATI FirePro V4") ||
- strstr(renderer, "AMD Radeon R5 2")) {
- GPG.support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED;
- }
- }
- /* Driver 20.11.2 fixes a lot of issues for the Navi cards, but introduces new ones
+ /* Driver 20.11.2/3 fixes a lot of issues for the Navi cards, but introduces new ones
* for Polaris based cards cards. The viewport has glitches but doesn't crash.
- * See T82856 */
+ * See T82856,T83574. */
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_WIN, GPU_DRIVER_OFFICIAL) &&
- strstr(version, " 20.11.2 ")) {
+ (strstr(version, " 20.11.2 ") || strstr(version, " 20.11.3 "))) {
if (strstr(renderer, "Radeon RX 460 ") || strstr(renderer, "Radeon RX 470 ") ||
strstr(renderer, "Radeon RX 480 ") || strstr(renderer, "Radeon RX 490 ") ||
strstr(renderer, "Radeon RX 560 ") || strstr(renderer, "Radeon RX 570 ") ||
@@ -152,8 +144,10 @@ void GLBackend::platform_init()
}
}
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_ANY)) {
+ /* Platform seems to work when SB backend is disabled. This can be done
+ * by adding the environment variable `R600_DEBUG=nosb`. */
if (strstr(renderer, "AMD CEDAR")) {
- GPG.support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED;
+ GPG.support_level = GPU_SUPPORT_LEVEL_LIMITED;
}
}
}
@@ -253,10 +247,6 @@ static void detect_workarounds()
return;
}
- /* Some Intel drivers have issues with using mips as framebuffer targets if
- * GL_TEXTURE_MAX_LEVEL is higher than the target mip.
- * Only check at the end after all other workarounds because this uses the drawing code. */
- GCaps.mip_render_workaround = detect_mip_render_workaround();
/* Limit support for GLEW_ARB_base_instance to OpenGL 4.0 and higher. NVIDIA Quadro FX 4800
* (TeraScale) report that they support GLEW_ARB_base_instance, but the driver does not support
* GLEW_ARB_draw_indirect as it has an OpenGL3 context what also matches the minimum needed
@@ -277,6 +267,7 @@ static void detect_workarounds()
(strstr(version, "4.5.13399") || strstr(version, "4.5.13417") ||
strstr(version, "4.5.13422"))) {
GLContext::unused_fb_slot_workaround = true;
+ GCaps.mip_render_workaround = true;
GCaps.shader_image_load_store_support = false;
GCaps.broken_amd_driver = true;
}
@@ -368,6 +359,13 @@ static void detect_workarounds()
}
}
+ /* Some Intel drivers have issues with using mips as framebuffer targets if
+ * GL_TEXTURE_MAX_LEVEL is higher than the target mip.
+ * Only check at the end after all other workarounds because this uses the drawing code.
+ * Also after device/driver flags to avoid the check that causes pre GCN Radeon to crash. */
+ if (GCaps.mip_render_workaround == false) {
+ GCaps.mip_render_workaround = detect_mip_render_workaround();
+ }
/* Disable multidraw if the base instance cannot be read. */
if (GLContext::shader_draw_parameters_support == false) {
GLContext::multi_draw_indirect_support = false;
diff --git a/source/blender/gpu/opengl/gl_debug.cc b/source/blender/gpu/opengl/gl_debug.cc
index 4e45ff11fc7..0914c117241 100644
--- a/source/blender/gpu/opengl/gl_debug.cc
+++ b/source/blender/gpu/opengl/gl_debug.cc
@@ -42,7 +42,7 @@
#include "gl_debug.hh"
-#include <stdio.h>
+#include <cstdio>
static CLG_LogRef LOG = {"gpu.debug"};
diff --git a/source/blender/gpu/opengl/gl_debug_layer.cc b/source/blender/gpu/opengl/gl_debug_layer.cc
index 9c2b6c0e547..7d2abfb2cff 100644
--- a/source/blender/gpu/opengl/gl_debug_layer.cc
+++ b/source/blender/gpu/opengl/gl_debug_layer.cc
@@ -30,7 +30,7 @@
#include "gl_debug.hh"
-typedef void *GPUvoidptr;
+using GPUvoidptr = void *;
#define GPUvoidptr_set void *ret =
#define GPUvoidptr_ret return ret
diff --git a/source/blender/gpu/opengl/gl_drawlist.cc b/source/blender/gpu/opengl/gl_drawlist.cc
index aecadc4d14a..f0a18deafd3 100644
--- a/source/blender/gpu/opengl/gl_drawlist.cc
+++ b/source/blender/gpu/opengl/gl_drawlist.cc
@@ -39,24 +39,24 @@
#include "gl_drawlist.hh"
#include "gl_primitive.hh"
-#include <limits.h>
+#include <climits>
using namespace blender::gpu;
-typedef struct GLDrawCommand {
+struct GLDrawCommand {
GLuint v_count;
GLuint i_count;
GLuint v_first;
GLuint i_first;
-} GLDrawCommand;
+};
-typedef struct GLDrawCommandIndexed {
+struct GLDrawCommandIndexed {
GLuint v_count;
GLuint i_count;
GLuint v_first;
GLuint base_index;
GLuint i_first;
-} GLDrawCommandIndexed;
+};
#define MDI_ENABLED (buffer_size_ != 0)
#define MDI_DISABLED (buffer_size_ == 0)
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_output_aov.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_output_aov.glsl
new file mode 100644
index 00000000000..648994739bf
--- /dev/null
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_output_aov.glsl
@@ -0,0 +1,13 @@
+
+void node_output_aov(vec4 color, float value, out Closure result)
+{
+ result = CLOSURE_DEFAULT;
+#ifndef VOLUMETRICS
+ if (render_pass_aov_is_color()) {
+ result.radiance = color.rgb;
+ }
+ else {
+ result.radiance = vec3(value);
+ }
+#endif
+}
diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp
index 61f2153cf6c..9512bce1914 100644
--- a/source/blender/ikplugin/intern/itasc_plugin.cpp
+++ b/source/blender/ikplugin/intern/itasc_plugin.cpp
@@ -23,8 +23,8 @@
*/
#include <cmath>
-#include <stdlib.h>
-#include <string.h>
+#include <cstdlib>
+#include <cstring>
#include <vector>
/* iTaSC headers */
@@ -73,12 +73,12 @@ struct IK_Data {
struct IK_Scene *first;
};
-typedef float Vector3[3];
-typedef float Vector4[4];
+using Vector3 = float[3];
+using Vector4 = float[4];
struct IK_Target;
-typedef void (*ErrorCallback)(const iTaSC::ConstraintValues *values,
- unsigned int nvalues,
- IK_Target *iktarget);
+using ErrorCallback = void (*)(const iTaSC::ConstraintValues *values,
+ unsigned int nvalues,
+ IK_Target *iktarget);
/* one structure for each target in the scene */
struct IK_Target {
@@ -194,8 +194,8 @@ struct IK_Scene {
{
/* delete scene first */
delete scene;
- for (std::vector<IK_Target *>::iterator it = targets.begin(); it != targets.end(); ++it) {
- delete (*it);
+ for (IK_Target *target : targets) {
+ delete target;
}
targets.clear();
delete[] channels;
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
index b7a15812547..4580bfd2cbf 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.c
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -123,16 +123,16 @@ static void fillDpxMainHeader(LogImageFile *dpx,
header->televisionHeader.field_number = DPX_UNDEFINED_U8;
header->televisionHeader.video_signal = DPX_UNDEFINED_U8;
header->televisionHeader.padding = DPX_UNDEFINED_U8;
- header->televisionHeader.horizontal_sample_rate = DPX_UNDEFINED_R32;
- header->televisionHeader.vertical_sample_rate = DPX_UNDEFINED_R32;
- header->televisionHeader.frame_rate = DPX_UNDEFINED_R32;
- header->televisionHeader.time_offset = DPX_UNDEFINED_R32;
+ header->televisionHeader.horizontal_sample_rate = swap_float(DPX_UNDEFINED_R32, dpx->isMSB);
+ header->televisionHeader.vertical_sample_rate = swap_float(DPX_UNDEFINED_R32, dpx->isMSB);
+ header->televisionHeader.frame_rate = swap_float(DPX_UNDEFINED_R32, dpx->isMSB);
+ header->televisionHeader.time_offset = swap_float(DPX_UNDEFINED_R32, dpx->isMSB);
header->televisionHeader.gamma = swap_float(dpx->gamma, dpx->isMSB);
header->televisionHeader.black_level = swap_float(dpx->referenceBlack, dpx->isMSB);
- header->televisionHeader.black_gain = DPX_UNDEFINED_R32;
- header->televisionHeader.breakpoint = DPX_UNDEFINED_R32;
+ header->televisionHeader.black_gain = swap_float(DPX_UNDEFINED_R32, dpx->isMSB);
+ header->televisionHeader.breakpoint = swap_float(DPX_UNDEFINED_R32, dpx->isMSB);
header->televisionHeader.white_level = swap_float(dpx->referenceWhite, dpx->isMSB);
- header->televisionHeader.integration_times = DPX_UNDEFINED_R32;
+ header->televisionHeader.integration_times = swap_float(DPX_UNDEFINED_R32, dpx->isMSB);
}
LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t bufferSize)
@@ -339,13 +339,11 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf
dpx->element[i].refHighData = (unsigned int)dpx->element[i].maxValue;
}
- if (dpx->element[i].refLowQuantity == DPX_UNDEFINED_R32 ||
- isnan(dpx->element[i].refLowQuantity)) {
+ if (IS_DPX_UNDEFINED_R32(dpx->element[i].refLowQuantity)) {
dpx->element[i].refLowQuantity = 0.0f;
}
- if (dpx->element[i].refHighQuantity == DPX_UNDEFINED_R32 ||
- isnan(dpx->element[i].refHighQuantity)) {
+ if (IS_DPX_UNDEFINED_R32(dpx->element[i].refHighQuantity)) {
if (ELEM(dpx->element[i].transfer, transfer_PrintingDensity, transfer_Logarithmic)) {
dpx->element[i].refHighQuantity = 2.048f;
}
@@ -370,13 +368,11 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf
dpx->element[i].refHighData = 235.0f / 255.0f * dpx->element[i].maxValue;
}
- if (dpx->element[i].refLowQuantity == DPX_UNDEFINED_R32 ||
- isnan(dpx->element[i].refLowQuantity)) {
+ if (IS_DPX_UNDEFINED_R32(dpx->element[i].refLowQuantity)) {
dpx->element[i].refLowQuantity = 0.0f;
}
- if (dpx->element[i].refHighQuantity == DPX_UNDEFINED_R32 ||
- isnan(dpx->element[i].refHighQuantity)) {
+ if (IS_DPX_UNDEFINED_R32(dpx->element[i].refHighQuantity)) {
dpx->element[i].refHighQuantity = 0.7f;
}
@@ -391,10 +387,9 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf
dpx->referenceWhite = swap_float(header.televisionHeader.white_level, dpx->isMSB);
dpx->gamma = swap_float(header.televisionHeader.gamma, dpx->isMSB);
- if ((dpx->referenceBlack == DPX_UNDEFINED_R32 || isnan(dpx->referenceBlack)) ||
- (dpx->referenceWhite == DPX_UNDEFINED_R32 || dpx->referenceWhite <= dpx->referenceBlack ||
- isnan(dpx->referenceWhite)) ||
- (dpx->gamma == DPX_UNDEFINED_R32 || dpx->gamma <= 0 || isnan(dpx->gamma))) {
+ if (IS_DPX_UNDEFINED_R32(dpx->referenceBlack) ||
+ (dpx->referenceWhite <= dpx->referenceBlack || IS_DPX_UNDEFINED_R32(dpx->referenceWhite)) ||
+ (dpx->gamma <= 0 || IS_DPX_UNDEFINED_R32(dpx->gamma))) {
dpx->referenceBlack = 95.0f / 1023.0f * dpx->element[0].maxValue;
dpx->referenceWhite = 685.0f / 1023.0f * dpx->element[0].maxValue;
dpx->gamma = 1.7f;
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.h b/source/blender/imbuf/intern/cineon/dpxlib.h
index 6b729dba59a..1228ac4ee66 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.h
+++ b/source/blender/imbuf/intern/cineon/dpxlib.h
@@ -24,6 +24,8 @@
#pragma once
+#include <math.h>
+
#include "logImageCore.h"
#ifdef __cplusplus
@@ -34,7 +36,8 @@ extern "C" {
#define DPX_UNDEFINED_U8 0xFF
#define DPX_UNDEFINED_U16 0xFFFF
#define DPX_UNDEFINED_U32 0xFFFFFFFF
-#define DPX_UNDEFINED_R32 0xFFFFFFFF
+#define DPX_UNDEFINED_R32 NAN
+#define IS_DPX_UNDEFINED_R32(x) isnan(x)
#define DPX_UNDEFINED_CHAR 0
typedef struct {
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.cpp b/source/blender/imbuf/intern/dds/BlockDXT.cpp
index 2d9c300a147..4e4fca864a0 100644
--- a/source/blender/imbuf/intern/dds/BlockDXT.cpp
+++ b/source/blender/imbuf/intern/dds/BlockDXT.cpp
@@ -608,8 +608,8 @@ void mem_read(Stream &mem, BlockDXT1 &block)
void mem_read(Stream &mem, AlphaBlockDXT3 &block)
{
- for (unsigned int i = 0; i < 4; i++) {
- mem_read(mem, block.row[i]);
+ for (unsigned short &alpha : block.row) {
+ mem_read(mem, alpha);
}
}
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.cpp b/source/blender/imbuf/intern/dds/ColorBlock.cpp
index 7c8b7c1d345..00fa0111d1c 100644
--- a/source/blender/imbuf/intern/dds/ColorBlock.cpp
+++ b/source/blender/imbuf/intern/dds/ColorBlock.cpp
@@ -150,12 +150,12 @@ static inline uint8 component(Color32 c, uint i)
void ColorBlock::swizzle(uint x, uint y, uint z, uint w)
{
- for (int i = 0; i < 16; i++) {
- Color32 c = m_color[i];
- m_color[i].r = component(c, x);
- m_color[i].g = component(c, y);
- m_color[i].b = component(c, z);
- m_color[i].a = component(c, w);
+ for (Color32 &color : m_color) {
+ const Color32 c = color;
+ color.r = component(c, x);
+ color.g = component(c, y);
+ color.b = component(c, z);
+ color.a = component(c, w);
}
}
@@ -243,8 +243,8 @@ Color32 ColorBlock::averageColor() const
/** Return true if the block is not fully opaque. */
bool ColorBlock::hasAlpha() const
{
- for (uint i = 0; i < 16; i++) {
- if (m_color[i].a != 255) {
+ for (const auto &i : m_color) {
+ if (i.a != 255) {
return true;
}
}
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
index 37e30d30e2c..2a36946df8f 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
@@ -52,9 +52,9 @@
#include <DirectDrawSurface.h>
#include <PixelFormat.h>
-#include <math.h> /* sqrt */
-#include <stdio.h> /* printf */
-#include <stdlib.h> /* malloc */
+#include <cmath> /* sqrt */
+#include <cstdio> /* printf */
+#include <cstdlib> /* malloc */
#include <sys/types.h>
/*** declarations ***/
diff --git a/source/blender/imbuf/intern/dds/FlipDXT.cpp b/source/blender/imbuf/intern/dds/FlipDXT.cpp
index 9b07084bf81..2acf072556a 100644
--- a/source/blender/imbuf/intern/dds/FlipDXT.cpp
+++ b/source/blender/imbuf/intern/dds/FlipDXT.cpp
@@ -36,7 +36,7 @@
#include "IMB_imbuf_types.h"
-#include <string.h>
+#include <cstring>
#include <BlockDXT.h>
#include <ColorBlock.h>
@@ -45,7 +45,7 @@
#include <Stream.h>
/* A function that flips a DXTC block. */
-typedef void (*FlipBlockFunction)(uint8_t *block);
+using FlipBlockFunction = void (*)(uint8_t *block);
/* Flips a full DXT1 block in the y direction. */
static void FlipDXT1BlockFull(uint8_t *block)
diff --git a/source/blender/imbuf/intern/dds/Image.cpp b/source/blender/imbuf/intern/dds/Image.cpp
index 7958a586c7d..9dfa5dd2621 100644
--- a/source/blender/imbuf/intern/dds/Image.cpp
+++ b/source/blender/imbuf/intern/dds/Image.cpp
@@ -30,7 +30,7 @@
#include <Color.h>
#include <Image.h>
-#include <stdio.h> /* printf */
+#include <cstdio> /* printf */
Image::Image() : m_width(0), m_height(0), m_format(Format_RGB), m_data(nullptr)
{
diff --git a/source/blender/imbuf/intern/dds/Stream.cpp b/source/blender/imbuf/intern/dds/Stream.cpp
index 59892a0a228..3dab3c35675 100644
--- a/source/blender/imbuf/intern/dds/Stream.cpp
+++ b/source/blender/imbuf/intern/dds/Stream.cpp
@@ -20,8 +20,8 @@
#include <Stream.h>
-#include <stdio.h> /* printf */
-#include <string.h> /* memcpy */
+#include <cstdio> /* printf */
+#include <cstring> /* memcpy */
static const char *msg_error_seek = "DDS: trying to seek beyond end of stream (corrupt file?)";
static const char *msg_error_read = "DDS: trying to read beyond end of stream (corrupt file?)";
diff --git a/source/blender/imbuf/intern/dds/dds_api.cpp b/source/blender/imbuf/intern/dds/dds_api.cpp
index 804d8130b4c..e767cb14b1a 100644
--- a/source/blender/imbuf/intern/dds/dds_api.cpp
+++ b/source/blender/imbuf/intern/dds/dds_api.cpp
@@ -23,10 +23,10 @@
#include <DirectDrawSurface.h>
#include <FlipDXT.h>
#include <Stream.h>
+#include <cstddef>
+#include <cstdio> /* printf */
#include <dds_api.h>
#include <fstream>
-#include <stddef.h>
-#include <stdio.h> /* printf */
#if defined(WIN32)
# include "utfconv.h"
diff --git a/source/blender/imbuf/intern/oiio/CMakeLists.txt b/source/blender/imbuf/intern/oiio/CMakeLists.txt
index 211b6a0b40e..ee5848dec36 100644
--- a/source/blender/imbuf/intern/oiio/CMakeLists.txt
+++ b/source/blender/imbuf/intern/oiio/CMakeLists.txt
@@ -49,6 +49,7 @@ if(WITH_OPENIMAGEIO)
)
list(APPEND LIB
${OPENIMAGEIO_LIBRARIES}
+ ${PUGIXML_LIBRARIES}
)
if(WITH_IMAGE_OPENEXR)
list(APPEND INC_SYS
diff --git a/source/blender/imbuf/intern/oiio/openimageio_api.cpp b/source/blender/imbuf/intern/oiio/openimageio_api.cpp
index 1e8c3c25778..65c25194477 100644
--- a/source/blender/imbuf/intern/oiio/openimageio_api.cpp
+++ b/source/blender/imbuf/intern/oiio/openimageio_api.cpp
@@ -48,7 +48,7 @@ OIIO_NAMESPACE_USING
using std::string;
using std::unique_ptr;
-typedef unsigned char uchar;
+using uchar = unsigned char;
template<class T, class Q>
static void fill_all_channels(T *pixels, int width, int height, int components, Q alpha)
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 56188fbe98a..9726eaeed2c 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -22,14 +22,14 @@
*/
#include <algorithm>
-#include <errno.h>
+#include <cerrno>
+#include <cstddef>
+#include <cstdio>
+#include <cstdlib>
#include <fstream>
#include <iostream>
#include <set>
-#include <stddef.h>
#include <stdexcept>
-#include <stdio.h>
-#include <stdlib.h>
#include <string>
#include <Iex.h>
@@ -120,11 +120,11 @@ class IMemStream : public Imf::IStream {
_exrbuf = exrbuf;
}
- virtual ~IMemStream()
+ ~IMemStream() override
{
}
- virtual bool read(char c[], int n)
+ bool read(char c[], int n) override
{
if (n + _exrpos <= _exrsize) {
memcpy(c, (void *)(&_exrbuf[_exrpos]), n);
@@ -135,17 +135,17 @@ class IMemStream : public Imf::IStream {
return false;
}
- virtual Int64 tellg()
+ Int64 tellg() override
{
return _exrpos;
}
- virtual void seekg(Int64 pos)
+ void seekg(Int64 pos) override
{
_exrpos = pos;
}
- virtual void clear()
+ void clear() override
{
}
@@ -175,7 +175,7 @@ class IFileStream : public Imf::IStream {
}
}
- virtual bool read(char c[], int n)
+ bool read(char c[], int n) override
{
if (!ifs) {
throw Iex::InputExc("Unexpected end of file.");
@@ -186,18 +186,18 @@ class IFileStream : public Imf::IStream {
return check_error();
}
- virtual Int64 tellg()
+ Int64 tellg() override
{
return std::streamoff(ifs.tellg());
}
- virtual void seekg(Int64 pos)
+ void seekg(Int64 pos) override
{
ifs.seekg(pos);
check_error();
}
- virtual void clear()
+ void clear() override
{
ifs.clear();
}
@@ -227,7 +227,7 @@ class OMemStream : public OStream {
{
}
- virtual void write(const char c[], int n)
+ void write(const char c[], int n) override
{
ensure_size(offset + n);
memcpy(ibuf->encodedbuffer + offset, c, n);
@@ -235,12 +235,12 @@ class OMemStream : public OStream {
ibuf->encodedsize += n;
}
- virtual Int64 tellp()
+ Int64 tellp() override
{
return offset;
}
- virtual void seekp(Int64 pos)
+ void seekp(Int64 pos) override
{
offset = pos;
ensure_size(offset);
@@ -281,19 +281,19 @@ class OFileStream : public OStream {
}
}
- virtual void write(const char c[], int n)
+ void write(const char c[], int n) override
{
errno = 0;
ofs.write(c, n);
check_error();
}
- virtual Int64 tellp()
+ Int64 tellp() override
{
return std::streamoff(ofs.tellp());
}
- virtual void seekp(Int64 pos)
+ void seekp(Int64 pos) override
{
ofs.seekp(pos);
check_error();
@@ -322,7 +322,7 @@ struct _RGBAZ {
half z;
};
-typedef struct _RGBAZ RGBAZ;
+using RGBAZ = _RGBAZ;
extern "C" {
@@ -620,7 +620,7 @@ bool imb_save_openexr(struct ImBuf *ibuf, const char *name, int flags)
static ListBase exrhandles = {nullptr, nullptr};
-typedef struct ExrHandle {
+struct ExrHandle {
struct ExrHandle *next, *prev;
char name[FILE_MAX];
@@ -645,10 +645,10 @@ typedef struct ExrHandle {
ListBase layers; /* hierarchical, pointing in end to ExrChannel */
int num_half_channels; /* used during filr save, allows faster temporary buffers allocation */
-} ExrHandle;
+};
/* flattened out channel */
-typedef struct ExrChannel {
+struct ExrChannel {
struct ExrChannel *next, *prev;
char name[EXR_TOT_MAXNAME + 1]; /* full name with everything */
@@ -658,10 +658,10 @@ typedef struct ExrChannel {
char chan_id; /* quick lookup of channel char */
int view_id; /* quick lookup of channel view */
bool use_half_float; /* when saving use half float for file storage */
-} ExrChannel;
+};
/* hierarchical; layers -> passes -> channels[] */
-typedef struct ExrPass {
+struct ExrPass {
struct ExrPass *next, *prev;
char name[EXR_PASS_MAXNAME];
int totchan;
@@ -672,13 +672,13 @@ typedef struct ExrPass {
char internal_name[EXR_PASS_MAXNAME]; /* name with no view */
char view[EXR_VIEW_MAXNAME];
int view_id;
-} ExrPass;
+};
-typedef struct ExrLayer {
+struct ExrLayer {
struct ExrLayer *next, *prev;
char name[EXR_LAY_MAXNAME + 1];
ListBase passes;
-} ExrLayer;
+};
/* ********************** */
@@ -733,8 +733,8 @@ static void imb_exr_get_views(MultiPartInputFile &file, StringVector &views)
if (exr_has_multipart_file(file) == false) {
if (exr_has_multiview(file)) {
StringVector sv = multiView(file.header(0));
- for (StringVector::const_iterator i = sv.begin(); i != sv.end(); ++i) {
- views.push_back(*i);
+ for (const std::string &view_name : sv) {
+ views.push_back(view_name);
}
}
}
@@ -991,21 +991,15 @@ int IMB_exr_begin_read(void *handle, const char *filename, int *width, int *heig
std::vector<MultiViewChannelName> channels;
GetChannelsInMultiPartFile(*data->ifile, channels);
- for (size_t i = 0; i < channels.size(); i++) {
- IMB_exr_add_channel(data,
- nullptr,
- channels[i].name.c_str(),
- channels[i].view.c_str(),
- 0,
- 0,
- nullptr,
- false);
+ for (const MultiViewChannelName &channel : channels) {
+ IMB_exr_add_channel(
+ data, nullptr, channel.name.c_str(), channel.view.c_str(), 0, 0, nullptr, false);
echan = (ExrChannel *)data->channels.last;
- echan->m->name = channels[i].name;
- echan->m->view = channels[i].view;
- echan->m->part_number = channels[i].part_number;
- echan->m->internal_name = channels[i].internal_name;
+ echan->m->name = channel.name;
+ echan->m->view = channel.view;
+ echan->m->part_number = channel.part_number;
+ echan->m->internal_name = channel.internal_name;
}
return 1;
@@ -1311,9 +1305,8 @@ void IMB_exr_multilayer_convert(void *handle,
}
else {
/* add views to RenderResult */
- for (StringVector::const_iterator i = data->multiView->begin(); i != data->multiView->end();
- ++i) {
- addview(base, (*i).c_str());
+ for (const std::string &view_name : *data->multiView) {
+ addview(base, view_name.c_str());
}
}
@@ -1554,15 +1547,15 @@ static ExrHandle *imb_exr_begin_read_mem(IStream &file_stream,
imb_exr_get_views(*data->ifile, *data->multiView);
- for (size_t i = 0; i < channels.size(); i++) {
+ for (const MultiViewChannelName &channel : channels) {
IMB_exr_add_channel(
- data, nullptr, channels[i].name.c_str(), channels[i].view.c_str(), 0, 0, nullptr, false);
+ data, nullptr, channel.name.c_str(), channel.view.c_str(), 0, 0, nullptr, false);
echan = (ExrChannel *)data->channels.last;
- echan->m->name = channels[i].name;
- echan->m->view = channels[i].view;
- echan->m->part_number = channels[i].part_number;
- echan->m->internal_name = channels[i].internal_name;
+ echan->m->name = channel.name;
+ echan->m->view = channel.view;
+ echan->m->part_number = channel.part_number;
+ echan->m->internal_name = channel.internal_name;
}
/* now try to sort out how to assign memory to the channels */
@@ -1689,8 +1682,8 @@ static void exr_print_filecontents(MultiPartInputFile &file)
const StringVector views = multiView(file.header(0));
printf("OpenEXR-load: MultiView file\n");
printf("OpenEXR-load: Default view: %s\n", defaultViewName(views).c_str());
- for (StringVector::const_iterator i = views.begin(); i != views.end(); ++i) {
- printf("OpenEXR-load: Found view %s\n", (*i).c_str());
+ for (const std::string &view : views) {
+ printf("OpenEXR-load: Found view %s\n", view.c_str());
}
}
else if (numparts > 1) {
@@ -1835,10 +1828,10 @@ static void imb_exr_type_by_channels(ChannelList &channels,
* with non-empty ones in the file.
*/
for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); i++) {
- for (std::set<string>::iterator i = layerNames.begin(); i != layerNames.end(); i++) {
+ for (const std::string &layer_name : layerNames) {
/* see if any layername differs from a viewname */
- if (imb_exr_get_multiView_id(views, *i) == -1) {
- std::string layerName = *i;
+ if (imb_exr_get_multiView_id(views, layer_name) == -1) {
+ std::string layerName = layer_name;
size_t pos = layerName.rfind('.');
if (pos == std::string::npos) {
diff --git a/source/blender/imbuf/intern/thumbs_blend.c b/source/blender/imbuf/intern/thumbs_blend.c
index 1d0964ebb62..d5ded02be62 100644
--- a/source/blender/imbuf/intern/thumbs_blend.c
+++ b/source/blender/imbuf/intern/thumbs_blend.c
@@ -68,7 +68,7 @@ ImBuf *IMB_thumb_load_blend(const char *blen_path, const char *blen_group, const
printf("%s: error, found %d items, %d previews\n", __func__, nnames, nprevs);
}
BLI_linklist_free(previews, BKE_previewimg_freefunc);
- BLI_linklist_free(names, free);
+ BLI_linklist_freeN(names);
return ima;
}
@@ -93,7 +93,7 @@ ImBuf *IMB_thumb_load_blend(const char *blen_path, const char *blen_group, const
}
BLI_linklist_free(previews, BKE_previewimg_freefunc);
- BLI_linklist_free(names, free);
+ BLI_linklist_freeN(names);
}
else {
BlendThumbnail *data;
diff --git a/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc b/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc
index 334a26df784..8073e157c13 100644
--- a/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc
+++ b/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc
@@ -18,7 +18,7 @@
*/
#include "abc_subdiv_disabler.h"
-#include <stdio.h>
+#include <cstdio>
#include "BLI_listbase.h"
diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc
index 14c3d756d56..0b9636ffb70 100644
--- a/source/blender/io/alembic/intern/abc_reader_mesh.cc
+++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc
@@ -724,9 +724,7 @@ void AbcMeshReader::assign_facesets_to_mpoly(const ISampleSelector &sample_sel,
int current_mat = 0;
- for (int i = 0; i < face_sets.size(); i++) {
- const std::string &grp_name = face_sets[i];
-
+ for (const std::string &grp_name : face_sets) {
if (r_mat_map.find(grp_name) == r_mat_map.end()) {
r_mat_map[grp_name] = ++current_mat;
}
diff --git a/source/blender/io/alembic/tests/abc_export_test.cc b/source/blender/io/alembic/tests/abc_export_test.cc
index e1a9bd34f6b..e20fe2ff492 100644
--- a/source/blender/io/alembic/tests/abc_export_test.cc
+++ b/source/blender/io/alembic/tests/abc_export_test.cc
@@ -23,7 +23,7 @@ class AlembicExportTest : public testing::Test {
Depsgraph *depsgraph;
Main *bmain;
- virtual void SetUp()
+ void SetUp() override
{
abc_archive = nullptr;
@@ -41,7 +41,7 @@ class AlembicExportTest : public testing::Test {
depsgraph = DEG_graph_new(bmain, &scene, view_layer, DAG_EVAL_RENDER);
}
- virtual void TearDown()
+ void TearDown() override
{
BKE_main_free(bmain);
DEG_graph_free(depsgraph);
diff --git a/source/blender/io/collada/AnimationImporter.cpp b/source/blender/io/collada/AnimationImporter.cpp
index 2e7977d89bb..77ccdeae28d 100644
--- a/source/blender/io/collada/AnimationImporter.cpp
+++ b/source/blender/io/collada/AnimationImporter.cpp
@@ -18,7 +18,7 @@
* \ingroup collada
*/
-#include <stddef.h>
+#include <cstddef>
/* COLLADABU_ASSERT, may be able to remove later */
#include "COLLADABUPlatform.h"
@@ -272,9 +272,8 @@ void AnimationImporter::add_fcurves_to_object(Main *bmain,
AnimationImporter::~AnimationImporter()
{
/* free unused FCurves */
- for (std::vector<FCurve *>::iterator it = unused_curves.begin(); it != unused_curves.end();
- it++) {
- BKE_fcurve_free(*it);
+ for (FCurve *unused_curve : unused_curves) {
+ BKE_fcurve_free(unused_curve);
}
if (!unused_curves.empty()) {
@@ -2035,8 +2034,8 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm,
COLLADABU::Math::Matrix4 matrix;
int mi = 0, mj = 0;
- for (std::vector<FCurve *>::iterator it = curves.begin(); it != curves.end(); it++) {
- matrix.setElement(mi, mj, evaluate_fcurve(*it, fra));
+ for (FCurve *curve : curves) {
+ matrix.setElement(mi, mj, evaluate_fcurve(curve, fra));
mj++;
if (mj == 4) {
mi++;
diff --git a/source/blender/io/collada/BCAnimationCurve.cpp b/source/blender/io/collada/BCAnimationCurve.cpp
index 33eaf3376cd..5065accf554 100644
--- a/source/blender/io/collada/BCAnimationCurve.cpp
+++ b/source/blender/io/collada/BCAnimationCurve.cpp
@@ -173,8 +173,14 @@ std::string BCAnimationCurve::get_animation_name(Object *ob) const
name = "";
}
else {
- const char *boneName = BLI_str_quoted_substrN(fcurve->rna_path, "pose.bones[");
- name = (boneName) ? id_name(ob) + "_" + std::string(boneName) : "";
+ char *boneName = BLI_str_quoted_substrN(fcurve->rna_path, "pose.bones[");
+ if (boneName) {
+ name = id_name(ob) + "_" + std::string(boneName);
+ MEM_freeN(boneName);
+ }
+ else {
+ name = "";
+ }
}
} break;
diff --git a/source/blender/io/collada/BCAnimationSampler.cpp b/source/blender/io/collada/BCAnimationSampler.cpp
index abc770ceef5..a6ee0b8bee6 100644
--- a/source/blender/io/collada/BCAnimationSampler.cpp
+++ b/source/blender/io/collada/BCAnimationSampler.cpp
@@ -448,6 +448,7 @@ void BCAnimationSampler::initialize_curves(BCAnimationCurveMap &curves, Object *
char *boneName = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
if (boneName) {
object_type = BC_ANIMATION_TYPE_BONE;
+ MEM_freeN(boneName);
}
}
diff --git a/source/blender/io/collada/BCMath.cpp b/source/blender/io/collada/BCMath.cpp
index 8a3fbf3c92c..0521fda5fb1 100644
--- a/source/blender/io/collada/BCMath.cpp
+++ b/source/blender/io/collada/BCMath.cpp
@@ -157,20 +157,20 @@ void BCMatrix::transpose(Matrix &mat)
void BCMatrix::sanitize(Matrix &mat, int precision)
{
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- double val = (double)mat[i][j];
+ for (auto &row : mat) {
+ for (float &cell : row) {
+ double val = (double)cell;
val = double_round(val, precision);
- mat[i][j] = (float)val;
+ cell = (float)val;
}
}
}
void BCMatrix::sanitize(DMatrix &mat, int precision)
{
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- mat[i][j] = double_round(mat[i][j], precision);
+ for (auto &row : mat) {
+ for (double &cell : row) {
+ cell = double_round(cell, precision);
}
}
}
diff --git a/source/blender/io/collada/BlenderContext.cpp b/source/blender/io/collada/BlenderContext.cpp
index 8009f10aa03..ab420e79ba7 100644
--- a/source/blender/io/collada/BlenderContext.cpp
+++ b/source/blender/io/collada/BlenderContext.cpp
@@ -81,8 +81,8 @@ bool bc_is_in_Export_set(LinkNode *export_set, Object *ob, ViewLayer *view_layer
std::vector<Object *> children;
bc_get_children(children, ob, view_layer);
- for (int i = 0; i < children.size(); i++) {
- if (bc_is_in_Export_set(export_set, children[i], view_layer)) {
+ for (Object *child : children) {
+ if (bc_is_in_Export_set(export_set, child, view_layer)) {
to_export = true;
break;
}
diff --git a/source/blender/io/collada/ControllerExporter.cpp b/source/blender/io/collada/ControllerExporter.cpp
index 52d4bbf122e..6f0d422dbe2 100644
--- a/source/blender/io/collada/ControllerExporter.cpp
+++ b/source/blender/io/collada/ControllerExporter.cpp
@@ -245,9 +245,9 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm)
if (sumw > 0.0f) {
float invsumw = 1.0f / sumw;
vcounts.push_back(jw.size());
- for (std::map<int, float>::iterator m = jw.begin(); m != jw.end(); ++m) {
- joints.push_back((*m).first);
- weights.push_back(invsumw * (*m).second);
+ for (auto &index_and_weight : jw) {
+ joints.push_back(index_and_weight.first);
+ weights.push_back(invsumw * index_and_weight.second);
}
}
else {
@@ -596,8 +596,8 @@ std::string ControllerExporter::add_weights_source(Mesh *me,
source.prepareToAppendValues();
- for (std::list<float>::const_iterator i = weights.begin(); i != weights.end(); ++i) {
- source.appendValues(*i);
+ for (float weight : weights) {
+ source.appendValues(weight);
}
source.finish();
@@ -638,8 +638,8 @@ void ControllerExporter::add_vertex_weights_element(const std::string &weights_s
/* write deformer index - weight index pairs */
int weight_index = 0;
- for (std::list<int>::const_iterator i = joints.begin(); i != joints.end(); ++i) {
- weightselem.appendValues(*i, weight_index++);
+ for (int joint_index : joints) {
+ weightselem.appendValues(joint_index, weight_index++);
}
weightselem.finish();
diff --git a/source/blender/io/collada/DocumentExporter.cpp b/source/blender/io/collada/DocumentExporter.cpp
index 241afbd4034..46dfdda4ede 100644
--- a/source/blender/io/collada/DocumentExporter.cpp
+++ b/source/blender/io/collada/DocumentExporter.cpp
@@ -19,9 +19,9 @@
*/
#include <algorithm> /* std::find */
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
#include <vector>
#include "COLLADASWAsset.h"
@@ -121,7 +121,7 @@ extern "C" char build_hash[];
#include "MaterialExporter.h"
#include "SceneExporter.h"
-#include <errno.h>
+#include <cerrno>
char *bc_CustomData_get_layer_name(const struct CustomData *data, int type, int n)
{
diff --git a/source/blender/io/collada/DocumentImporter.cpp b/source/blender/io/collada/DocumentImporter.cpp
index b85a96d89de..10c1a90576c 100644
--- a/source/blender/io/collada/DocumentImporter.cpp
+++ b/source/blender/io/collada/DocumentImporter.cpp
@@ -241,10 +241,8 @@ void DocumentImporter::finish()
armature_importer.fix_animation();
#endif
- for (std::vector<const COLLADAFW::VisualScene *>::iterator vsit = vscenes.begin();
- vsit != vscenes.end();
- vsit++) {
- const COLLADAFW::NodePointerArray &roots = (*vsit)->getRootNodes();
+ for (const COLLADAFW::VisualScene *vscene : vscenes) {
+ const COLLADAFW::NodePointerArray &roots = vscene->getRootNodes();
for (unsigned int i = 0; i < roots.getCount(); i++) {
translate_anim_recursive(roots[i], nullptr, nullptr);
@@ -665,9 +663,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node,
goto finally;
}
- for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end();
- ++it) {
- ob = *it;
+ for (Object *ob : *objects_done) {
std::string nodename = node->getName().empty() ? node->getOriginalId() : node->getName();
BKE_libblock_rename(bmain, &ob->id, (char *)nodename.c_str());
object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), ob));
@@ -681,10 +677,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node,
/* create_constraints(et,ob); */
}
- for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end();
- ++it) {
- ob = *it;
-
+ for (Object *ob : *objects_done) {
if (read_transform) {
anim_importer.read_node_transform(node, ob); /* overwrites location set earlier */
}
diff --git a/source/blender/io/collada/ErrorHandler.cpp b/source/blender/io/collada/ErrorHandler.cpp
index 7467d519f28..844065e3ba3 100644
--- a/source/blender/io/collada/ErrorHandler.cpp
+++ b/source/blender/io/collada/ErrorHandler.cpp
@@ -26,7 +26,7 @@
#include "GeneratedSaxParserParserError.h"
-#include <string.h>
+#include <cstring>
#include "BLI_utildefines.h"
diff --git a/source/blender/io/collada/ExtraHandler.cpp b/source/blender/io/collada/ExtraHandler.cpp
index 8aefb321dd6..11cb75fb5e9 100644
--- a/source/blender/io/collada/ExtraHandler.cpp
+++ b/source/blender/io/collada/ExtraHandler.cpp
@@ -19,7 +19,7 @@
*/
#include "BLI_string.h"
-#include <stddef.h>
+#include <cstddef>
#include "ExtraHandler.h"
diff --git a/source/blender/io/collada/ExtraTags.cpp b/source/blender/io/collada/ExtraTags.cpp
index d8fbf96db51..8c63a21f88a 100644
--- a/source/blender/io/collada/ExtraTags.cpp
+++ b/source/blender/io/collada/ExtraTags.cpp
@@ -19,8 +19,8 @@
*/
#include "BLI_string.h"
-#include <stddef.h>
-#include <stdlib.h>
+#include <cstddef>
+#include <cstdlib>
#include <iostream>
diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp
index bb2aabb0598..2934ea1caa6 100644
--- a/source/blender/io/collada/MeshImporter.cpp
+++ b/source/blender/io/collada/MeshImporter.cpp
@@ -973,9 +973,7 @@ static void bc_remove_materials_from_object(Object *ob, Mesh *me)
std::vector<Object *> MeshImporter::get_all_users_of(Mesh *reference_mesh)
{
std::vector<Object *> mesh_users;
- for (std::vector<Object *>::iterator it = imported_objects.begin(); it != imported_objects.end();
- ++it) {
- Object *ob = (*it);
+ for (Object *ob : imported_objects) {
if (bc_is_marked(ob)) {
bc_remove_mark(ob);
Mesh *me = (Mesh *)ob->data;
@@ -1007,9 +1005,7 @@ std::vector<Object *> MeshImporter::get_all_users_of(Mesh *reference_mesh)
*/
void MeshImporter::optimize_material_assignements()
{
- for (std::vector<Object *>::iterator it = imported_objects.begin(); it != imported_objects.end();
- ++it) {
- Object *ob = (*it);
+ for (Object *ob : imported_objects) {
Mesh *me = (Mesh *)ob->data;
if (ID_REAL_USERS(&me->id) == 1) {
bc_copy_materials_to_data(ob, me);
@@ -1029,8 +1025,7 @@ void MeshImporter::optimize_material_assignements()
}
if (can_move) {
bc_copy_materials_to_data(ref_ob, me);
- for (int index = 0; index < mesh_users.size(); index++) {
- Object *object = mesh_users[index];
+ for (Object *object : mesh_users) {
bc_remove_materials_from_object(object, me);
bc_remove_mark(object);
}
diff --git a/source/blender/io/collada/SceneExporter.cpp b/source/blender/io/collada/SceneExporter.cpp
index 01c270518e9..5bbd22b8275 100644
--- a/source/blender/io/collada/SceneExporter.cpp
+++ b/source/blender/io/collada/SceneExporter.cpp
@@ -86,8 +86,7 @@ void SceneExporter::writeNodeList(std::vector<Object *> &child_objects, Object *
* I really prefer to enforce the export of hidden
* elements in an object hierarchy. When the children of
* the hidden elements are exported as well. */
- for (int i = 0; i < child_objects.size(); i++) {
- Object *child = child_objects[i];
+ for (auto *child : child_objects) {
writeNode(child);
if (bc_is_marked(child)) {
bc_remove_mark(child);
diff --git a/source/blender/io/collada/SkinInfo.cpp b/source/blender/io/collada/SkinInfo.cpp
index 19a4a4f61c2..8f6f1e467d9 100644
--- a/source/blender/io/collada/SkinInfo.cpp
+++ b/source/blender/io/collada/SkinInfo.cpp
@@ -21,7 +21,7 @@
#include <algorithm>
#if !defined(WIN32)
-# include <stdint.h>
+# include <cstdint>
#endif
/* COLLADABU_ASSERT, may be able to remove later */
diff --git a/source/blender/io/collada/collada_internal.cpp b/source/blender/io/collada/collada_internal.cpp
index 096f6a678ac..787af933e8f 100644
--- a/source/blender/io/collada/collada_internal.cpp
+++ b/source/blender/io/collada/collada_internal.cpp
@@ -205,7 +205,7 @@ const unsigned char translate_name_map[256] = {
242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
};
-typedef std::map<std::string, std::vector<std::string>> map_string_list;
+using map_string_list = std::map<std::string, std::vector<std::string>>;
map_string_list global_id_map;
void clear_global_id_map()
@@ -280,8 +280,7 @@ std::string encode_xml(std::string xml)
std::map<char, std::string>::const_iterator it;
std::string encoded_xml;
- for (unsigned int i = 0; i < xml.size(); i++) {
- char c = xml.at(i);
+ for (char c : xml) {
it = escape.find(c);
if (it == escape.end()) {
diff --git a/source/blender/io/collada/collada_utils.cpp b/source/blender/io/collada/collada_utils.cpp
index c57952afcc8..ad1cc1035fb 100644
--- a/source/blender/io/collada/collada_utils.cpp
+++ b/source/blender/io/collada/collada_utils.cpp
@@ -379,11 +379,9 @@ void bc_match_scale(std::vector<Object *> *objects_done,
UnitConverter &bc_unit,
bool scale_to_scene)
{
- for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end();
- ++it) {
- Object *ob = *it;
+ for (Object *ob : *objects_done) {
if (ob->parent == nullptr) {
- bc_match_scale(*it, bc_unit, scale_to_scene);
+ bc_match_scale(ob, bc_unit, scale_to_scene);
}
}
}
@@ -524,10 +522,8 @@ BoneExtensionManager::~BoneExtensionManager()
std::map<std::string, BoneExtensionMap *>::iterator map_it;
for (map_it = extended_bone_maps.begin(); map_it != extended_bone_maps.end(); ++map_it) {
BoneExtensionMap *extended_bones = map_it->second;
- for (BoneExtensionMap::iterator ext_it = extended_bones->begin();
- ext_it != extended_bones->end();
- ++ext_it) {
- delete ext_it->second;
+ for (auto &extended_bone : *extended_bones) {
+ delete extended_bone.second;
}
extended_bones->clear();
delete extended_bones;
@@ -1180,17 +1176,6 @@ static std::string bc_get_uvlayer_name(Mesh *me, int layer)
return "";
}
-std::string bc_find_bonename_in_path(std::string path, std::string probe)
-{
- std::string result;
- char *boneName = BLI_str_quoted_substrN(path.c_str(), probe.c_str());
- if (boneName) {
- result = std::string(boneName);
- MEM_freeN(boneName);
- }
- return result;
-}
-
static bNodeTree *prepare_material_nodetree(Material *ma)
{
if (ma->nodetree == nullptr) {
diff --git a/source/blender/io/collada/collada_utils.h b/source/blender/io/collada/collada_utils.h
index fa65d398954..d0a5d37d6d2 100644
--- a/source/blender/io/collada/collada_utils.h
+++ b/source/blender/io/collada/collada_utils.h
@@ -146,8 +146,6 @@ extern void bc_bubble_sort_by_Object_name(LinkNode *export_set);
extern bool bc_is_root_bone(Bone *aBone, bool deform_bones_only);
extern int bc_get_active_UVLayer(Object *ob);
-std::string bc_find_bonename_in_path(std::string path, std::string probe);
-
inline std::string bc_string_after(const std::string &s, const std::string probe)
{
size_t i = s.rfind(probe);
diff --git a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
index fc47b024be1..eaa4d2fdde7 100644
--- a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
+++ b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
@@ -19,10 +19,10 @@
#include "IO_abstract_hierarchy_iterator.h"
#include "dupli_parent_finder.hh"
+#include <climits>
+#include <cstdio>
#include <iostream>
-#include <limits.h>
#include <sstream>
-#include <stdio.h>
#include <string>
#include "BKE_anim_data.h"
diff --git a/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc b/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc
index ad0d6820e2b..8acdba416d3 100644
--- a/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc
+++ b/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc
@@ -73,7 +73,7 @@ class TestingHierarchyIterator : public AbstractHierarchyIterator {
explicit TestingHierarchyIterator(Depsgraph *depsgraph) : AbstractHierarchyIterator(depsgraph)
{
}
- virtual ~TestingHierarchyIterator()
+ ~TestingHierarchyIterator() override
{
release_writers();
}
@@ -106,13 +106,13 @@ class AbstractHierarchyIteratorTest : public BlendfileLoadingBaseTest {
protected:
TestingHierarchyIterator *iterator;
- virtual void SetUp()
+ void SetUp() override
{
BlendfileLoadingBaseTest::SetUp();
iterator = nullptr;
}
- virtual void TearDown()
+ void TearDown() override
{
iterator_free();
BlendfileLoadingBaseTest::TearDown();
diff --git a/source/blender/io/common/intern/object_identifier.cc b/source/blender/io/common/intern/object_identifier.cc
index a2d2d998bec..5d0b89b0630 100644
--- a/source/blender/io/common/intern/object_identifier.cc
+++ b/source/blender/io/common/intern/object_identifier.cc
@@ -21,7 +21,7 @@
#include "BKE_duplilist.h"
extern "C" {
-#include <limits.h> /* For INT_MAX. */
+#include <climits> /* For INT_MAX. */
}
#include <cstring>
#include <sstream>
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index 9a31447dacd..17d41985f80 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -875,6 +875,10 @@ typedef enum eNlaTrack_Flag {
/** track is not allowed to execute,
* usually as result of tweaking being enabled (internal flag) */
NLATRACK_DISABLED = (1 << 10),
+
+ /** This NLA track is added to an override ID, which means it is fully editable.
+ * Irrelevant in case the owner ID is not an override. */
+ NLATRACK_OVERRIDELIBRARY_LOCAL = 1 << 16,
} eNlaTrack_Flag;
/* ************************************ */
diff --git a/source/blender/makesdna/DNA_brush_defaults.h b/source/blender/makesdna/DNA_brush_defaults.h
index b0a35ac783e..fb726e24929 100644
--- a/source/blender/makesdna/DNA_brush_defaults.h
+++ b/source/blender/makesdna/DNA_brush_defaults.h
@@ -45,6 +45,7 @@
.topology_rake_factor = 0.0f, \
.crease_pinch_factor = 0.5f, \
.normal_radius_factor = 0.5f, \
+ .wet_paint_radius_factor = 0.5f, \
.area_radius_factor = 0.5f, \
.disconnected_distance_max = 0.1f, \
.sculpt_plane = SCULPT_DISP_DIR_AREA, \
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 756f21321f4..7bd3c7d0117 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -402,6 +402,11 @@ typedef enum eBrushBoundaryFalloffType {
BRUSH_BOUNDARY_FALLOFF_LOOP_INVERT = 3,
} eBrushBoundaryFalloffType;
+typedef enum eBrushSnakeHookDeformType {
+ BRUSH_SNAKE_HOOK_DEFORM_FALLOFF = 0,
+ BRUSH_SNAKE_HOOK_DEFORM_ELASTIC = 1,
+} eBrushSnakeHookDeformType;
+
/* Gpencilsettings.Vertex_mode */
typedef enum eGp_Vertex_Mode {
/* Affect to Stroke only. */
@@ -585,6 +590,7 @@ typedef struct Brush {
float normal_radius_factor;
float area_radius_factor;
+ float wet_paint_radius_factor;
float plane_trim;
/** Affectable height of brush (layer height for layer tool, i.e.). */
@@ -606,6 +612,9 @@ typedef struct Brush {
int elastic_deform_type;
float elastic_deform_volume_preservation;
+ /* snake hook */
+ int snake_hook_deform_type;
+
/* pose */
int pose_deform_type;
float pose_offset;
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 70d33d9ff94..ddc1b3bd9d7 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -61,12 +61,17 @@ typedef struct bConstraint {
/** Space that target should be evaluated in (only used if 1 target). */
char tarspace;
- /** Constraint name, MAX_NAME. */
- char name[64];
-
/* An "expand" bit for each of the constraint's (sub)panels (uiPanelDataExpansion). */
short ui_expand_flag;
+ /** Object to use as target for Custom Space of owner. */
+ struct Object *space_object;
+ /** Subtarget for Custom Space of owner - pchan or vgroup name, MAX_ID_NAME-2. */
+ char space_subtarget[64];
+
+ /** Constraint name, MAX_NAME. */
+ char name[64];
+
/** Amount of influence exherted by constraint (0.0-1.0). */
float enforce;
/** Point along subtarget bone where the actual target is. 0=head (default for all), 1=tail. */
@@ -722,6 +727,8 @@ typedef enum eBConstraint_Flags {
typedef enum eBConstraint_SpaceTypes {
/** Default for all - worldspace. */
CONSTRAINT_SPACE_WORLD = 0,
+ /** For all - custom space. */
+ CONSTRAINT_SPACE_CUSTOM = 5,
/**
* For objects (relative to parent/without parent influence),
* for bones (along normals of bone, without parent/rest-positions).
diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h
index 85065ba35d4..6a91f4857b4 100644
--- a/source/blender/makesdna/DNA_layer_types.h
+++ b/source/blender/makesdna/DNA_layer_types.h
@@ -47,8 +47,31 @@ typedef enum eViewLayerEEVEEPassType {
EEVEE_RENDER_PASS_SHADOW = (1 << 12),
EEVEE_RENDER_PASS_AO = (1 << 13),
EEVEE_RENDER_PASS_BLOOM = (1 << 14),
+ EEVEE_RENDER_PASS_AOV = (1 << 15),
+ EEVEE_RENDER_PASS_CRYPTOMATTE = (1 << 16),
} eViewLayerEEVEEPassType;
-#define EEVEE_RENDER_PASS_MAX_BIT 15
+#define EEVEE_RENDER_PASS_MAX_BIT 17
+
+/* #ViewLayerAOV.type */
+typedef enum eViewLayerAOVType {
+ AOV_TYPE_VALUE = 0,
+ AOV_TYPE_COLOR = 1,
+} eViewLayerAOVType;
+
+/* #ViewLayerAOV.flag */
+typedef enum eViewLayerAOVFlag {
+ AOV_CONFLICT = (1 << 0),
+} eViewLayerAOVFlag;
+
+/* #ViewLayer.cryptomatte_flag */
+typedef enum eViewLayerCryptomatteFlags {
+ VIEW_LAYER_CRYPTOMATTE_OBJECT = (1 << 0),
+ VIEW_LAYER_CRYPTOMATTE_MATERIAL = (1 << 1),
+ VIEW_LAYER_CRYPTOMATTE_ASSET = (1 << 2),
+ VIEW_LAYER_CRYPTOMATTE_ACCURATE = (1 << 3),
+} eViewLayerCryptomatteFlags;
+#define VIEW_LAYER_CRYPTOMATTE_ALL \
+ (VIEW_LAYER_CRYPTOMATTE_OBJECT | VIEW_LAYER_CRYPTOMATTE_MATERIAL | VIEW_LAYER_CRYPTOMATTE_ASSET)
typedef struct Base {
struct Base *next, *prev;
@@ -104,6 +127,17 @@ typedef struct ViewLayerEEVEE {
int _pad[1];
} ViewLayerEEVEE;
+/* AOV Renderpass definition. */
+typedef struct ViewLayerAOV {
+ struct ViewLayerAOV *next, *prev;
+
+ /* Name of the AOV */
+ char name[64];
+ int flag;
+ /* Type of AOV (color/value)
+ * matches `eViewLayerAOVType` */
+ int type;
+} ViewLayerAOV;
typedef struct ViewLayer {
struct ViewLayer *next, *prev;
/** MAX_NAME. */
@@ -127,6 +161,10 @@ typedef struct ViewLayer {
/** Pass_xor has to be after passflag. */
int passflag;
float pass_alpha_threshold;
+ short cryptomatte_flag;
+ short cryptomatte_levels;
+ char _pad1[4];
+
int samples;
struct Material *mat_override;
@@ -136,6 +174,10 @@ typedef struct ViewLayer {
struct FreestyleConfig freestyle_config;
struct ViewLayerEEVEE eevee;
+ /* List containing the `ViewLayerAOV`s */
+ ListBase aovs;
+ ViewLayerAOV *active_aov;
+
/* Runtime data */
/** ViewLayerEngineData. */
ListBase drawdata;
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index a822a6723fa..04fbc030ed9 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -220,6 +220,8 @@ typedef struct Mesh {
float remesh_voxel_adaptivity;
char remesh_mode;
+ /* Indicates the symmetry that a mesh has, according to the artist, so that tools can
+ * consistently ensure that this symmetry is maintained. */
char symmetry;
char _pad1[2];
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index b2f8d845815..780115a31be 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -340,7 +340,7 @@ enum {
};
/**
- * \note While alpha is currently is not in the view-port,
+ * \note While alpha is not currently in the 3D Viewport,
* this may eventually be added back, keep this value set to 255.
*/
typedef struct MLoopCol {
diff --git a/source/blender/makesdna/DNA_modifier_defaults.h b/source/blender/makesdna/DNA_modifier_defaults.h
index f73f43ddade..e122d50cba8 100644
--- a/source/blender/makesdna/DNA_modifier_defaults.h
+++ b/source/blender/makesdna/DNA_modifier_defaults.h
@@ -801,6 +801,7 @@
#define _DNA_DEFAULT_WeldModifierData \
{ \
.merge_dist = 0.001f, \
+ .mode = MOD_WELD_MODE_ALL, \
.defgrp_name = "", \
}
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index edb0a4439d6..03cf4aca963 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1588,7 +1588,7 @@ typedef struct WeightVGProximityModifierData {
/** Name of vertex group to modify/weight. MAX_VGROUP_NAME. */
char defgrp_name[64];
-
+
/* Mapping stuff. */
/** The custom mapping curve!. */
struct CurveMapping *cmap_curve;
@@ -2004,7 +2004,8 @@ typedef struct WeldModifierData {
/* Name of vertex group to use to mask, MAX_VGROUP_NAME. */
char defgrp_name[64];
- short flag;
+ char mode;
+ char flag;
char _pad[2];
} WeldModifierData;
@@ -2013,6 +2014,12 @@ enum {
MOD_WELD_INVERT_VGROUP = (1 << 0),
};
+/* #WeldModifierData.mode */
+enum {
+ MOD_WELD_MODE_ALL = 0,
+ MOD_WELD_MODE_CONNECTED = 1,
+};
+
typedef struct DataTransferModifierData {
ModifierData modifier;
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 29c83d2d4ed..13f8b11352a 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1464,6 +1464,13 @@ typedef enum GeometryNodeUseAttributeFlag {
GEO_NODE_USE_ATTRIBUTE_B = (1 << 1),
} GeometryNodeUseAttributeFlag;
+typedef enum GeometryNodeAttributeInputMode {
+ GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE = 0,
+ GEO_NODE_ATTRIBUTE_INPUT_FLOAT = 1,
+ GEO_NODE_ATTRIBUTE_INPUT_VECTOR = 2,
+ GEO_NODE_ATTRIBUTE_INPUT_COLOR = 3,
+} GeometryNodeAttributeInputMode;
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesdna/DNA_outliner_types.h b/source/blender/makesdna/DNA_outliner_types.h
index cc376c0cebf..d561b489ae4 100644
--- a/source/blender/makesdna/DNA_outliner_types.h
+++ b/source/blender/makesdna/DNA_outliner_types.h
@@ -66,7 +66,9 @@ enum {
/* Needed because outliner-only elements can be active */
TSE_ACTIVE = (1 << 9),
/* TSE_ACTIVE_WALK = (1 << 10), */ /* Unused */
+ TSE_HIGHLIGHTED_ICON = (1 << 11),
TSE_DRAG_ANY = (TSE_DRAG_INTO | TSE_DRAG_BEFORE | TSE_DRAG_AFTER),
+ TSE_HIGHLIGHTED_ANY = (TSE_HIGHLIGHTED | TSE_HIGHLIGHTED_ICON),
};
/* TreeStoreElem->types */
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index cbf6e900416..6fd112628a1 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -1,4 +1,4 @@
-/*
+/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@@ -279,11 +279,6 @@ typedef struct SpaceOutliner {
char show_restrict_flags;
short filter_id_type;
- /**
- * Pointers to treestore elements, grouped by (id, type, nr)
- * in hashtable for faster searching */
- void *treehash;
-
SpaceOutliner_Runtime *runtime;
} SpaceOutliner;
@@ -703,7 +698,7 @@ typedef struct FileSelectParams {
/* short */
/** XXXXX for now store type here, should be moved to the operator. */
- short type;
+ short type; /* eFileSelectType */
/** Settings for filter, hiding dots files. */
short flag;
/** Sort order. */
@@ -812,12 +807,14 @@ enum eFileDetails {
#define FILE_MAX_LIBEXTRA (FILE_MAX + MAX_ID_NAME)
/* filesel types */
-#define FILE_UNIX 8
-#define FILE_BLENDER 8 /* don't display relative paths */
-#define FILE_SPECIAL 9
-
-#define FILE_LOADLIB 1
-#define FILE_MAIN 2
+typedef enum eFileSelectType {
+ FILE_LOADLIB = 1,
+ FILE_MAIN = 2,
+
+ FILE_UNIX = 8,
+ FILE_BLENDER = 8, /* don't display relative paths */
+ FILE_SPECIAL = 9,
+} eFileSelectType;
/* filesel op property -> action */
typedef enum eFileSel_Action {
diff --git a/source/blender/makesdna/DNA_vfont_types.h b/source/blender/makesdna/DNA_vfont_types.h
index 6f0820ff62c..bc1a71102da 100644
--- a/source/blender/makesdna/DNA_vfont_types.h
+++ b/source/blender/makesdna/DNA_vfont_types.h
@@ -20,7 +20,7 @@
/** \file
* \ingroup DNA
*
- * Vector Fonts used for text in the 3D view-port
+ * Vector Fonts used for text in the 3D Viewport
* (unrelated to text used to render the GUI).
*/
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 9a233878840..b8e2256c3c6 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -192,6 +192,7 @@ typedef struct View3DShading {
/* Render pass displayed in the viewport. Is an `eScenePassType` where one bit is set */
int render_pass;
+ char aov_name[64];
struct IDProperty *prop;
void *_pad2;
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index f51202348b5..a581edcb04b 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -60,6 +60,7 @@ extern StructRNA RNA_AnimData;
extern StructRNA RNA_AnimViz;
extern StructRNA RNA_AnimVizMotionPaths;
extern StructRNA RNA_AnyType;
+extern StructRNA RNA_AOV;
extern StructRNA RNA_Area;
extern StructRNA RNA_AreaLight;
extern StructRNA RNA_Armature;
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index cb316e56a68..d0e0b69a8d5 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -1188,7 +1188,7 @@ static void rna_def_image_preview(BlenderRNA *brna)
prop = RNA_def_property(srna, "image_pixels", PROP_INT, PROP_NONE);
RNA_def_property_flag(prop, PROP_DYNAMIC);
RNA_def_property_multi_array(prop, 1, NULL);
- RNA_def_property_ui_text(prop, "Image Pixels", "Image pixels, as bytes (always RGBA 32bits)");
+ RNA_def_property_ui_text(prop, "Image Pixels", "Image pixels, as bytes (always 32-bit RGBA)");
RNA_def_property_dynamic_array_funcs(prop, "rna_ImagePreview_image_pixels_get_length");
RNA_def_property_int_funcs(
prop, "rna_ImagePreview_image_pixels_get", "rna_ImagePreview_image_pixels_set", NULL);
@@ -1221,7 +1221,7 @@ static void rna_def_image_preview(BlenderRNA *brna)
prop = RNA_def_property(srna, "icon_pixels", PROP_INT, PROP_NONE);
RNA_def_property_flag(prop, PROP_DYNAMIC);
RNA_def_property_multi_array(prop, 1, NULL);
- RNA_def_property_ui_text(prop, "Icon Pixels", "Icon pixels, as bytes (always RGBA 32bits)");
+ RNA_def_property_ui_text(prop, "Icon Pixels", "Icon pixels, as bytes (always 32-bit RGBA)");
RNA_def_property_dynamic_array_funcs(prop, "rna_ImagePreview_icon_pixels_get_length");
RNA_def_property_int_funcs(
prop, "rna_ImagePreview_icon_pixels_get", "rna_ImagePreview_icon_pixels_set", NULL);
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 4991f34c3f6..6586cfc7969 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -31,6 +31,7 @@
#include "DNA_scene_types.h"
#include "DNA_windowmanager_types.h"
+#include "BLI_alloca.h"
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
#include "BLI_ghash.h"
@@ -4957,14 +4958,10 @@ PointerRNA rna_array_lookup_int(
static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int bracket)
{
const char *p;
- char *buf;
- char quote = '\0';
- int i, j, len, escape;
-
- len = 0;
+ int len = 0;
if (bracket) {
- /* get data between [], check escaping ] with \] */
+ /* get data between [], check escaping quotes and back-slashes with #BLI_str_unescape. */
if (**path == '[') {
(*path)++;
}
@@ -4974,33 +4971,24 @@ static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int
p = *path;
- /* 2 kinds of lookups now, quoted or unquoted */
- quote = *p;
-
- if (quote != '"') { /* " - this comment is hack for Aligorith's text editor's sanity */
- quote = 0;
- }
-
- if (quote == 0) {
+ /* 2 kinds of look-ups now, quoted or unquoted. */
+ if (*p != '"') {
while (*p && (*p != ']')) {
len++;
p++;
}
}
else {
- escape = 0;
- /* skip the first quote */
- len++;
- p++;
- while (*p && (*p != quote || escape)) {
- escape = (*p == '\\');
- len++;
- p++;
+ const char *p_end = BLI_str_escape_find_quote(p + 1);
+ if (p_end == NULL) {
+ /* No Matching quote. */
+ return NULL;
}
+ /* Skip the last quoted char to get the `]`. */
+ p_end += 1;
- /* skip the last quoted char to get the ']' */
- len++;
- p++;
+ len += (p_end - p);
+ p = p_end;
}
if (*p != ']') {
@@ -5022,25 +5010,13 @@ static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int
return NULL;
}
- /* try to use fixed buffer if possible */
- if (len + 1 < fixedlen) {
- buf = fixedbuf;
- }
- else {
- buf = MEM_mallocN(sizeof(char) * (len + 1), "rna_path_token");
- }
+ /* Try to use fixed buffer if possible. */
+ char *buf = (len + 1 < fixedlen) ? fixedbuf : MEM_mallocN(sizeof(char) * (len + 1), __func__);
/* copy string, taking into account escaped ] */
if (bracket) {
- for (p = *path, i = 0, j = 0; i < len; i++, p++) {
- if (*p == '\\' && *(p + 1) == quote) {
- }
- else {
- buf[j++] = *p;
- }
- }
-
- buf[j] = 0;
+ BLI_str_unescape(buf, *path, len);
+ p = (*path) + len;
}
else {
memcpy(buf, *path, sizeof(char) * len);
@@ -5552,8 +5528,7 @@ char *RNA_path_append(
const char *path, PointerRNA *UNUSED(ptr), PropertyRNA *prop, int intkey, const char *strkey)
{
DynStr *dynstr;
- const char *s;
- char appendstr[128], *result;
+ char *result;
dynstr = BLI_dynstr_new();
@@ -5572,22 +5547,15 @@ char *RNA_path_append(
BLI_dynstr_append(dynstr, "[");
if (strkey) {
+ const int strkey_esc_max_size = (strlen(strkey) * 2) + 1;
+ char *strkey_esc = BLI_array_alloca(strkey_esc, strkey_esc_max_size);
+ BLI_str_escape(strkey_esc, strkey, strkey_esc_max_size);
BLI_dynstr_append(dynstr, "\"");
- for (s = strkey; *s; s++) {
- if (*s == '[') {
- appendstr[0] = '\\';
- appendstr[1] = *s;
- appendstr[2] = 0;
- }
- else {
- appendstr[0] = *s;
- appendstr[1] = 0;
- }
- BLI_dynstr_append(dynstr, appendstr);
- }
+ BLI_dynstr_append(dynstr, strkey_esc);
BLI_dynstr_append(dynstr, "\"");
}
else {
+ char appendstr[128];
BLI_snprintf(appendstr, sizeof(appendstr), "%d", intkey);
BLI_dynstr_append(dynstr, appendstr);
}
@@ -6008,7 +5976,7 @@ char *RNA_path_from_ID_to_property_index(PointerRNA *ptr,
}
else {
char propname_esc[MAX_IDPROP_NAME * 2];
- BLI_strescape(propname_esc, propname, sizeof(propname_esc));
+ BLI_str_escape(propname_esc, propname, sizeof(propname_esc));
path = BLI_sprintfN("%s[\"%s\"]%s", ptrpath, propname_esc, index_str);
}
MEM_freeN(ptrpath);
@@ -6019,7 +5987,7 @@ char *RNA_path_from_ID_to_property_index(PointerRNA *ptr,
}
else {
char propname_esc[MAX_IDPROP_NAME * 2];
- BLI_strescape(propname_esc, propname, sizeof(propname_esc));
+ BLI_str_escape(propname_esc, propname, sizeof(propname_esc));
path = BLI_sprintfN("[\"%s\"]%s", propname_esc, index_str);
}
}
@@ -6105,7 +6073,7 @@ char *RNA_path_full_ID_py(Main *bmain, ID *id)
char id_esc[(sizeof(id->name) - 2) * 2];
- BLI_strescape(id_esc, id->name + 2, sizeof(id_esc));
+ BLI_str_escape(id_esc, id->name + 2, sizeof(id_esc));
return BLI_sprintfN("bpy.data.%s[\"%s\"]%s%s",
BKE_idtype_idcode_to_name_plural(GS(id->name)),
@@ -7059,7 +7027,7 @@ char *RNA_property_as_string(
buf = MEM_mallocN(sizeof(char) * (length + 1), "RNA_property_as_string");
buf_esc = MEM_mallocN(sizeof(char) * (length * 2 + 1), "RNA_property_as_string esc");
RNA_property_string_get(ptr, prop, buf);
- BLI_strescape(buf_esc, buf, length * 2 + 1);
+ BLI_str_escape(buf_esc, buf, length * 2 + 1);
MEM_freeN(buf);
BLI_dynstr_appendf(dynstr, "\"%s\"", buf_esc);
MEM_freeN(buf_esc);
diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c
index 4bbbf5f01da..c0b2de268cd 100644
--- a/source/blender/makesrna/intern/rna_access_compare_override.c
+++ b/source/blender/makesrna/intern/rna_access_compare_override.c
@@ -23,7 +23,9 @@
#include "MEM_guardedalloc.h"
#include "DNA_ID.h"
+#include "DNA_anim_types.h"
#include "DNA_constraint_types.h"
+#include "DNA_gpencil_modifier_types.h"
#include "DNA_key_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
@@ -77,6 +79,18 @@ bool RNA_property_overridable_get(PointerRNA *ptr, PropertyRNA *prop)
return true;
}
}
+ else if (RNA_struct_is_a(ptr->type, &RNA_GpencilModifier)) {
+ GpencilModifierData *gp_mod = ptr->data;
+ if (gp_mod->flag & eGpencilModifierFlag_OverrideLibrary_Local) {
+ return true;
+ }
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_NlaTrack)) {
+ NlaTrack *nla_track = ptr->data;
+ if (nla_track->flag & NLATRACK_OVERRIDELIBRARY_LOCAL) {
+ return true;
+ }
+ }
/* If this is a RNA-defined property (real or 'virtual' IDProp),
* we want to use RNA prop flag. */
return !(prop->flag_override & PROPOVERRIDE_NO_COMPARISON) &&
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 0a9f2ff4819..10f86fe2671 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -587,7 +587,7 @@ static void rna_KeyingSet_paths_clear(KeyingSet *keyingset, ReportList *reports)
/* needs wrapper function to push notifier */
static NlaTrack *rna_NlaTrack_new(ID *id, AnimData *adt, Main *bmain, bContext *C, NlaTrack *track)
{
- NlaTrack *new_track = BKE_nlatrack_add(adt, track);
+ NlaTrack *new_track = BKE_nlatrack_add(adt, track, ID_IS_OVERRIDE_LIBRARY(id));
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL);
@@ -732,6 +732,60 @@ bool rna_AnimaData_override_apply(Main *UNUSED(bmain),
return false;
}
+bool rna_NLA_tracks_override_apply(Main *bmain,
+ PointerRNA *ptr_dst,
+ PointerRNA *ptr_src,
+ PointerRNA *UNUSED(ptr_storage),
+ PropertyRNA *UNUSED(prop_dst),
+ PropertyRNA *UNUSED(prop_src),
+ PropertyRNA *UNUSED(prop_storage),
+ const int UNUSED(len_dst),
+ const int UNUSED(len_src),
+ const int UNUSED(len_storage),
+ PointerRNA *UNUSED(ptr_item_dst),
+ PointerRNA *UNUSED(ptr_item_src),
+ PointerRNA *UNUSED(ptr_item_storage),
+ IDOverrideLibraryPropertyOperation *opop)
+{
+ BLI_assert(opop->operation == IDOVERRIDE_LIBRARY_OP_INSERT_AFTER &&
+ "Unsupported RNA override operation on constraints collection");
+
+ AnimData *anim_data_dst = (AnimData *)ptr_dst->data;
+ AnimData *anim_data_src = (AnimData *)ptr_src->data;
+
+ /* Remember that insertion operations are defined and stored in correct order, which means that
+ * even if we insert several items in a row, we always insert first one, then second one, etc.
+ * So we should always find 'anchor' track in both _src *and* _dst. */
+ NlaTrack *nla_track_anchor = NULL;
+# if 0
+ /* This is not working so well with index-based insertion, especially in case some tracks get
+ * added to lib linked data. So we simply add locale tracks at the end of the list always, order
+ * of override operations should ensure order of local tracks is preserved properly. */
+ if (opop->subitem_local_index >= 0) {
+ nla_track_anchor = BLI_findlink(&anim_data_dst->nla_tracks, opop->subitem_local_index);
+ }
+ /* Otherwise we just insert in first position. */
+# else
+ nla_track_anchor = anim_data_dst->nla_tracks.last;
+# endif
+
+ NlaTrack *nla_track_src = NULL;
+ if (opop->subitem_local_index >= 0) {
+ nla_track_src = BLI_findlink(&anim_data_src->nla_tracks, opop->subitem_local_index);
+ }
+ nla_track_src = nla_track_src ? nla_track_src->next : anim_data_src->nla_tracks.first;
+
+ BLI_assert(nla_track_src != NULL);
+
+ NlaTrack *nla_track_dst = BKE_nlatrack_copy(bmain, nla_track_src, true, 0);
+
+ /* This handles NULL anchor as expected by adding at head of list. */
+ BLI_insertlinkafter(&anim_data_dst->nla_tracks, nla_track_anchor, nla_track_dst);
+
+ // printf("%s: We inserted a NLA Track...\n", __func__);
+ return true;
+}
+
#else
/* helper function for Keying Set -> keying settings */
@@ -1251,14 +1305,19 @@ static void rna_def_animdata(BlenderRNA *brna)
RNA_def_property_collection_sdna(prop, NULL, "nla_tracks", NULL);
RNA_def_property_struct_type(prop, "NlaTrack");
RNA_def_property_ui_text(prop, "NLA Tracks", "NLA Tracks (i.e. Animation Layers)");
+ RNA_def_property_override_flag(prop,
+ PROPOVERRIDE_OVERRIDABLE_LIBRARY |
+ PROPOVERRIDE_LIBRARY_INSERTION | PROPOVERRIDE_NO_PROP_NAME);
+ RNA_def_property_override_funcs(prop, NULL, NULL, "rna_NLA_tracks_override_apply");
rna_api_animdata_nla_tracks(brna, prop);
+ RNA_define_lib_overridable(true);
+
/* Active Action */
prop = RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
/* this flag as well as the dynamic test must be defined for this to be editable... */
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
- RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_pointer_funcs(
prop, NULL, "rna_AnimData_action_set", NULL, "rna_Action_id_poll");
RNA_def_property_editable_func(prop, "rna_AnimData_action_editable");
@@ -1297,11 +1356,14 @@ static void rna_def_animdata(BlenderRNA *brna)
prop = RNA_def_property(srna, "drivers", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "drivers", NULL);
RNA_def_property_struct_type(prop, "FCurve");
- RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_ui_text(prop, "Drivers", "The Drivers/Expressions for this data-block");
+ RNA_define_lib_overridable(false);
+
rna_api_animdata_drivers(brna, prop);
+ RNA_define_lib_overridable(true);
+
/* General Settings */
prop = RNA_def_property(srna, "use_nla", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", ADT_NLA_EVAL_OFF);
@@ -1322,6 +1384,8 @@ static void rna_def_animdata(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Pin in Graph Editor", "");
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ RNA_define_lib_overridable(false);
+
/* Animation Data API */
RNA_api_animdata(srna);
}
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index d586f222203..1628c978c30 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -245,7 +245,7 @@ static char *rna_Bone_path(PointerRNA *ptr)
Bone *bone = (Bone *)ptr->data;
char name_esc[sizeof(bone->name) * 2];
- BLI_strescape(name_esc, bone->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, bone->name, sizeof(name_esc));
/* special exception for trying to get the path where ID-block is Object
* - this will be assumed to be from a Pose Bone...
diff --git a/source/blender/makesrna/intern/rna_attribute.c b/source/blender/makesrna/intern/rna_attribute.c
index ad615026343..95f6340174a 100644
--- a/source/blender/makesrna/intern/rna_attribute.c
+++ b/source/blender/makesrna/intern/rna_attribute.c
@@ -38,10 +38,10 @@
#include "WM_types.h"
const EnumPropertyItem rna_enum_attribute_type_items[] = {
- {CD_PROP_FLOAT, "FLOAT", 0, "Float", "Floating point value"},
- {CD_PROP_INT32, "INT", 0, "Integer", "32 bit integer"},
- {CD_PROP_FLOAT3, "FLOAT_VECTOR", 0, "Vector", "3D vector with floating point values"},
- {CD_PROP_COLOR, "FLOAT_COLOR", 0, "Float Color", "RGBA color with floating point precisions"},
+ {CD_PROP_FLOAT, "FLOAT", 0, "Float", "Floating-point value"},
+ {CD_PROP_INT32, "INT", 0, "Integer", "32-bit integer"},
+ {CD_PROP_FLOAT3, "FLOAT_VECTOR", 0, "Vector", "3D vector with floating-point values"},
+ {CD_PROP_COLOR, "FLOAT_COLOR", 0, "Float Color", "RGBA color with floating-point precisions"},
{CD_MLOOPCOL, "BYTE_COLOR", 0, "Byte Color", "RGBA color with 8-bit precision"},
{CD_PROP_STRING, "STRING", 0, "String", "Text string"},
{0, NULL, 0, NULL, NULL},
diff --git a/source/blender/makesrna/intern/rna_boid.c b/source/blender/makesrna/intern/rna_boid.c
index 33d69f6f912..3e3452af713 100644
--- a/source/blender/makesrna/intern/rna_boid.c
+++ b/source/blender/makesrna/intern/rna_boid.c
@@ -183,7 +183,7 @@ static char *rna_BoidRule_path(PointerRNA *ptr)
BoidRule *rule = (BoidRule *)ptr->data;
char name_esc[sizeof(rule->name) * 2];
- BLI_strescape(name_esc, rule->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, rule->name, sizeof(name_esc));
return BLI_sprintfN("rules[\"%s\"]", name_esc); /* XXX not unique */
}
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 1e5309e5869..b5ce7976fd8 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -2072,6 +2072,20 @@ static void rna_def_brush(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
+ static const EnumPropertyItem brush_snake_hook_deform_type_items[] = {
+ {BRUSH_SNAKE_HOOK_DEFORM_FALLOFF,
+ "FALLOFF",
+ 0,
+ "Radius Falloff",
+ "Applies the brush falloff in the tip of the brush"},
+ {BRUSH_SNAKE_HOOK_DEFORM_ELASTIC,
+ "ELASTIC",
+ 0,
+ "Elastic",
+ "Modifies the entire mesh using elastic deform"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
static const EnumPropertyItem brush_cloth_deform_type_items[] = {
{BRUSH_CLOTH_DEFORM_DRAG, "DRAG", 0, "Drag", ""},
{BRUSH_CLOTH_DEFORM_PUSH, "PUSH", 0, "Push", ""},
@@ -2309,6 +2323,11 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Deformation", "Deformation type that is used in the brush");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "snake_hook_deform_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, brush_snake_hook_deform_type_items);
+ RNA_def_property_ui_text(prop, "Deformation", "Deformation type that is used in the brush");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "cloth_deform_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, brush_cloth_deform_type_items);
RNA_def_property_ui_text(prop, "Deformation", "Deformation type that is used in the brush");
@@ -2854,6 +2873,16 @@ static void rna_def_brush(BlenderRNA *brna)
"used to sample the area center");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "wet_paint_radius_factor", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "wet_paint_radius_factor");
+ RNA_def_property_range(prop, 0.0f, 2.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 2.0f, 0.001, 3);
+ RNA_def_property_ui_text(prop,
+ "Wet Paint Radius",
+ "Ratio between the brush radius and the radius that is going to be "
+ "used to sample the color to blend in wet paint");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "stencil_pos", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "stencil_pos");
RNA_def_property_array(prop, 2);
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index 27318494428..b0e0b577629 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -439,7 +439,7 @@ static char *rna_ClothSettings_path(PointerRNA *ptr)
if (md) {
char name_esc[sizeof(md->name) * 2];
- BLI_strescape(name_esc, md->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, md->name, sizeof(name_esc));
return BLI_sprintfN("modifiers[\"%s\"].settings", name_esc);
}
else {
@@ -454,7 +454,7 @@ static char *rna_ClothCollisionSettings_path(PointerRNA *ptr)
if (md) {
char name_esc[sizeof(md->name) * 2];
- BLI_strescape(name_esc, md->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, md->name, sizeof(name_esc));
return BLI_sprintfN("modifiers[\"%s\"].collision_settings", name_esc);
}
else {
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 1c84be5907b..0b3dc2a3504 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -200,6 +200,12 @@ static const EnumPropertyItem target_space_pchan_items[] = {
"World Space",
"The transformation of the target is evaluated relative to the world "
"coordinate system"},
+ {CONSTRAINT_SPACE_CUSTOM,
+ "CUSTOM",
+ 0,
+ "Custom Space",
+ "The transformation of the target is evaluated relative to a custom object/bone/vertex "
+ "group"},
{CONSTRAINT_SPACE_POSE,
"POSE",
0,
@@ -227,6 +233,11 @@ static const EnumPropertyItem owner_space_pchan_items[] = {
0,
"World Space",
"The constraint is applied relative to the world coordinate system"},
+ {CONSTRAINT_SPACE_CUSTOM,
+ "CUSTOM",
+ 0,
+ "Custom Space",
+ "The constraint is applied in local space of a custom object/bone/vertex group"},
{CONSTRAINT_SPACE_POSE,
"POSE",
0,
@@ -275,6 +286,12 @@ static const EnumPropertyItem space_object_items[] = {
0,
"World Space",
"The transformation of the target is evaluated relative to the world coordinate system"},
+ {CONSTRAINT_SPACE_CUSTOM,
+ "CUSTOM",
+ 0,
+ "Custom Space",
+ "The transformation of the target is evaluated relative to a custom object/bone/vertex "
+ "group"},
{CONSTRAINT_SPACE_LOCAL,
"LOCAL",
0,
@@ -416,13 +433,13 @@ static char *rna_Constraint_do_compute_path(Object *ob, bConstraint *con)
if (pchan) {
char name_esc_pchan[sizeof(pchan->name) * 2];
char name_esc_const[sizeof(con->name) * 2];
- BLI_strescape(name_esc_pchan, pchan->name, sizeof(name_esc_pchan));
- BLI_strescape(name_esc_const, con->name, sizeof(name_esc_const));
+ BLI_str_escape(name_esc_pchan, pchan->name, sizeof(name_esc_pchan));
+ BLI_str_escape(name_esc_const, con->name, sizeof(name_esc_const));
return BLI_sprintfN("pose.bones[\"%s\"].constraints[\"%s\"]", name_esc_pchan, name_esc_const);
}
else {
char name_esc_const[sizeof(con->name) * 2];
- BLI_strescape(name_esc_const, con->name, sizeof(name_esc_const));
+ BLI_str_escape(name_esc_const, con->name, sizeof(name_esc_const));
return BLI_sprintfN("constraints[\"%s\"]", name_esc_const);
}
}
@@ -3398,6 +3415,18 @@ void RNA_def_constraint(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Target Space", "Space that target is evaluated in");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+ prop = RNA_def_property(srna, "space_object", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "space_object");
+ RNA_def_property_ui_text(prop, "Object", "Object for Custom Space");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+
+ prop = RNA_def_property(srna, "space_subtarget", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "space_subtarget");
+ RNA_def_property_ui_text(prop, "Sub-Target", "Armature bone, mesh or lattice vertex group, ...");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+
/* flags */
prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_OFF);
diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c
index f86cfb674d1..7c4762aa3a3 100644
--- a/source/blender/makesrna/intern/rna_dynamicpaint.c
+++ b/source/blender/makesrna/intern/rna_dynamicpaint.c
@@ -57,7 +57,7 @@ static char *rna_DynamicPaintCanvasSettings_path(PointerRNA *ptr)
ModifierData *md = (ModifierData *)settings->pmd;
char name_esc[sizeof(md->name) * 2];
- BLI_strescape(name_esc, md->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, md->name, sizeof(name_esc));
return BLI_sprintfN("modifiers[\"%s\"].canvas_settings", name_esc);
}
@@ -67,7 +67,7 @@ static char *rna_DynamicPaintBrushSettings_path(PointerRNA *ptr)
ModifierData *md = (ModifierData *)settings->pmd;
char name_esc[sizeof(md->name) * 2];
- BLI_strescape(name_esc, md->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, md->name, sizeof(name_esc));
return BLI_sprintfN("modifiers[\"%s\"].brush_settings", name_esc);
}
@@ -78,8 +78,8 @@ static char *rna_DynamicPaintSurface_path(PointerRNA *ptr)
char name_esc[sizeof(md->name) * 2];
char name_esc_surface[sizeof(surface->name) * 2];
- BLI_strescape(name_esc, md->name, sizeof(name_esc));
- BLI_strescape(name_esc_surface, surface->name, sizeof(name_esc_surface));
+ BLI_str_escape(name_esc, md->name, sizeof(name_esc));
+ BLI_str_escape(name_esc_surface, surface->name, sizeof(name_esc_surface));
return BLI_sprintfN(
"modifiers[\"%s\"].canvas_settings.canvas_surfaces[\"%s\"]", name_esc, name_esc_surface);
}
diff --git a/source/blender/makesrna/intern/rna_fluid.c b/source/blender/makesrna/intern/rna_fluid.c
index 02ae71e3b3d..90f5434bea0 100644
--- a/source/blender/makesrna/intern/rna_fluid.c
+++ b/source/blender/makesrna/intern/rna_fluid.c
@@ -872,7 +872,7 @@ static char *rna_FluidDomainSettings_path(PointerRNA *ptr)
ModifierData *md = (ModifierData *)settings->fmd;
char name_esc[sizeof(md->name) * 2];
- BLI_strescape(name_esc, md->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, md->name, sizeof(name_esc));
return BLI_sprintfN("modifiers[\"%s\"].domain_settings", name_esc);
}
@@ -882,7 +882,7 @@ static char *rna_FluidFlowSettings_path(PointerRNA *ptr)
ModifierData *md = (ModifierData *)settings->fmd;
char name_esc[sizeof(md->name) * 2];
- BLI_strescape(name_esc, md->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, md->name, sizeof(name_esc));
return BLI_sprintfN("modifiers[\"%s\"].flow_settings", name_esc);
}
@@ -892,7 +892,7 @@ static char *rna_FluidEffectorSettings_path(PointerRNA *ptr)
ModifierData *md = (ModifierData *)settings->fmd;
char name_esc[sizeof(md->name) * 2];
- BLI_strescape(name_esc, md->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, md->name, sizeof(name_esc));
return BLI_sprintfN("modifiers[\"%s\"].effector_settings", name_esc);
}
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index 603bd51b2d9..7be9d14b1d1 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -308,7 +308,7 @@ static char *rna_GPencilLayer_path(PointerRNA *ptr)
bGPDlayer *gpl = (bGPDlayer *)ptr->data;
char name_esc[sizeof(gpl->info) * 2];
- BLI_strescape(name_esc, gpl->info, sizeof(name_esc));
+ BLI_str_escape(name_esc, gpl->info, sizeof(name_esc));
return BLI_sprintfN("layers[\"%s\"]", name_esc);
}
@@ -406,8 +406,8 @@ static char *rna_GPencilLayerMask_path(PointerRNA *ptr)
char name_layer[sizeof(gpl->info) * 2];
char name_mask[sizeof(mask->name) * 2];
- BLI_strescape(name_layer, gpl->info, sizeof(name_layer));
- BLI_strescape(name_mask, mask->name, sizeof(name_mask));
+ BLI_str_escape(name_layer, gpl->info, sizeof(name_layer));
+ BLI_str_escape(name_mask, mask->name, sizeof(name_mask));
return BLI_sprintfN("layers[\"%s\"].mask_layers[\"%s\"]", name_layer, name_mask);
}
diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c
index 19264aeebd7..5f131de6a40 100644
--- a/source/blender/makesrna/intern/rna_gpencil_modifier.c
+++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c
@@ -276,7 +276,7 @@ static char *rna_GpencilModifier_path(PointerRNA *ptr)
GpencilModifierData *gmd = ptr->data;
char name_esc[sizeof(gmd->name) * 2];
- BLI_strescape(name_esc, gmd->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, gmd->name, sizeof(name_esc));
return BLI_sprintfN("grease_pencil_modifiers[\"%s\"]", name_esc);
}
@@ -781,7 +781,7 @@ static void rna_def_modifier_gpencilsimplify(BlenderRNA *brna)
prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "factor");
RNA_def_property_range(prop, 0, 100.0);
- RNA_def_property_ui_range(prop, 0, 100.0, 1.0f, 3);
+ RNA_def_property_ui_range(prop, 0, 5.0f, 1.0f, 3);
RNA_def_property_ui_text(prop, "Factor", "Factor of Simplify");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 504a4a6bdf3..2373045d95a 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -1136,7 +1136,7 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IMA_HIGH_BITDEPTH);
RNA_def_property_ui_text(prop,
"Half Float Precision",
- "Use 16bits per channel to lower the memory usage during rendering");
+ "Use 16 bits per channel to lower the memory usage during rendering");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_gpu_texture_update");
/* multiview */
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 31e920a6799..1c6f83efd65 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -345,6 +345,10 @@ void rna_ViewLayer_material_override_update(struct Main *bmain,
void rna_ViewLayer_pass_update(struct Main *bmain,
struct Scene *activescene,
struct PointerRNA *ptr);
+void rna_ViewLayer_active_aov_index_range(
+ PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax);
+int rna_ViewLayer_active_aov_index_get(PointerRNA *ptr);
+void rna_ViewLayer_active_aov_index_set(PointerRNA *ptr, int value);
/* named internal so as not to conflict with obj.update() rna func */
void rna_Object_internal_update_data(struct Main *bmain,
diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c
index e0005766c48..3b9fc970072 100644
--- a/source/blender/makesrna/intern/rna_key.c
+++ b/source/blender/makesrna/intern/rna_key.c
@@ -676,7 +676,7 @@ static char *rna_ShapeKey_path(PointerRNA *ptr)
ID *id = ptr->owner_id;
char name_esc[sizeof(kb->name) * 2];
- BLI_strescape(name_esc, kb->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, kb->name, sizeof(name_esc));
if ((id) && (GS(id->name) != ID_KE)) {
return BLI_sprintfN("shape_keys.key_blocks[\"%s\"]", name_esc);
@@ -774,7 +774,7 @@ static char *rna_ShapeKeyPoint_path(PointerRNA *ptr)
index = rna_ShapeKey_curve_find_index(key, index);
}
- BLI_strescape(name_esc_kb, kb->name, sizeof(name_esc_kb));
+ BLI_str_escape(name_esc_kb, kb->name, sizeof(name_esc_kb));
if (GS(id->name) == ID_KE) {
return BLI_sprintfN("key_blocks[\"%s\"].data[%d]", name_esc_kb, index);
diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c
index c7a53757296..afe69c37eef 100644
--- a/source/blender/makesrna/intern/rna_layer.c
+++ b/source/blender/makesrna/intern/rna_layer.c
@@ -115,7 +115,7 @@ static char *rna_ViewLayer_path(PointerRNA *ptr)
ViewLayer *srl = (ViewLayer *)ptr->data;
char name_esc[sizeof(srl->name) * 2];
- BLI_strescape(name_esc, srl->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, srl->name, sizeof(name_esc));
return BLI_sprintfN("view_layers[\"%s\"]", name_esc);
}
@@ -152,6 +152,18 @@ static void rna_ViewLayer_update_render_passes(ID *id)
if (scene->nodetree) {
ntreeCompositUpdateRLayers(scene->nodetree);
}
+
+ RenderEngineType *engine_type = RE_engines_find(scene->r.engine);
+ if (engine_type->update_render_passes) {
+ RenderEngine *engine = RE_engine_create(engine_type);
+ if (engine) {
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ BKE_view_layer_verify_aov(engine, scene, view_layer);
+ }
+ }
+ RE_engine_free(engine);
+ engine = NULL;
+ }
}
static PointerRNA rna_ViewLayer_objects_get(CollectionPropertyIterator *iter)
diff --git a/source/blender/makesrna/intern/rna_linestyle.c b/source/blender/makesrna/intern/rna_linestyle.c
index 03442748854..ca97f2c9a55 100644
--- a/source/blender/makesrna/intern/rna_linestyle.c
+++ b/source/blender/makesrna/intern/rna_linestyle.c
@@ -257,7 +257,7 @@ static char *rna_LineStyle_color_modifier_path(PointerRNA *ptr)
{
LineStyleModifier *m = (LineStyleModifier *)ptr->data;
char name_esc[sizeof(m->name) * 2];
- BLI_strescape(name_esc, m->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, m->name, sizeof(name_esc));
return BLI_sprintfN("color_modifiers[\"%s\"]", name_esc);
}
@@ -265,7 +265,7 @@ static char *rna_LineStyle_alpha_modifier_path(PointerRNA *ptr)
{
LineStyleModifier *m = (LineStyleModifier *)ptr->data;
char name_esc[sizeof(m->name) * 2];
- BLI_strescape(name_esc, m->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, m->name, sizeof(name_esc));
return BLI_sprintfN("alpha_modifiers[\"%s\"]", name_esc);
}
@@ -273,7 +273,7 @@ static char *rna_LineStyle_thickness_modifier_path(PointerRNA *ptr)
{
LineStyleModifier *m = (LineStyleModifier *)ptr->data;
char name_esc[sizeof(m->name) * 2];
- BLI_strescape(name_esc, m->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, m->name, sizeof(name_esc));
return BLI_sprintfN("thickness_modifiers[\"%s\"]", name_esc);
}
@@ -281,7 +281,7 @@ static char *rna_LineStyle_geometry_modifier_path(PointerRNA *ptr)
{
LineStyleModifier *m = (LineStyleModifier *)ptr->data;
char name_esc[sizeof(m->name) * 2];
- BLI_strescape(name_esc, m->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, m->name, sizeof(name_esc));
return BLI_sprintfN("geometry_modifiers[\"%s\"]", name_esc);
}
diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c
index cfbaf0cccf5..db3e5195c79 100644
--- a/source/blender/makesrna/intern/rna_mask.c
+++ b/source/blender/makesrna/intern/rna_mask.c
@@ -182,7 +182,7 @@ static char *rna_MaskLayer_path(PointerRNA *ptr)
{
MaskLayer *masklay = (MaskLayer *)ptr->data;
char name_esc[sizeof(masklay->name) * 2];
- BLI_strescape(name_esc, masklay->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, masklay->name, sizeof(name_esc));
return BLI_sprintfN("layers[\"%s\"]", name_esc);
}
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 4afb17fe0b9..2bbfee2dcef 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -670,7 +670,7 @@ static char *rna_MeshUVLoopLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
- BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("uv_layers[\"%s\"]", name_esc);
}
@@ -913,7 +913,7 @@ static char *rna_MeshSkinVertexLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
- BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("skin_vertices[\"%s\"]", name_esc);
}
@@ -945,7 +945,7 @@ static char *rna_MeshPaintMaskLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
- BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("vertex_paint_masks[\"%s\"]", name_esc);
}
@@ -979,7 +979,7 @@ static char *rna_MeshFaceMapLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
- BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("face_maps[\"%s\"]", name_esc);
}
@@ -1189,7 +1189,7 @@ static char *rna_VertCustomData_data_path(PointerRNA *ptr, const char *collectio
b = ((char *)ptr->data - ((char *)cdl->data)) / CustomData_sizeof(type);
if (b >= 0 && b < totvert) {
char name_esc[sizeof(cdl->name) * 2];
- BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("%s[\"%s\"].data[%d]", collection, name_esc, b);
}
}
@@ -1210,7 +1210,7 @@ static char *rna_PolyCustomData_data_path(PointerRNA *ptr, const char *collectio
b = ((char *)ptr->data - ((char *)cdl->data)) / CustomData_sizeof(type);
if (b >= 0 && b < totpoly) {
char name_esc[sizeof(cdl->name) * 2];
- BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("%s[\"%s\"].data[%d]", collection, name_esc, b);
}
}
@@ -1231,7 +1231,7 @@ static char *rna_LoopCustomData_data_path(PointerRNA *ptr, const char *collectio
b = ((char *)ptr->data - ((char *)cdl->data)) / CustomData_sizeof(type);
if (b >= 0 && b < totloop) {
char name_esc[sizeof(cdl->name) * 2];
- BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("%s[\"%s\"].data[%d]", collection, name_esc, b);
}
}
@@ -1249,7 +1249,7 @@ static char *rna_MeshLoopColorLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
- BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("vertex_colors[\"%s\"]", name_esc);
}
@@ -1262,7 +1262,7 @@ static char *rna_MeshVertColorLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
- BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("sculpt_vertex_colors[\"%s\"]", name_esc);
}
@@ -1276,14 +1276,14 @@ static char *rna_MeshVertexFloatPropertyLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
- BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("vertex_float_layers[\"%s\"]", name_esc);
}
static char *rna_MeshPolygonFloatPropertyLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
- BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("polygon_float_layers[\"%s\"]", name_esc);
}
@@ -1327,14 +1327,14 @@ static char *rna_MeshVertexIntPropertyLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
- BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("vertex_int_layers[\"%s\"]", name_esc);
}
static char *rna_MeshPolygonIntPropertyLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
- BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("polygon_int_layers[\"%s\"]", name_esc);
}
@@ -1378,14 +1378,14 @@ static char *rna_MeshVertexStringPropertyLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
- BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("vertex_string_layers[\"%s\"]", name_esc);
}
static char *rna_MeshPolygonStringPropertyLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
- BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("polygon_string_layers[\"%s\"]", name_esc);
}
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index f0836ae59ad..d91b6ea19f7 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -660,7 +660,7 @@ static char *rna_Modifier_path(PointerRNA *ptr)
ModifierData *md = ptr->data;
char name_esc[sizeof(md->name) * 2];
- BLI_strescape(name_esc, md->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, md->name, sizeof(name_esc));
return BLI_sprintfN("modifiers[\"%s\"]", name_esc);
}
@@ -6231,6 +6231,12 @@ static void rna_def_modifier_weld(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
+ static const EnumPropertyItem mode_items[] = {
+ {MOD_WELD_MODE_ALL, "ALL", 0, "All", "Full merge by distance"},
+ {MOD_WELD_MODE_CONNECTED, "CONNECTED", 0, "Connected", "Only merge along the edges"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
srna = RNA_def_struct(brna, "WeldModifier", "Modifier");
RNA_def_struct_ui_text(srna, "Weld Modifier", "Weld modifier");
RNA_def_struct_sdna(srna, "WeldModifierData");
@@ -6238,6 +6244,11 @@ static void rna_def_modifier_weld(BlenderRNA *brna)
RNA_define_lib_overridable(true);
+ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, mode_items);
+ RNA_def_property_ui_text(prop, "Mode", "Mode defines the merge rule");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
prop = RNA_def_property(srna, "merge_threshold", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "merge_dist");
RNA_def_property_range(prop, 0, FLT_MAX);
diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c
index b0dda1237b0..f8a342e7f7e 100644
--- a/source/blender/makesrna/intern/rna_nla.c
+++ b/source/blender/makesrna/intern/rna_nla.c
@@ -88,8 +88,8 @@ static char *rna_NlaStrip_path(PointerRNA *ptr)
char name_esc_nlt[sizeof(nlt->name) * 2];
char name_esc_strip[sizeof(strip->name) * 2];
- BLI_strescape(name_esc_nlt, nlt->name, sizeof(name_esc_nlt));
- BLI_strescape(name_esc_strip, strip->name, sizeof(name_esc_strip));
+ BLI_str_escape(name_esc_nlt, nlt->name, sizeof(name_esc_nlt));
+ BLI_str_escape(name_esc_strip, strip->name, sizeof(name_esc_strip));
return BLI_sprintfN(
"animation_data.nla_tracks[\"%s\"].strips[\"%s\"]", name_esc_nlt, name_esc_strip);
}
@@ -607,6 +607,8 @@ static void rna_def_nlastrip(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_NlaStrip_path");
RNA_def_struct_ui_icon(srna, ICON_NLA); /* XXX */
+ RNA_define_lib_overridable(true);
+
/* name property */
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Name", "");
@@ -820,6 +822,8 @@ static void rna_def_nlastrip(BlenderRNA *brna)
"Update range of frames referenced from action "
"after tweaking strip and its keyframes");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update");
+
+ RNA_define_lib_overridable(false);
}
static void rna_api_nlatrack_strips(BlenderRNA *brna, PropertyRNA *cprop)
@@ -877,10 +881,14 @@ static void rna_def_nlatrack(BlenderRNA *brna)
/* strips collection */
prop = RNA_def_property(srna, "strips", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "NlaStrip");
+ /* We do not support inserting or removing strips in overrides of tracks for now. */
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_ui_text(prop, "NLA Strips", "NLA Strips on this NLA-track");
rna_api_nlatrack_strips(brna, prop);
+ RNA_define_lib_overridable(true);
+
/* name property */
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Name", "");
@@ -920,6 +928,8 @@ static void rna_def_nlatrack(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_PROTECTED);
RNA_def_property_ui_text(prop, "Locked", "NLA Track is locked");
RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */
+
+ RNA_define_lib_overridable(false);
}
/* --------- */
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 99ae1b85e0c..dd02cc214e0 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -1457,7 +1457,7 @@ static char *rna_Node_path(PointerRNA *ptr)
bNode *node = (bNode *)ptr->data;
char name_esc[sizeof(node->name) * 2];
- BLI_strescape(name_esc, node->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, node->name, sizeof(name_esc));
return BLI_sprintfN("nodes[\"%s\"]", name_esc);
}
@@ -1484,7 +1484,7 @@ char *rna_Node_ImageUser_path(PointerRNA *ptr)
continue;
}
- BLI_strescape(name_esc, node->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, node->name, sizeof(name_esc));
return BLI_sprintfN("nodes[\"%s\"].image_user", name_esc);
}
@@ -2463,7 +2463,7 @@ static char *rna_NodeSocket_path(PointerRNA *ptr)
return NULL;
}
- BLI_strescape(name_esc, node->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, node->name, sizeof(name_esc));
if (sock->in_out == SOCK_IN) {
return BLI_sprintfN("nodes[\"%s\"].inputs[%d]", name_esc, socketindex);
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index a04ad28f9c3..9fb883568c9 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -324,8 +324,27 @@ static void rna_Object_mat_convert_space(Object *ob,
return;
}
}
+ /* These checks are extra security, they should never occur. */
+ if (from == CONSTRAINT_SPACE_CUSTOM) {
+ const char *identifier = NULL;
+ RNA_enum_identifier(space_items, from, &identifier);
+ BKE_reportf(reports,
+ RPT_ERROR,
+ "'from_space' '%s' is invalid when no custom space is given!",
+ identifier);
+ return;
+ }
+ if (to == CONSTRAINT_SPACE_CUSTOM) {
+ const char *identifier = NULL;
+ RNA_enum_identifier(space_items, to, &identifier);
+ BKE_reportf(reports,
+ RPT_ERROR,
+ "'to_space' '%s' is invalid when no custom space is given!",
+ identifier);
+ return;
+ }
- BKE_constraint_mat_convertspace(ob, pchan, (float(*)[4])mat_ret, from, to, false);
+ BKE_constraint_mat_convertspace(ob, pchan, NULL, (float(*)[4])mat_ret, from, to, false);
}
static void rna_Object_calc_matrix_camera(Object *ob,
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index 39783f9e31f..db4f3754b25 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -154,7 +154,7 @@ static char *rna_PointCache_path(PointerRNA *ptr)
}
char name_esc[sizeof(md->name) * 2];
- BLI_strescape(name_esc, md->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, md->name, sizeof(name_esc));
switch (md->type) {
case eModifierType_ParticleSystem: {
@@ -171,7 +171,7 @@ static char *rna_PointCache_path(PointerRNA *ptr)
for (; surface; surface = surface->next) {
if (surface->pointcache == cache) {
char name_surface_esc[sizeof(surface->name) * 2];
- BLI_strescape(name_surface_esc, surface->name, sizeof(name_surface_esc));
+ BLI_str_escape(name_surface_esc, surface->name, sizeof(name_surface_esc));
return BLI_sprintfN(
"modifiers[\"%s\"].canvas_settings.canvas_surfaces[\"%s\"].point_cache",
name_esc,
@@ -436,7 +436,7 @@ static char *rna_CollisionSettings_path(PointerRNA *UNUSED(ptr))
if (md) {
char name_esc[sizeof(md->name) * 2];
- BLI_strescape(name_esc, md->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, md->name, sizeof(name_esc));
return BLI_sprintfN("modifiers[\"%s\"].settings", name_esc);
}
else {
@@ -608,7 +608,7 @@ static char *rna_SoftBodySettings_path(PointerRNA *ptr)
ModifierData *md = (ModifierData *)BKE_modifiers_findby_type(ob, eModifierType_Softbody);
char name_esc[sizeof(md->name) * 2];
- BLI_strescape(name_esc, md->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, md->name, sizeof(name_esc));
return BLI_sprintfN("modifiers[\"%s\"].settings", name_esc);
}
@@ -797,7 +797,7 @@ static char *rna_EffectorWeight_path(PointerRNA *ptr)
/* no pointer from modifier data to actual softbody storage, would be good to add */
if (ob->soft->effector_weights == ew) {
char name_esc[sizeof(md->name) * 2];
- BLI_strescape(name_esc, md->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, md->name, sizeof(name_esc));
return BLI_sprintfN("modifiers[\"%s\"].settings.effector_weights", name_esc);
}
}
@@ -808,7 +808,7 @@ static char *rna_EffectorWeight_path(PointerRNA *ptr)
ClothModifierData *cmd = (ClothModifierData *)md;
if (cmd->sim_parms->effector_weights == ew) {
char name_esc[sizeof(md->name) * 2];
- BLI_strescape(name_esc, md->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, md->name, sizeof(name_esc));
return BLI_sprintfN("modifiers[\"%s\"].settings.effector_weights", name_esc);
}
}
@@ -820,7 +820,7 @@ static char *rna_EffectorWeight_path(PointerRNA *ptr)
if (fmd->type == MOD_FLUID_TYPE_DOMAIN && fmd->domain &&
fmd->domain->effector_weights == ew) {
char name_esc[sizeof(md->name) * 2];
- BLI_strescape(name_esc, md->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, md->name, sizeof(name_esc));
return BLI_sprintfN("modifiers[\"%s\"].domain_settings.effector_weights", name_esc);
}
}
@@ -838,8 +838,8 @@ static char *rna_EffectorWeight_path(PointerRNA *ptr)
char name_esc[sizeof(md->name) * 2];
char name_esc_surface[sizeof(surface->name) * 2];
- BLI_strescape(name_esc, md->name, sizeof(name_esc));
- BLI_strescape(name_esc_surface, surface->name, sizeof(name_esc_surface));
+ BLI_str_escape(name_esc, md->name, sizeof(name_esc));
+ BLI_str_escape(name_esc_surface, surface->name, sizeof(name_esc_surface));
return BLI_sprintfN(
"modifiers[\"%s\"].canvas_settings.canvas_surfaces[\"%s\"]"
".effector_weights",
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 5987f52328d..e04ef105071 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -1490,7 +1490,7 @@ static char *rna_ParticleSystem_path(PointerRNA *ptr)
ParticleSystem *psys = (ParticleSystem *)ptr->data;
char name_esc[sizeof(psys->name) * 2];
- BLI_strescape(name_esc, psys->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, psys->name, sizeof(name_esc));
return BLI_sprintfN("particle_systems[\"%s\"]", name_esc);
}
@@ -2484,7 +2484,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
NULL,
"ParticleSettingsTextureSlot",
"ParticleSettingsTextureSlots",
- "rna_Particle_reset",
+ "rna_Particle_reset_dependency",
NULL);
/* Fluid particle type can't be checked from the type value in RNA
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index bc9aabbefe6..5f74e8cfc78 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -132,7 +132,7 @@ static char *rna_PoseBone_path(PointerRNA *ptr)
bPoseChannel *pchan = ptr->data;
char name_esc[sizeof(pchan->name) * 2];
- BLI_strescape(name_esc, pchan->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, pchan->name, sizeof(name_esc));
return BLI_sprintfN("pose.bones[\"%s\"]", name_esc);
}
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index eae1c7bc223..98ae7591062 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -1360,7 +1360,7 @@ static int rna_property_override_diff_propptr(Main *bmain,
BLI_assert(STREQ(rna_itemname_a, rna_itemname_b));
char esc_item_name[RNA_PATH_BUFFSIZE];
- const size_t esc_item_name_len = BLI_strescape(
+ const size_t esc_item_name_len = BLI_str_escape(
esc_item_name, rna_itemname_a, RNA_PATH_BUFFSIZE);
extended_rna_path_len = rna_path_len + 2 + esc_item_name_len + 2;
if (extended_rna_path_len >= RNA_PATH_BUFFSIZE) {
@@ -1858,7 +1858,7 @@ int rna_property_override_diff_default(Main *bmain,
is_id,
is_valid_for_diffing,
is_valid_for_insertion,
- (RNA_property_override_flag(prop_a) & PROPOVERRIDE_LIBRARY_INSERTION) != 0,
+ use_collection_insertion,
do_create);
}
# endif
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 235042122e6..da03921bca6 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -390,7 +390,7 @@ const EnumPropertyItem rna_enum_image_color_mode_items[] = {
"BW",
0,
"BW",
- "Images get saved in 8 bits grayscale (only PNG, JPEG, TGA, TIF)"},
+ "Images get saved in 8-bit grayscale (only PNG, JPEG, TGA, TIF)"},
{R_IMF_PLANES_RGB, "RGB", 0, "RGB", "Images are saved with RGB (color) data"},
{R_IMF_PLANES_RGBA,
"RGBA",
@@ -408,12 +408,12 @@ const EnumPropertyItem rna_enum_image_color_mode_items[] = {
const EnumPropertyItem rna_enum_image_color_depth_items[] = {
/* 1 (monochrome) not used */
- {R_IMF_CHAN_DEPTH_8, "8", 0, "8", "8 bit color channels"},
- {R_IMF_CHAN_DEPTH_10, "10", 0, "10", "10 bit color channels"},
- {R_IMF_CHAN_DEPTH_12, "12", 0, "12", "12 bit color channels"},
- {R_IMF_CHAN_DEPTH_16, "16", 0, "16", "16 bit color channels"},
+ {R_IMF_CHAN_DEPTH_8, "8", 0, "8", "8-bit color channels"},
+ {R_IMF_CHAN_DEPTH_10, "10", 0, "10", "10-bit color channels"},
+ {R_IMF_CHAN_DEPTH_12, "12", 0, "12", "12-bit color channels"},
+ {R_IMF_CHAN_DEPTH_16, "16", 0, "16", "16-bit color channels"},
/* 24 not used */
- {R_IMF_CHAN_DEPTH_32, "32", 0, "32", "32 bit color channels"},
+ {R_IMF_CHAN_DEPTH_32, "32", 0, "32", "32-bit color channels"},
{0, NULL, 0, NULL, NULL},
};
@@ -529,6 +529,12 @@ const EnumPropertyItem rna_enum_bake_pass_filter_type_items[] = {
{0, NULL, 0, NULL, NULL},
};
+static const EnumPropertyItem rna_enum_view_layer_aov_type_items[] = {
+ {AOV_TYPE_COLOR, "COLOR", 0, "Color", ""},
+ {AOV_TYPE_VALUE, "VALUE", 0, "Value", ""},
+ {0, NULL, 0, NULL, NULL},
+};
+
#ifndef RNA_RUNTIME
static const EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = {
/* interpolation */
@@ -1779,6 +1785,27 @@ void rna_ViewLayer_pass_update(Main *bmain, Scene *activescene, PointerRNA *ptr)
ntreeCompositUpdateRLayers(scene->nodetree);
}
+ ViewLayer *view_layer = NULL;
+ if (ptr->type == &RNA_ViewLayer) {
+ view_layer = (ViewLayer *)ptr->data;
+ }
+ else if (ptr->type == &RNA_AOV) {
+ ViewLayerAOV *aov = (ViewLayerAOV *)ptr->data;
+ view_layer = BKE_view_layer_find_with_aov(scene, aov);
+ }
+
+ if (view_layer) {
+ RenderEngineType *engine_type = RE_engines_find(scene->r.engine);
+ if (engine_type->update_render_passes) {
+ RenderEngine *engine = RE_engine_create(engine_type);
+ if (engine) {
+ BKE_view_layer_verify_aov(engine, scene, view_layer);
+ }
+ RE_engine_free(engine);
+ engine = NULL;
+ }
+ }
+
rna_Scene_glsl_update(bmain, activescene, ptr);
}
@@ -2397,6 +2424,28 @@ static void rna_ViewLayer_remove(
}
}
+void rna_ViewLayer_active_aov_index_range(
+ PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax))
+{
+ ViewLayer *view_layer = (ViewLayer *)ptr->data;
+
+ *min = 0;
+ *max = max_ii(0, BLI_listbase_count(&view_layer->aovs) - 1);
+}
+
+int rna_ViewLayer_active_aov_index_get(PointerRNA *ptr)
+{
+ ViewLayer *view_layer = (ViewLayer *)ptr->data;
+ return BLI_findindex(&view_layer->aovs, view_layer->active_aov);
+}
+
+void rna_ViewLayer_active_aov_index_set(PointerRNA *ptr, int value)
+{
+ ViewLayer *view_layer = (ViewLayer *)ptr->data;
+ ViewLayerAOV *aov = BLI_findlink(&view_layer->aovs, value);
+ view_layer->active_aov = aov;
+}
+
/* Fake value, used internally (not saved to DNA). */
# define V3D_ORIENT_DEFAULT -1
@@ -3944,7 +3993,7 @@ static void rna_def_view_layer_eevee(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "ViewLayerEEVEE", NULL);
- RNA_def_struct_ui_text(srna, "EEVEE Settings", "View layer settings for EEVEE");
+ RNA_def_struct_ui_text(srna, "Eevee Settings", "View layer settings for Eevee");
prop = RNA_def_property(srna, "use_pass_volume_scatter", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "render_passes", EEVEE_RENDER_PASS_VOLUME_SCATTER);
@@ -3963,6 +4012,33 @@ static void rna_def_view_layer_eevee(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
}
+static void rna_def_view_layer_aov(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+ srna = RNA_def_struct(brna, "AOV", NULL);
+ RNA_def_struct_sdna(srna, "ViewLayerAOV");
+ RNA_def_struct_ui_text(srna, "Shader AOV", "");
+
+ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "name");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Name", "Name of the AOV");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
+ RNA_def_struct_name_property(srna, prop);
+
+ prop = RNA_def_property(srna, "is_valid", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", AOV_CONFLICT);
+ RNA_def_property_ui_text(prop, "Valid", "Is the name of the AOV conflicting");
+
+ prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "type");
+ RNA_def_property_enum_items(prop, rna_enum_view_layer_aov_type_items);
+ RNA_def_property_enum_default(prop, AOV_TYPE_COLOR);
+ RNA_def_property_ui_text(prop, "Type", "Data type of the AOV");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
+}
+
void rna_def_view_layer_common(StructRNA *srna, const bool scene)
{
PropertyRNA *prop;
@@ -4012,7 +4088,65 @@ void rna_def_view_layer_common(StructRNA *srna, const bool scene)
prop = RNA_def_property(srna, "eevee", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "ViewLayerEEVEE");
- RNA_def_property_ui_text(prop, "EEVEE Settings", "View layer settings for EEVEE");
+ RNA_def_property_ui_text(prop, "Eevee Settings", "View layer settings for Eevee");
+
+ prop = RNA_def_property(srna, "aovs", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "aovs", NULL);
+ RNA_def_property_struct_type(prop, "AOV");
+ RNA_def_property_ui_text(prop, "Shader AOV", "");
+
+ prop = RNA_def_property(srna, "active_aov", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "AOV");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Shader AOV", "Active AOV");
+
+ prop = RNA_def_property(srna, "active_aov_index", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_funcs(prop,
+ "rna_ViewLayer_active_aov_index_get",
+ "rna_ViewLayer_active_aov_index_set",
+ "rna_ViewLayer_active_aov_index_range");
+ RNA_def_property_ui_text(prop, "Active AOV Index", "Index of active aov");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "use_pass_cryptomatte_object", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "cryptomatte_flag", VIEW_LAYER_CRYPTOMATTE_OBJECT);
+ RNA_def_property_ui_text(
+ prop,
+ "Cryptomatte Object",
+ "Render cryptomatte object pass, for isolating objects in compositing");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
+
+ prop = RNA_def_property(srna, "use_pass_cryptomatte_material", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "cryptomatte_flag", VIEW_LAYER_CRYPTOMATTE_MATERIAL);
+ RNA_def_property_ui_text(
+ prop,
+ "Cryptomatte Material",
+ "Render cryptomatte material pass, for isolating materials in compositing");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
+
+ prop = RNA_def_property(srna, "use_pass_cryptomatte_asset", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "cryptomatte_flag", VIEW_LAYER_CRYPTOMATTE_ASSET);
+ RNA_def_property_ui_text(
+ prop,
+ "Cryptomatte Asset",
+ "Render cryptomatte asset pass, for isolating groups of objects with the same parent");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
+
+ prop = RNA_def_property(srna, "pass_cryptomatte_depth", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "cryptomatte_levels");
+ RNA_def_property_int_default(prop, 6);
+ RNA_def_property_range(prop, 2.0, 16.0);
+ RNA_def_property_ui_text(
+ prop, "Cryptomatte Levels", "Sets how many unique objects can be distinguished per pixel");
+ RNA_def_property_ui_range(prop, 2.0, 16.0, 2.0, 0.0);
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
+
+ prop = RNA_def_property(srna, "use_pass_cryptomatte_accurate", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "cryptomatte_flag", VIEW_LAYER_CRYPTOMATTE_ACCURATE);
+ RNA_def_property_boolean_default(prop, true);
+ RNA_def_property_ui_text(
+ prop, "Cryptomatte Accurate", "Generate a more accurate cryptomatte pass");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
}
/* layer options */
@@ -5353,7 +5487,7 @@ static void rna_def_scene_image_format_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_zbuffer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", R_IMF_FLAG_ZBUF);
RNA_def_property_ui_text(
- prop, "Z Buffer", "Save the z-depth per pixel (32 bit unsigned int z-buffer)");
+ prop, "Z Buffer", "Save the z-depth per pixel (32-bit unsigned integer z-buffer)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "use_preview", PROP_BOOLEAN, PROP_NONE);
@@ -5589,26 +5723,26 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "video_bitrate", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "video_bitrate");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Bitrate", "Video bitrate (kb/s)");
+ RNA_def_property_ui_text(prop, "Bitrate", "Video bitrate (kbit/s)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "minrate", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "rc_min_rate");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Min Rate", "Rate control: min rate (kb/s)");
+ RNA_def_property_ui_text(prop, "Min Rate", "Rate control: min rate (kbit/s)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "maxrate", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "rc_max_rate");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Max Rate", "Rate control: max rate (kb/s)");
+ RNA_def_property_ui_text(prop, "Max Rate", "Rate control: max rate (kbit/s)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "muxrate", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "mux_rate");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0, 100000000);
- RNA_def_property_ui_text(prop, "Mux Rate", "Mux rate (bits/s(!))");
+ RNA_def_property_ui_text(prop, "Mux Rate", "Mux rate (bits/second)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "gopsize", PROP_INT, PROP_NONE);
@@ -7289,7 +7423,7 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_shadow_high_bitdepth", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SHADOW_HIGH_BITDEPTH);
- RNA_def_property_ui_text(prop, "High Bitdepth", "Use 32bit shadows");
+ RNA_def_property_ui_text(prop, "High Bit Depth", "Use 32-bit shadows");
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
@@ -7824,7 +7958,7 @@ void RNA_def_scene(BlenderRNA *brna)
/* EEVEE */
prop = RNA_def_property(srna, "eevee", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "SceneEEVEE");
- RNA_def_property_ui_text(prop, "EEVEE", "EEVEE settings for the scene");
+ RNA_def_property_ui_text(prop, "Eevee", "Eevee settings for the scene");
/* Grease Pencil */
prop = RNA_def_property(srna, "grease_pencil_settings", PROP_POINTER, PROP_NONE);
@@ -7848,6 +7982,7 @@ void RNA_def_scene(BlenderRNA *brna)
rna_def_display_safe_areas(brna);
rna_def_scene_display(brna);
rna_def_scene_eevee(brna);
+ rna_def_view_layer_aov(brna);
rna_def_view_layer_eevee(brna);
rna_def_scene_gpencil(brna);
RNA_define_animate_sdna(true);
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index ac45cd5c5ff..9e7fbf2f9a9 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -506,7 +506,7 @@ static char *rna_SequenceTransform_path(PointerRNA *ptr)
if (seq && seq->name + 2) {
char name_esc[(sizeof(seq->name) - 2) * 2];
- BLI_strescape(name_esc, seq->name + 2, sizeof(name_esc));
+ BLI_str_escape(name_esc, seq->name + 2, sizeof(name_esc));
return BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].transform", name_esc);
}
else {
@@ -558,7 +558,7 @@ static char *rna_SequenceCrop_path(PointerRNA *ptr)
if (seq && seq->name + 2) {
char name_esc[(sizeof(seq->name) - 2) * 2];
- BLI_strescape(name_esc, seq->name + 2, sizeof(name_esc));
+ BLI_str_escape(name_esc, seq->name + 2, sizeof(name_esc));
return BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].crop", name_esc);
}
else {
@@ -704,7 +704,7 @@ static char *rna_Sequence_path(PointerRNA *ptr)
if (seq->name + 2) {
char name_esc[(sizeof(seq->name) - 2) * 2];
- BLI_strescape(name_esc, seq->name + 2, sizeof(name_esc));
+ BLI_str_escape(name_esc, seq->name + 2, sizeof(name_esc));
return BLI_sprintfN("sequence_editor.sequences_all[\"%s\"]", name_esc);
}
else {
@@ -1023,7 +1023,7 @@ static char *rna_SequenceColorBalance_path(PointerRNA *ptr)
if (seq && seq->name + 2) {
char name_esc[(sizeof(seq->name) - 2) * 2];
- BLI_strescape(name_esc, seq->name + 2, sizeof(name_esc));
+ BLI_str_escape(name_esc, seq->name + 2, sizeof(name_esc));
if (!smd) {
/* path to old filter color balance */
@@ -1033,7 +1033,7 @@ static char *rna_SequenceColorBalance_path(PointerRNA *ptr)
/* path to modifier */
char name_esc_smd[sizeof(smd->name) * 2];
- BLI_strescape(name_esc_smd, smd->name, sizeof(name_esc_smd));
+ BLI_str_escape(name_esc_smd, smd->name, sizeof(name_esc_smd));
return BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].modifiers[\"%s\"].color_balance",
name_esc,
name_esc_smd);
@@ -1168,8 +1168,8 @@ static char *rna_SequenceModifier_path(PointerRNA *ptr)
char name_esc[(sizeof(seq->name) - 2) * 2];
char name_esc_smd[sizeof(smd->name) * 2];
- BLI_strescape(name_esc, seq->name + 2, sizeof(name_esc));
- BLI_strescape(name_esc_smd, smd->name, sizeof(name_esc_smd));
+ BLI_str_escape(name_esc, seq->name + 2, sizeof(name_esc));
+ BLI_str_escape(name_esc_smd, smd->name, sizeof(name_esc_smd));
return BLI_sprintfN(
"sequence_editor.sequences_all[\"%s\"].modifiers[\"%s\"]", name_esc, name_esc_smd);
}
@@ -1408,7 +1408,7 @@ static void rna_def_strip_transform(BlenderRNA *brna)
prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "rotation");
- RNA_def_property_ui_text(prop, "Rotation", "Rotate around image centr");
+ RNA_def_property_ui_text(prop, "Rotation", "Rotate around image center");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update");
RNA_def_struct_path_func(srna, "rna_SequenceTransform_path");
diff --git a/source/blender/makesrna/intern/rna_shader_fx.c b/source/blender/makesrna/intern/rna_shader_fx.c
index 7b039b91188..451cc56eba7 100644
--- a/source/blender/makesrna/intern/rna_shader_fx.c
+++ b/source/blender/makesrna/intern/rna_shader_fx.c
@@ -161,7 +161,7 @@ static char *rna_ShaderFx_path(PointerRNA *ptr)
ShaderFxData *gmd = ptr->data;
char name_esc[sizeof(gmd->name) * 2];
- BLI_strescape(name_esc, gmd->name, sizeof(name_esc));
+ BLI_str_escape(name_esc, gmd->name, sizeof(name_esc));
return BLI_sprintfN("shader_effects[\"%s\"]", name_esc);
}
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 8ff4336ba83..65ea155ffba 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -426,6 +426,9 @@ static const EnumPropertyItem rna_enum_view3dshading_render_pass_type_items[] =
{EEVEE_RENDER_PASS_NORMAL, "NORMAL", 0, "Normal", ""},
{EEVEE_RENDER_PASS_MIST, "MIST", 0, "Mist", ""},
+ {0, "", ICON_NONE, "Shader AOV", ""},
+ {EEVEE_RENDER_PASS_AOV, "AOV", 0, "AOV", ""},
+
{0, NULL, 0, NULL, NULL},
};
@@ -1065,6 +1068,19 @@ static Scene *rna_3DViewShading_scene(PointerRNA *ptr)
}
}
+static ViewLayer *rna_3DViewShading_view_layer(PointerRNA *ptr)
+{
+ /* Get scene, depends if using 3D view or OpenGL render settings. */
+ ID *id = ptr->owner_id;
+ if (GS(id->name) == ID_SCE) {
+ return NULL;
+ }
+ else {
+ bScreen *screen = (bScreen *)ptr->owner_id;
+ return WM_windows_view_layer_get_from_screen(G_MAIN->wm.first, screen);
+ }
+}
+
static int rna_3DViewShading_type_get(PointerRNA *ptr)
{
/* Available shading types depend on render engine. */
@@ -1292,15 +1308,33 @@ static const EnumPropertyItem *rna_3DViewShading_render_pass_itemf(bContext *C,
bool *r_free)
{
Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
const bool bloom_enabled = scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED;
+ const bool aov_available = BKE_view_layer_has_valid_aov(view_layer);
int totitem = 0;
EnumPropertyItem *result = NULL;
+ EnumPropertyItem aov_template;
for (int i = 0; rna_enum_view3dshading_render_pass_type_items[i].identifier != NULL; i++) {
const EnumPropertyItem *item = &rna_enum_view3dshading_render_pass_type_items[i];
- if (!((!bloom_enabled &&
- (item->value == EEVEE_RENDER_PASS_BLOOM || STREQ(item->name, "Effects"))))) {
+ if (item->value == EEVEE_RENDER_PASS_AOV) {
+ aov_template.value = item->value;
+ aov_template.icon = 0;
+ aov_template.description = item->description;
+ LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
+ if ((aov->flag & AOV_CONFLICT) != 0) {
+ continue;
+ }
+ aov_template.name = aov->name;
+ aov_template.identifier = aov->name;
+ RNA_enum_item_add(&result, &totitem, &aov_template);
+ aov_template.value++;
+ }
+ }
+ else if (!((!bloom_enabled &&
+ (item->value == EEVEE_RENDER_PASS_BLOOM || STREQ(item->name, "Effects"))) ||
+ (!aov_available && STREQ(item->name, "Shader AOV")))) {
RNA_enum_item_add(&result, &totitem, item);
}
}
@@ -1314,14 +1348,58 @@ static int rna_3DViewShading_render_pass_get(PointerRNA *ptr)
View3DShading *shading = (View3DShading *)ptr->data;
eViewLayerEEVEEPassType result = shading->render_pass;
Scene *scene = rna_3DViewShading_scene(ptr);
+ ViewLayer *view_layer = rna_3DViewShading_view_layer(ptr);
if (result == EEVEE_RENDER_PASS_BLOOM && ((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) {
- result = EEVEE_RENDER_PASS_COMBINED;
+ return EEVEE_RENDER_PASS_COMBINED;
+ }
+ else if (result == EEVEE_RENDER_PASS_AOV) {
+ if (!view_layer) {
+ return EEVEE_RENDER_PASS_COMBINED;
+ }
+ const int aov_index = BLI_findstringindex(
+ &view_layer->aovs, shading->aov_name, offsetof(ViewLayerAOV, name));
+ if (aov_index == -1) {
+ return EEVEE_RENDER_PASS_COMBINED;
+ }
+ return result + aov_index;
}
return result;
}
+static void rna_3DViewShading_render_pass_set(PointerRNA *ptr, int value)
+{
+ View3DShading *shading = (View3DShading *)ptr->data;
+ Scene *scene = rna_3DViewShading_scene(ptr);
+ ViewLayer *view_layer = rna_3DViewShading_view_layer(ptr);
+ shading->aov_name[0] = 0;
+
+ if ((value & EEVEE_RENDER_PASS_AOV) != 0) {
+ if (!view_layer) {
+ shading->render_pass = EEVEE_RENDER_PASS_COMBINED;
+ return;
+ }
+ const int aov_index = value & ~EEVEE_RENDER_PASS_AOV;
+ ViewLayerAOV *aov = BLI_findlink(&view_layer->aovs, aov_index);
+ if (!aov) {
+ /* AOV not found, cannot select AOV. */
+ shading->render_pass = EEVEE_RENDER_PASS_COMBINED;
+ return;
+ }
+
+ shading->render_pass = EEVEE_RENDER_PASS_AOV;
+ BLI_strncpy(shading->aov_name, aov->name, sizeof(aov->name));
+ }
+ else if (value == EEVEE_RENDER_PASS_BLOOM &&
+ ((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) {
+ shading->render_pass = EEVEE_RENDER_PASS_COMBINED;
+ }
+ else {
+ shading->render_pass = value;
+ }
+}
+
static void rna_SpaceView3D_use_local_collections_update(bContext *C, PointerRNA *ptr)
{
Main *bmain = CTX_data_main(C);
@@ -2035,7 +2113,7 @@ static void rna_SpaceDopeSheetEditor_action_update(bContext *C, PointerRNA *ptr)
* and the user then uses the browse menu to get back to this action,
* assigning it as the active action (i.e. the stash strip gets out of sync)
*/
- BKE_nla_action_stash(adt);
+ BKE_nla_action_stash(adt, ID_IS_OVERRIDE_LIBRARY(id));
}
BKE_animdata_set_action(NULL, id, saction->action);
@@ -2389,6 +2467,18 @@ static PointerRNA rna_FileSelectParams_filter_id_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_FileSelectIDFilter, ptr->data);
}
+static PointerRNA rna_FileBrowser_params_get(PointerRNA *ptr)
+{
+ SpaceFile *sfile = ptr->data;
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+
+ if (params) {
+ return rna_pointer_inherit_refine(ptr, &RNA_FileSelectParams, params);
+ }
+
+ return rna_pointer_inherit_refine(ptr, NULL, NULL);
+}
+
static void rna_FileBrowser_FSMenuEntry_path_get(PointerRNA *ptr, char *value)
{
char *path = ED_fsmenu_entry_get_path(ptr->data);
@@ -3488,9 +3578,17 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "render_pass");
RNA_def_property_enum_items(prop, rna_enum_view3dshading_render_pass_type_items);
RNA_def_property_ui_text(prop, "Render Pass", "Render Pass to show in the viewport");
- RNA_def_property_enum_funcs(
- prop, "rna_3DViewShading_render_pass_get", NULL, "rna_3DViewShading_render_pass_itemf");
+ RNA_def_property_enum_funcs(prop,
+ "rna_3DViewShading_render_pass_get",
+ "rna_3DViewShading_render_pass_set",
+ "rna_3DViewShading_render_pass_itemf");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING, NULL);
+
+ prop = RNA_def_property(srna, "aov_name", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "aov_name");
+ RNA_def_property_ui_text(prop, "Shader AOV Name", "Name of the active Shader AOV");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
}
static void rna_def_space_view3d_overlay(BlenderRNA *brna)
@@ -5957,7 +6055,8 @@ static void rna_def_space_filebrowser(BlenderRNA *brna)
rna_def_space_generic_show_region_toggles(srna, (1 << RGN_TYPE_TOOLS) | (1 << RGN_TYPE_UI));
prop = RNA_def_property(srna, "params", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "params");
+ RNA_def_property_struct_type(prop, "FileSelectParams");
+ RNA_def_property_pointer_funcs(prop, "rna_FileBrowser_params_get", NULL, NULL, NULL);
RNA_def_property_ui_text(
prop, "Filebrowser Parameter", "Parameters and Settings for the Filebrowser");
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index fb6d40b3a55..cf8abf26c0a 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -148,6 +148,7 @@ static const EnumPropertyItem blend_type_items[] = {
# include "BKE_texture.h"
# include "DEG_depsgraph.h"
+# include "DEG_depsgraph_build.h"
# include "ED_node.h"
# include "ED_render.h"
@@ -233,6 +234,12 @@ static void rna_Texture_type_set(PointerRNA *ptr, int value)
BKE_texture_type_set(tex, value);
}
+void rna_TextureSlotTexture_update(bContext *C, PointerRNA *ptr)
+{
+ DEG_relations_tag_update(CTX_data_main(C));
+ rna_TextureSlot_update(C, ptr);
+}
+
void rna_TextureSlot_update(bContext *C, PointerRNA *ptr)
{
ID *id = ptr->owner_id;
@@ -317,7 +324,7 @@ char *rna_TextureSlot_path(PointerRNA *ptr)
if (mtex->tex) {
char name_esc[(sizeof(mtex->tex->id.name) - 2) * 2];
- BLI_strescape(name_esc, mtex->tex->id.name + 2, sizeof(name_esc));
+ BLI_str_escape(name_esc, mtex->tex->id.name + 2, sizeof(name_esc));
return BLI_sprintfN("texture_slots[\"%s\"]", name_esc);
}
else {
@@ -623,7 +630,7 @@ static void rna_def_mtex(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_CONTEXT_UPDATE);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_ui_text(prop, "Texture", "Texture data-block used by this texture slot");
- RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING_LINKS, "rna_TextureSlot_update");
+ RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING_LINKS, "rna_TextureSlotTexture_update");
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 23f3a04fd91..f1f7810bcf0 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -5026,7 +5026,6 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
prop,
"Channel Group Colors",
"Use animation channel group colors; generally this is used to show bone group colors");
- RNA_def_property_boolean_default(prop, true);
RNA_def_property_update(prop, 0, "rna_userdef_anim_update");
prop = RNA_def_property(srna, "fcurve_new_auto_smoothing", PROP_ENUM, PROP_NONE);
@@ -5274,12 +5273,12 @@ static void rna_def_userdef_system(BlenderRNA *brna)
};
static const EnumPropertyItem audio_format_items[] = {
- {0x01, "U8", 0, "8-bit Unsigned", "Set audio sample format to 8 bit unsigned integer"},
- {0x12, "S16", 0, "16-bit Signed", "Set audio sample format to 16 bit signed integer"},
- {0x13, "S24", 0, "24-bit Signed", "Set audio sample format to 24 bit signed integer"},
- {0x14, "S32", 0, "32-bit Signed", "Set audio sample format to 32 bit signed integer"},
- {0x24, "FLOAT", 0, "32-bit Float", "Set audio sample format to 32 bit float"},
- {0x28, "DOUBLE", 0, "64-bit Float", "Set audio sample format to 64 bit float"},
+ {0x01, "U8", 0, "8-bit Unsigned", "Set audio sample format to 8-bit unsigned integer"},
+ {0x12, "S16", 0, "16-bit Signed", "Set audio sample format to 16-bit signed integer"},
+ {0x13, "S24", 0, "24-bit Signed", "Set audio sample format to 24-bit signed integer"},
+ {0x14, "S32", 0, "32-bit Signed", "Set audio sample format to 32-bit signed integer"},
+ {0x24, "FLOAT", 0, "32-bit Float", "Set audio sample format to 32-bit float"},
+ {0x28, "DOUBLE", 0, "64-bit Float", "Set audio sample format to 64-bit float"},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/makesrna/intern/rna_volume.c b/source/blender/makesrna/intern/rna_volume.c
index 37b34f68be5..42d491b734e 100644
--- a/source/blender/makesrna/intern/rna_volume.c
+++ b/source/blender/makesrna/intern/rna_volume.c
@@ -228,8 +228,8 @@ static void rna_def_volume_grid(BlenderRNA *brna)
{VOLUME_GRID_BOOLEAN, "BOOLEAN", 0, "Boolean", "Boolean"},
{VOLUME_GRID_FLOAT, "FLOAT", 0, "Float", "Single precision float"},
{VOLUME_GRID_DOUBLE, "DOUBLE", 0, "Double", "Double precision"},
- {VOLUME_GRID_INT, "INT", 0, "Integer", "32 bit integer"},
- {VOLUME_GRID_INT64, "INT64", 0, "Integer 64 bit", "64 bit integer"},
+ {VOLUME_GRID_INT, "INT", 0, "Integer", "32-bit integer"},
+ {VOLUME_GRID_INT64, "INT64", 0, "Integer 64-bit", "64-bit integer"},
{VOLUME_GRID_MASK, "MASK", 0, "Mask", "No data, boolean mask of active voxels"},
{VOLUME_GRID_STRING, "STRING", 0, "String", "Text string"},
{VOLUME_GRID_VECTOR_FLOAT, "VECTOR_FLOAT", 0, "Float Vector", "3D float vector"},
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c
index 4152e8633e5..0513d3af13a 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -630,7 +630,15 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
Object *operand_ob = bmd->object;
+#ifdef DEBUG_TIME
+ TIMEIT_BLOCK_INIT(operand_get_evaluated_mesh);
+ TIMEIT_BLOCK_START(operand_get_evaluated_mesh);
+#endif
mesh_operand_ob = BKE_modifier_get_evaluated_mesh_from_evaluated_object(operand_ob, false);
+#ifdef DEBUG_TIME
+ TIMEIT_BLOCK_END(operand_get_evaluated_mesh);
+ TIMEIT_BLOCK_STATS(operand_get_evaluated_mesh);
+#endif
if (mesh_operand_ob) {
/* XXX This is utterly non-optimal, we may go from a bmesh to a mesh back to a bmesh!
@@ -642,11 +650,35 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
result = get_quick_mesh(object, mesh, operand_ob, mesh_operand_ob, bmd->operation);
if (result == NULL) {
+#ifdef DEBUG_TIME
+ TIMEIT_BLOCK_INIT(object_BMD_mesh_bm_create);
+ TIMEIT_BLOCK_START(object_BMD_mesh_bm_create);
+#endif
bm = BMD_mesh_bm_create(mesh, object, mesh_operand_ob, operand_ob, &is_flip);
+#ifdef DEBUG_TIME
+ TIMEIT_BLOCK_END(object_BMD_mesh_bm_create);
+ TIMEIT_BLOCK_STATS(object_BMD_mesh_bm_create);
+#endif
+#ifdef DEBUG_TIME
+ TIMEIT_BLOCK_INIT(BMD_mesh_intersection);
+ TIMEIT_BLOCK_START(BMD_mesh_intersection);
+#endif
BMD_mesh_intersection(bm, md, ctx, mesh_operand_ob, object, operand_ob, is_flip);
+#ifdef DEBUG_TIME
+ TIMEIT_BLOCK_END(BMD_mesh_intersection);
+ TIMEIT_BLOCK_STATS(BMD_mesh_intersection);
+#endif
+#ifdef DEBUG_TIME
+ TIMEIT_BLOCK_INIT(BKE_mesh_from_bmesh_for_eval_nomain);
+ TIMEIT_BLOCK_START(BKE_mesh_from_bmesh_for_eval_nomain);
+#endif
result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
+#ifdef DEBUG_TIME
+ TIMEIT_BLOCK_END(BKE_mesh_from_bmesh_for_eval_nomain);
+ TIMEIT_BLOCK_STATS(BKE_mesh_from_bmesh_for_eval_nomain);
+#endif
BM_mesh_free(bm);
result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
}
diff --git a/source/blender/modifiers/intern/MOD_weld.c b/source/blender/modifiers/intern/MOD_weld.c
index 1a25c24fedc..e34dcf48c19 100644
--- a/source/blender/modifiers/intern/MOD_weld.c
+++ b/source/blender/modifiers/intern/MOD_weld.c
@@ -1567,6 +1567,12 @@ static bool bvhtree_weld_overlap_cb(void *userdata, int index_a, int index_b, in
}
#endif
+/** Use for #MOD_WELD_MODE_CONNECTED calculation. */
+struct WeldVertexCluster {
+ float co[3];
+ uint merged_verts;
+};
+
static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContext *ctx, Mesh *mesh)
{
Mesh *result = mesh;
@@ -1606,6 +1612,7 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex
* This indicates which vert it is or is going to be merged. */
uint *vert_dest_map = MEM_malloc_arrayN(totvert, sizeof(*vert_dest_map), __func__);
uint vert_kill_len = 0;
+ if (wmd->mode == MOD_WELD_MODE_ALL)
#ifdef USE_BVHTREEKDOP
{
/* Get overlap map. */
@@ -1701,6 +1708,80 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex
BLI_kdtree_3d_free(tree);
}
#endif
+ else {
+ BLI_assert(wmd->mode == MOD_WELD_MODE_CONNECTED);
+
+ MEdge *medge, *me;
+
+ medge = mesh->medge;
+ totvert = mesh->totvert;
+ totedge = mesh->totedge;
+
+ struct WeldVertexCluster *vert_clusters = MEM_malloc_arrayN(
+ totvert, sizeof(*vert_clusters), __func__);
+ struct WeldVertexCluster *vc = &vert_clusters[0];
+ for (uint i = 0; i < totvert; i++, vc++) {
+ copy_v3_v3(vc->co, mvert[i].co);
+ vc->merged_verts = 0;
+ }
+ const float merge_dist_sq = square_f(wmd->merge_dist);
+
+ range_vn_u(vert_dest_map, totvert, 0);
+
+ /* Collapse Edges that are shorter than the threshold. */
+ me = &medge[0];
+ for (uint i = 0; i < totedge; i++, me++) {
+ uint v1 = me->v1;
+ uint v2 = me->v2;
+
+ while (v1 != vert_dest_map[v1]) {
+ v1 = vert_dest_map[v1];
+ }
+ while (v2 != vert_dest_map[v2]) {
+ v2 = vert_dest_map[v2];
+ }
+ if (v1 == v2) {
+ continue;
+ }
+ if (v_mask && (!BLI_BITMAP_TEST(v_mask, v1) || !BLI_BITMAP_TEST(v_mask, v2))) {
+ continue;
+ }
+ if (v1 > v2) {
+ SWAP(uint, v1, v2);
+ }
+ struct WeldVertexCluster *v1_cluster = &vert_clusters[v1];
+ struct WeldVertexCluster *v2_cluster = &vert_clusters[v2];
+
+ float edgedir[3];
+ sub_v3_v3v3(edgedir, v2_cluster->co, v1_cluster->co);
+ const float dist_sq = len_squared_v3(edgedir);
+ if (dist_sq <= merge_dist_sq) {
+ float influence = (v2_cluster->merged_verts + 1) /
+ (float)(v1_cluster->merged_verts + v2_cluster->merged_verts + 2);
+ madd_v3_v3fl(v1_cluster->co, edgedir, influence);
+
+ v1_cluster->merged_verts += v2_cluster->merged_verts + 1;
+ vert_dest_map[v2] = v1;
+ vert_kill_len++;
+ }
+ }
+
+ MEM_freeN(vert_clusters);
+
+ for (uint i = 0; i < totvert; i++) {
+ if (i == vert_dest_map[i]) {
+ vert_dest_map[i] = OUT_OF_CONTEXT;
+ }
+ else {
+ uint v = i;
+ while ((v != vert_dest_map[v]) && (vert_dest_map[v] != OUT_OF_CONTEXT)) {
+ v = vert_dest_map[v];
+ }
+ vert_dest_map[v] = v;
+ vert_dest_map[i] = v;
+ }
+ }
+ }
if (v_mask) {
MEM_freeN(v_mask);
@@ -1940,6 +2021,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiLayoutSetPropSep(layout, true);
+ uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "merge_threshold", 0, IFACE_("Distance"), ICON_NONE);
modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh
index 2b95f76d06b..a7df4bc3e1b 100644
--- a/source/blender/nodes/NOD_geometry_exec.hh
+++ b/source/blender/nodes/NOD_geometry_exec.hh
@@ -26,6 +26,8 @@
namespace blender::nodes {
+using bke::Color4fReadAttribute;
+using bke::Color4fWriteAttribute;
using bke::Float3ReadAttribute;
using bke::Float3WriteAttribute;
using bke::FloatReadAttribute;
@@ -146,6 +148,26 @@ class GeoNodeExecParams {
return self_object_;
}
+ /**
+ * Creates a read-only attribute based on node inputs. The method automatically detects which
+ * input with the given name is available.
+ */
+ ReadAttributePtr get_input_attribute(const StringRef name,
+ const GeometryComponent &component,
+ const AttributeDomain domain,
+ const CustomDataType type,
+ const void *default_value) const;
+
+ template<typename T>
+ bke::TypedReadAttribute<T> get_input_attribute(const StringRef name,
+ const GeometryComponent &component,
+ const AttributeDomain domain,
+ const T &default_value) const
+ {
+ const CustomDataType type = bke::cpp_type_to_custom_data_type(CPPType::get<T>());
+ return this->get_input_attribute(name, component, domain, type, &default_value);
+ }
+
private:
/* Utilities for detecting common errors at when using this class. */
void check_extract_input(StringRef identifier, const CPPType *requested_type = nullptr) const;
diff --git a/source/blender/nodes/geometry/node_geometry_tree.cc b/source/blender/nodes/geometry/node_geometry_tree.cc
index 69f9f7fb4ed..da77e8896fb 100644
--- a/source/blender/nodes/geometry/node_geometry_tree.cc
+++ b/source/blender/nodes/geometry/node_geometry_tree.cc
@@ -14,7 +14,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include <string.h>
+#include <cstring>
#include "MEM_guardedalloc.h"
diff --git a/source/blender/nodes/geometry/node_geometry_util.cc b/source/blender/nodes/geometry/node_geometry_util.cc
index 41bdb1cfff0..34c7d224f03 100644
--- a/source/blender/nodes/geometry/node_geometry_util.cc
+++ b/source/blender/nodes/geometry/node_geometry_util.cc
@@ -17,6 +17,27 @@
#include "node_geometry_util.hh"
#include "node_util.h"
+namespace blender::nodes {
+
+void update_attribute_input_socket_availabilities(bNode &node,
+ const StringRef name,
+ const GeometryNodeAttributeInputMode mode)
+{
+ const GeometryNodeAttributeInputMode mode_ = (GeometryNodeAttributeInputMode)mode;
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) {
+ if (name == socket->name) {
+ const bool is_available =
+ ((socket->type == SOCK_STRING && mode_ == GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE) ||
+ (socket->type == SOCK_FLOAT && mode_ == GEO_NODE_ATTRIBUTE_INPUT_FLOAT) ||
+ (socket->type == SOCK_VECTOR && mode_ == GEO_NODE_ATTRIBUTE_INPUT_VECTOR) ||
+ (socket->type == SOCK_RGBA && mode_ == GEO_NODE_ATTRIBUTE_INPUT_COLOR));
+ nodeSetSocketAvailability(socket, is_available);
+ }
+ }
+}
+
+} // namespace blender::nodes
+
bool geo_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree)
{
return STREQ(ntree->idname, "GeometryNodeTree");
diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh
index bb26763642b..ec389961615 100644
--- a/source/blender/nodes/geometry/node_geometry_util.hh
+++ b/source/blender/nodes/geometry/node_geometry_util.hh
@@ -37,3 +37,9 @@
void geo_node_type_base(
struct bNodeType *ntype, int type, const char *name, short nclass, short flag);
bool geo_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree);
+
+namespace blender::nodes {
+void update_attribute_input_socket_availabilities(bNode &node,
+ const StringRef name,
+ const GeometryNodeAttributeInputMode mode);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_common.cc b/source/blender/nodes/geometry/nodes/node_geo_common.cc
index 8adc3962698..441ad6bdc13 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_common.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_common.cc
@@ -26,7 +26,7 @@ void register_node_type_geo_group(void)
{
static bNodeType ntype;
- node_type_base_custom(&ntype, "GeometryNodeGroup", "Group", 0, 0);
+ node_type_base_custom(&ntype, "GeometryNodeGroup", "Group", NODE_CLASS_GROUP, 0);
ntype.type = NODE_GROUP;
ntype.poll = geo_node_poll_default;
ntype.poll_instance = node_group_poll_instance;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
index e5e7cf57e27..543859aef3f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
@@ -16,6 +16,7 @@
#include "MEM_guardedalloc.h"
+#include "BKE_mesh.h"
#include "BKE_subdiv.h"
#include "BKE_subdiv_mesh.h"
@@ -25,7 +26,7 @@ static bNodeSocketTemplate geo_node_subdivision_surface_in[] = {
{SOCK_GEOMETRY, N_("Geometry")},
{SOCK_INT, N_("Level"), 1, 0, 0, 0, 0, 6},
{SOCK_BOOLEAN, N_("Use Creases")},
- {SOCK_BOOLEAN, N_("Boundary Smooth")},
+ {SOCK_BOOLEAN, N_("Boundary Smooth"), true},
{SOCK_BOOLEAN, N_("Smooth UVs")},
{-1, ""},
};
@@ -76,7 +77,7 @@ static void geo_node_subdivision_surface_exec(GeoNodeExecParams params)
subdiv_settings.level = subdiv_level;
subdiv_settings.vtx_boundary_interpolation = BKE_subdiv_vtx_boundary_interpolation_from_subsurf(
- boundary_smooth);
+ !boundary_smooth);
subdiv_settings.fvar_linear_interpolation = BKE_subdiv_fvar_interpolation_from_uv_smooth(
smooth_uvs);
@@ -90,6 +91,7 @@ static void geo_node_subdivision_surface_exec(GeoNodeExecParams params)
}
Mesh *mesh_out = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh_in);
+ BKE_mesh_calc_normals(mesh_out);
geometry_set.replace_mesh(mesh_out);
diff --git a/source/blender/nodes/intern/node_geometry_exec.cc b/source/blender/nodes/intern/node_geometry_exec.cc
index 50292cb8cfb..a6d9115f01f 100644
--- a/source/blender/nodes/intern/node_geometry_exec.cc
+++ b/source/blender/nodes/intern/node_geometry_exec.cc
@@ -19,6 +19,47 @@
namespace blender::nodes {
+ReadAttributePtr GeoNodeExecParams::get_input_attribute(const StringRef name,
+ const GeometryComponent &component,
+ const AttributeDomain domain,
+ const CustomDataType type,
+ const void *default_value) const
+{
+ const bNodeSocket *found_socket = nullptr;
+ LISTBASE_FOREACH (const bNodeSocket *, socket, &node_.inputs) {
+ if ((socket->flag & SOCK_UNAVAIL) != 0) {
+ continue;
+ }
+ if (name == socket->name) {
+ found_socket = socket;
+ break;
+ }
+ }
+ BLI_assert(found_socket != nullptr);
+
+ if (found_socket->type == SOCK_STRING) {
+ const std::string name = this->get_input<std::string>(found_socket->identifier);
+ return component.attribute_get_for_read(name, domain, type, default_value);
+ }
+ if (found_socket->type == SOCK_FLOAT) {
+ const float value = this->get_input<float>(found_socket->identifier);
+ return component.attribute_get_constant_for_read_converted(
+ domain, CD_PROP_FLOAT, type, &value);
+ }
+ if (found_socket->type == SOCK_VECTOR) {
+ const float3 value = this->get_input<float3>(found_socket->identifier);
+ return component.attribute_get_constant_for_read_converted(
+ domain, CD_PROP_FLOAT3, type, &value);
+ }
+ if (found_socket->type == SOCK_RGBA) {
+ const Color4f value = this->get_input<Color4f>(found_socket->identifier);
+ return component.attribute_get_constant_for_read_converted(
+ domain, CD_PROP_COLOR, type, &value);
+ }
+ BLI_assert(false);
+ return component.attribute_get_constant_for_read(domain, type, default_value);
+}
+
void GeoNodeExecParams::check_extract_input(StringRef identifier,
const CPPType *requested_type) const
{
diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc
index d4b1df2f3f0..ebc70956147 100644
--- a/source/blender/nodes/intern/node_socket.cc
+++ b/source/blender/nodes/intern/node_socket.cc
@@ -21,7 +21,7 @@
* \ingroup nodes
*/
-#include <limits.h>
+#include <climits>
#include "DNA_node_types.h"
diff --git a/source/blender/nodes/intern/node_tree_multi_function.cc b/source/blender/nodes/intern/node_tree_multi_function.cc
index 8440e996651..ec5527a2970 100644
--- a/source/blender/nodes/intern/node_tree_multi_function.cc
+++ b/source/blender/nodes/intern/node_tree_multi_function.cc
@@ -204,6 +204,10 @@ static DataTypeConversions create_implicit_conversions()
conversions, "float3 to Color4f", [](float3 a) { return Color4f(a.x, a.y, a.z, 1.0f); });
add_implicit_conversion<Color4f, float3>(
conversions, "Color4f to float3", [](Color4f a) { return float3(a.r, a.g, a.b); });
+ add_implicit_conversion<float, Color4f>(
+ conversions, "float to Color4f", [](float a) { return Color4f(a, a, a, 1.0f); });
+ add_implicit_conversion<Color4f, float>(
+ conversions, "Color4f to float", [](Color4f a) { return rgb_to_grayscale(a); });
return conversions;
}
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index efd0e48f41a..a385cb7039f 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -903,6 +903,16 @@ void ntreeGPUMaterialNodes(bNodeTree *localtree,
/* Duplicate bump height branches for manual derivatives.
*/
nodeChainIterBackwards(localtree, output, ntree_shader_bump_branches, localtree, 0);
+ LISTBASE_FOREACH (bNode *, node, &localtree->nodes) {
+ if (node->type == SH_NODE_OUTPUT_AOV) {
+ nodeChainIterBackwards(localtree, node, ntree_shader_bump_branches, localtree, 0);
+ nTreeTags tags = {
+ .ssr_id = 1.0,
+ .sss_id = 1.0,
+ };
+ ntree_shader_tag_nodes(localtree, node, &tags);
+ }
+ }
/* TODO(fclem): consider moving this to the gpu shader tree evaluation. */
nTreeTags tags = {
@@ -913,6 +923,11 @@ void ntreeGPUMaterialNodes(bNodeTree *localtree,
exec = ntreeShaderBeginExecTree(localtree);
ntreeExecGPUNodes(exec, mat, output);
+ LISTBASE_FOREACH (bNode *, node, &localtree->nodes) {
+ if (node->type == SH_NODE_OUTPUT_AOV) {
+ ntreeExecGPUNodes(exec, mat, node);
+ }
+ }
ntreeShaderEndExecTree(exec);
/* EEVEE: Find which material domain was used (volume, surface ...). */
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_aov.c b/source/blender/nodes/shader/nodes/node_shader_output_aov.c
index 8e73a547bf7..403b3e6d9d6 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output_aov.c
+++ b/source/blender/nodes/shader/nodes/node_shader_output_aov.c
@@ -19,6 +19,8 @@
#include "../node_shader_util.h"
+#include "BLI_hash.h"
+
/* **************** OUTPUT ******************** */
static bNodeSocketTemplate sh_node_output_aov_in[] = {
@@ -33,6 +35,22 @@ static void node_shader_init_output_aov(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = aov;
}
+static int node_shader_gpu_output_aov(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData *UNUSED(execdata),
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ GPUNodeLink *outlink;
+ NodeShaderOutputAOV *aov = (NodeShaderOutputAOV *)node->storage;
+ /* Keep in sync with `renderpass_lib.glsl#render_pass_aov_hash`. */
+ unsigned int hash = BLI_hash_string(aov->name) & ~1;
+ GPU_stack_link(mat, node, "node_output_aov", in, out, &outlink);
+ GPU_material_add_output_link_aov(mat, outlink, hash);
+
+ return true;
+}
+
/* node type definition */
void register_node_type_sh_output_aov(void)
{
@@ -43,6 +61,7 @@ void register_node_type_sh_output_aov(void)
node_type_init(&ntype, node_shader_init_output_aov);
node_type_storage(
&ntype, "NodeShaderOutputAOV", node_free_standard_storage, node_copy_standard_storage);
+ node_type_gpu(&ntype, node_shader_gpu_output_aov);
/* Do not allow muting output node. */
node_type_internal_links(&ntype, NULL);
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index a8b66f3f2fe..63fb685e66d 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -20,8 +20,6 @@
#include <Python.h>
-#include <string.h>
-
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
@@ -255,7 +253,7 @@ static int BPy_IDGroup_SetName(BPy_IDProperty *self, PyObject *value, void *UNUS
name = _PyUnicode_AsStringAndSize(value, &name_size);
- if (name_size > MAX_IDPROP_NAME) {
+ if (name_size >= MAX_IDPROP_NAME) {
PyErr_SetString(PyExc_TypeError, "string length cannot exceed 63 characters!");
return -1;
}
@@ -367,16 +365,11 @@ static const char *idp_try_read_name(PyObject *name_obj)
return NULL;
}
- if (name_size > MAX_IDPROP_NAME) {
+ if (name_size >= MAX_IDPROP_NAME) {
PyErr_SetString(PyExc_KeyError,
"the length of IDProperty names is limited to 63 characters");
return NULL;
}
-
- if (strchr(name, '\"') || strchr(name, '\\') || strchr(name, '\'')) {
- PyErr_SetString(PyExc_KeyError, "IDProperty names cannot include \", \\, or \'");
- return NULL;
- }
}
else {
name = "";
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index 772b31fd9d8..5d8330e368d 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -255,7 +255,11 @@ if(WITH_SDL)
list(APPEND INC_SYS
${SDL_INCLUDE_DIR}
)
- if(NOT WITH_SDL_DYNLOAD)
+ if(WITH_SDL_DYNLOAD)
+ list(APPEND LIB
+ extern_sdlew
+ )
+ else()
list(APPEND LIB
${SDL_LIBRARY}
)
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index 804a28d0ebc..6462f8320d7 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -260,25 +260,19 @@ PyDoc_STRVAR(bpy_escape_identifier_doc,
" :rtype: string\n");
static PyObject *bpy_escape_identifier(PyObject *UNUSED(self), PyObject *value)
{
- const char *value_str;
Py_ssize_t value_str_len;
-
- char *value_escape_str;
- Py_ssize_t value_escape_str_len;
- PyObject *value_escape;
- size_t size;
-
- value_str = _PyUnicode_AsStringAndSize(value, &value_str_len);
+ const char *value_str = _PyUnicode_AsStringAndSize(value, &value_str_len);
if (value_str == NULL) {
PyErr_SetString(PyExc_TypeError, "expected a string");
return NULL;
}
- size = (value_str_len * 2) + 1;
- value_escape_str = PyMem_MALLOC(size);
- value_escape_str_len = BLI_strescape(value_escape_str, value_str, size);
+ const size_t size = (value_str_len * 2) + 1;
+ char *value_escape_str = PyMem_MALLOC(size);
+ const Py_ssize_t value_escape_str_len = BLI_str_escape(value_escape_str, value_str, size);
+ PyObject *value_escape;
if (value_escape_str_len == value_str_len) {
Py_INCREF(value);
value_escape = value;
@@ -292,6 +286,44 @@ static PyObject *bpy_escape_identifier(PyObject *UNUSED(self), PyObject *value)
return value_escape;
}
+PyDoc_STRVAR(bpy_unescape_identifier_doc,
+ ".. function:: unescape_identifier(string)\n"
+ "\n"
+ " Simple string un-escape function used for animation paths.\n"
+ " This performs the reverse of `escape_identifier`.\n"
+ "\n"
+ " :arg string: text\n"
+ " :type string: string\n"
+ " :return: The un-escaped string.\n"
+ " :rtype: string\n");
+static PyObject *bpy_unescape_identifier(PyObject *UNUSED(self), PyObject *value)
+{
+ Py_ssize_t value_str_len;
+ const char *value_str = _PyUnicode_AsStringAndSize(value, &value_str_len);
+
+ if (value_str == NULL) {
+ PyErr_SetString(PyExc_TypeError, "expected a string");
+ return NULL;
+ }
+
+ const size_t size = value_str_len + 1;
+ char *value_unescape_str = PyMem_MALLOC(size);
+ const Py_ssize_t value_unescape_str_len = BLI_str_unescape(value_unescape_str, value_str, size);
+
+ PyObject *value_unescape;
+ if (value_unescape_str_len == value_str_len) {
+ Py_INCREF(value);
+ value_unescape = value;
+ }
+ else {
+ value_unescape = PyUnicode_FromStringAndSize(value_unescape_str, value_unescape_str_len);
+ }
+
+ PyMem_FREE(value_unescape_str);
+
+ return value_unescape;
+}
+
static PyMethodDef meth_bpy_script_paths = {
"script_paths",
(PyCFunction)bpy_script_paths,
@@ -328,6 +360,12 @@ static PyMethodDef meth_bpy_escape_identifier = {
METH_O,
bpy_escape_identifier_doc,
};
+static PyMethodDef meth_bpy_unescape_identifier = {
+ "unescape_identifier",
+ (PyCFunction)bpy_unescape_identifier,
+ METH_O,
+ bpy_unescape_identifier_doc,
+};
static PyObject *bpy_import_test(const char *modname)
{
@@ -429,6 +467,9 @@ void BPy_init_modules(struct bContext *C)
PyModule_AddObject(mod,
meth_bpy_escape_identifier.ml_name,
(PyObject *)PyCFunction_New(&meth_bpy_escape_identifier, NULL));
+ PyModule_AddObject(mod,
+ meth_bpy_unescape_identifier.ml_name,
+ (PyObject *)PyCFunction_New(&meth_bpy_unescape_identifier, NULL));
/* register funcs (bpy_rna.c) */
PyModule_AddObject(mod,
diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c
index bc3d8b2c360..c6f0fbd3a2b 100644
--- a/source/blender/python/intern/bpy_library_load.c
+++ b/source/blender/python/intern/bpy_library_load.c
@@ -44,6 +44,8 @@
#include "BLO_readfile.h"
+#include "MEM_guardedalloc.h"
+
#include "bpy_capi_utils.h"
#include "bpy_library.h"
@@ -225,7 +227,7 @@ static PyObject *_bpy_names(BPy_Library *self, int blocktype)
PyList_SET_ITEM(list, counter, PyUnicode_FromString((char *)l->link));
counter++;
}
- BLI_linklist_free(names, free); /* free linklist *and* each node's data */
+ BLI_linklist_freeN(names); /* free linklist *and* each node's data */
}
return list;
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index d45c8e8b131..9d69d91c8c8 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -3494,7 +3494,6 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
if (!RNA_struct_is_a(ptype, &RNA_PropertyGroup)) {
PyErr_Format(PyExc_TypeError,
"CollectionProperty(...) expected an RNA type derived from %.200s",
- RNA_struct_ui_name(&RNA_ID),
RNA_struct_ui_name(&RNA_PropertyGroup));
return NULL;
}
diff --git a/source/blender/sequencer/intern/sequencer.c b/source/blender/sequencer/intern/sequencer.c
index 0ebf8f3c8e7..c998886626c 100644
--- a/source/blender/sequencer/intern/sequencer.c
+++ b/source/blender/sequencer/intern/sequencer.c
@@ -505,7 +505,7 @@ static size_t sequencer_rna_path_prefix(char str[SEQ_RNAPATH_MAXSTR], const char
{
char name_esc[SEQ_NAME_MAXSTR * 2];
- BLI_strescape(name_esc, name, sizeof(name_esc));
+ BLI_str_escape(name_esc, name, sizeof(name_esc));
return BLI_snprintf_rlen(
str, SEQ_RNAPATH_MAXSTR, "sequence_editor.sequences_all[\"%s\"]", name_esc);
}
diff --git a/source/blender/simulation/intern/hair_volume.cpp b/source/blender/simulation/intern/hair_volume.cpp
index 123b91edaac..08af2344bc4 100644
--- a/source/blender/simulation/intern/hair_volume.cpp
+++ b/source/blender/simulation/intern/hair_volume.cpp
@@ -68,20 +68,20 @@ BLI_INLINE int hair_grid_size(const int res[3])
return res[0] * res[1] * res[2];
}
-typedef struct HairGridVert {
+struct HairGridVert {
int samples;
float velocity[3];
float density;
float velocity_smooth[3];
-} HairGridVert;
+};
-typedef struct HairGrid {
+struct HairGrid {
HairGridVert *verts;
int res[3];
float gmin[3], gmax[3];
float cellsize, inv_cellsize;
-} HairGrid;
+};
#define HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, axis) \
(min_ii(max_ii((int)((vec[axis] - gmin[axis]) * scale), 0), res[axis] - 2))
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 47c5487a458..da2115e12fb 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -47,7 +47,6 @@ struct ImBuf;
struct ImageFormatData;
struct Main;
struct MenuType;
-struct Operator;
struct PointerRNA;
struct PropertyRNA;
struct ScrArea;
@@ -130,6 +129,9 @@ void WM_windows_scene_data_sync(const ListBase *win_lb, struct Scene *scene) ATT
struct Scene *WM_windows_scene_get_from_screen(const struct wmWindowManager *wm,
const struct bScreen *screen)
ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
+struct ViewLayer *WM_windows_view_layer_get_from_screen(const struct wmWindowManager *wm,
+ const struct bScreen *screen)
+ ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
struct WorkSpace *WM_windows_workspace_get_from_screen(const wmWindowManager *wm,
const struct bScreen *screen)
ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
@@ -256,9 +258,6 @@ void WM_event_set_keymap_handler_post_callback(struct wmEventHandler_Keymap *han
wmKeyMap *WM_event_get_keymap_from_handler(wmWindowManager *wm,
struct wmEventHandler_Keymap *handler);
-wmKeyMapItem *WM_event_match_modal_keymap_item(const wmKeyMap *keymap,
- struct wmOperator *op,
- const struct wmEvent *event);
wmKeyMapItem *WM_event_match_keymap_item(struct bContext *C,
wmKeyMap *keymap,
const struct wmEvent *event);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 587abf6fa0a..ac27862d507 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -376,10 +376,9 @@ void wm_event_do_refresh_wm_and_depsgraph(bContext *C)
/* Cached: editor refresh callbacks now, they get context. */
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
const bScreen *screen = WM_window_get_active_screen(win);
- ScrArea *area;
CTX_wm_window_set(C, win);
- for (area = screen->areabase.first; area; area = area->next) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (area->do_refresh) {
CTX_wm_area_set(C, area);
ED_area_do_refresh(C, area);
@@ -516,7 +515,7 @@ void wm_event_do_notifiers(bContext *C)
bScreen *screen = WM_window_get_active_screen(win);
WorkSpace *workspace = WM_window_get_active_workspace(win);
- /* Dilter out notifiers. */
+ /* Filter out notifiers. */
if (note->category == NC_SCREEN && note->reference && note->reference != screen &&
note->reference != workspace && note->reference != WM_window_get_active_layout(win)) {
/* Pass. */
@@ -525,8 +524,6 @@ void wm_event_do_notifiers(bContext *C)
/* Pass. */
}
else {
- ARegion *region;
-
/* XXX context in notifiers? */
CTX_wm_window_set(C, win);
@@ -538,13 +535,13 @@ void wm_event_do_notifiers(bContext *C)
# endif
ED_screen_do_listen(C, note);
- for (region = screen->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) {
ED_region_do_listen(win, NULL, region, note, scene);
}
ED_screen_areas_iter (win, screen, area) {
ED_area_do_listen(win, area, note, scene);
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
ED_region_do_listen(win, area, region, note, scene);
}
}
@@ -1708,7 +1705,8 @@ static void wm_handler_op_context(bContext *C, wmEventHandler_Op *handler, const
}
if (region == NULL) {
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region_iter, &area->regionbase) {
+ region = region_iter;
if (region == handler->context.region) {
break;
}
@@ -1911,13 +1909,6 @@ static wmKeyMapItem *wm_eventmatch_modal_keymap_items(const wmKeyMap *keymap,
return NULL;
}
-wmKeyMapItem *WM_event_match_modal_keymap_item(const wmKeyMap *keymap,
- wmOperator *op,
- const wmEvent *event)
-{
- return wm_eventmatch_modal_keymap_items(keymap, op, event);
-}
-
/**
* This function prepares events for use with #wmOperatorType.modal by:
*
@@ -2254,23 +2245,23 @@ static int wm_handler_fileselect_do(bContext *C,
}
}
else {
- wmWindow *temp_win;
ScrArea *ctx_area = CTX_wm_area(C);
- for (temp_win = wm->windows.first; temp_win; temp_win = temp_win->next) {
- bScreen *screen = WM_window_get_active_screen(temp_win);
+ wmWindow *temp_win = NULL;
+ LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
+ bScreen *screen = WM_window_get_active_screen(win);
ScrArea *file_area = screen->areabase.first;
if (screen->temp && (file_area->spacetype == SPACE_FILE)) {
int win_size[2];
bool is_maximized;
- ED_fileselect_window_params_get(temp_win, win_size, &is_maximized);
+ ED_fileselect_window_params_get(win, win_size, &is_maximized);
ED_fileselect_params_to_userdef(file_area->spacedata.first, win_size, is_maximized);
if (BLI_listbase_is_single(&file_area->spacedata)) {
- BLI_assert(ctx_win != temp_win);
+ BLI_assert(ctx_win != win);
- wm_window_close(C, wm, temp_win);
+ wm_window_close(C, wm, win);
CTX_wm_window_set(C, ctx_win); /* #wm_window_close() NULLs. */
/* Some operators expect a drawable context (for EVT_FILESELECT_EXEC). */
@@ -2279,7 +2270,7 @@ static int wm_handler_fileselect_do(bContext *C,
* opening (UI_BLOCK_MOVEMOUSE_QUIT). */
wm_get_cursor_position(ctx_win, &ctx_win->eventstate->x, &ctx_win->eventstate->y);
wm->winactive = ctx_win; /* Reports use this... */
- if (handler->context.win == temp_win) {
+ if (handler->context.win == win) {
handler->context.win = NULL;
}
}
@@ -2290,6 +2281,7 @@ static int wm_handler_fileselect_do(bContext *C,
ED_area_prevspace(C, file_area);
}
+ temp_win = win;
break;
}
}
@@ -2492,14 +2484,13 @@ static int wm_handlers_do_keymap_with_gizmo_handler(
{
int action = WM_HANDLER_CONTINUE;
bool keymap_poll = false;
- wmKeyMapItem *kmi;
PRINT("%s: checking '%s' ...", __func__, keymap->idname);
if (WM_keymap_poll(C, keymap)) {
keymap_poll = true;
PRINT("pass\n");
- for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
+ LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) {
if (wm_eventmatch(event, kmi)) {
PRINT("%s: item matched '%s'\n", __func__, kmi->idname);
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 3ddac8babd4..5b21b2397e7 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -115,7 +115,6 @@
#include "GHOST_Path-api.h"
#include "UI_interface.h"
-#include "UI_interface_icons.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -178,22 +177,17 @@ bool wm_file_or_image_is_modified(const Main *bmain, const wmWindowManager *wm)
*/
static void wm_window_match_init(bContext *C, ListBase *wmlist)
{
- wmWindowManager *wm;
- wmWindow *win, *active_win;
-
*wmlist = G_MAIN->wm;
BLI_listbase_clear(&G_MAIN->wm);
- active_win = CTX_wm_window(C);
+ wmWindow *active_win = CTX_wm_window(C);
/* first wrap up running stuff */
/* code copied from wm_init_exit.c */
- for (wm = wmlist->first; wm; wm = wm->id.next) {
-
+ LISTBASE_FOREACH (wmWindowManager *, wm, wmlist) {
WM_jobs_kill_all(wm);
- for (win = wm->windows.first; win; win = win->next) {
-
+ LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
CTX_wm_window_set(C, win); /* needed by operator close callbacks */
WM_event_remove_handlers(C, &win->handlers);
WM_event_remove_handlers(C, &win->modalhandlers);
@@ -519,11 +513,9 @@ void WM_file_autoexec_init(const char *filepath)
void wm_file_read_report(bContext *C, Main *bmain)
{
ReportList *reports = NULL;
- Scene *sce;
-
- for (sce = bmain->scenes.first; sce; sce = sce->id.next) {
- if (sce->r.engine[0] &&
- BLI_findstring(&R_engines, sce->r.engine, offsetof(RenderEngineType, idname)) == NULL) {
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
+ if (scene->r.engine[0] &&
+ BLI_findstring(&R_engines, scene->r.engine, offsetof(RenderEngineType, idname)) == NULL) {
if (reports == NULL) {
reports = CTX_wm_reports(C);
}
@@ -532,8 +524,8 @@ void wm_file_read_report(bContext *C, Main *bmain)
RPT_ERROR,
"Engine '%s' not available for scene '%s' (an add-on may need to be installed "
"or enabled)",
- sce->r.engine,
- sce->id.name + 2);
+ scene->r.engine,
+ scene->id.name + 2);
}
}
@@ -1136,7 +1128,7 @@ void wm_homefile_read(bContext *C,
if (use_userdef) {
/* Clear keymaps because the current default keymap may have been initialized
* from user preferences, which have been reset. */
- for (wmWindowManager *wm = bmain->wm.first; wm; wm = wm->id.next) {
+ LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) {
if (wm->defaultconf) {
wm->defaultconf->flag &= ~KEYCONF_INIT_DEFAULT;
}
@@ -1236,8 +1228,7 @@ static void wm_history_file_write(void)
fp = BLI_fopen(name, "w");
if (fp) {
- struct RecentFile *recent;
- for (recent = G.recent_files.first; recent; recent = recent->next) {
+ LISTBASE_FOREACH (RecentFile *, recent, &G.recent_files) {
fprintf(fp, "%s\n", recent->filepath);
}
fclose(fp);
@@ -1430,7 +1421,6 @@ static bool wm_file_write(bContext *C,
ReportList *reports)
{
Main *bmain = CTX_data_main(C);
- Library *li;
int len;
int ok = false;
BlendThumbnail *thumb, *main_thumb;
@@ -1459,7 +1449,7 @@ static bool wm_file_write(bContext *C,
* its handy for scripts to save to a predefined name without blender editing it */
/* send the OnSave event */
- for (li = bmain->libraries.first; li; li = li->id.next) {
+ LISTBASE_FOREACH (Library *, li, &bmain->libraries) {
if (BLI_path_cmp(li->filepath_abs, filepath) == 0) {
BKE_reportf(reports, RPT_ERROR, "Cannot overwrite used library '%.240s'", filepath);
return ok;
@@ -3206,40 +3196,13 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C,
{
wmGenericCallback *post_action = (wmGenericCallback *)arg1;
Main *bmain = CTX_data_main(C);
- const uiStyle *style = UI_style_get_dpi();
- const short icon_size = 64 * U.dpi_fac;
- const int text_points_max = MAX2(style->widget.points, style->widgetlabel.points);
- const int dialog_width = icon_size + (text_points_max * 34 * U.dpi_fac);
-
- /* By default, the space between icon and text/buttons will be equal to the 'columnspace',
- this extra padding will add some space by increasing the left column width,
- making the icon placement more symmetrical, between the block edge and the text. */
- const float icon_padding = 6.0f * U.dpi_fac;
- /* Calculate icon column factor. */
- const float split_factor = ((float)icon_size + icon_padding) /
- (float)(dialog_width - style->columnspace);
uiBlock *block = UI_block_begin(C, region, close_file_dialog_name, UI_EMBOSS);
-
UI_block_flag_enable(
block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_LOOP | UI_BLOCK_NO_WIN_CLIP | UI_BLOCK_NUMSELECT);
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
- UI_block_emboss_set(block, UI_EMBOSS);
-
- uiLayout *block_layout = UI_block_layout(
- block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, dialog_width, 0, 0, style);
-
- /* Split layout to put alert icon on left side. */
- uiLayout *split_block = uiLayoutSplit(block_layout, split_factor, false);
-
- /* Alert Icon. */
- uiLayout *layout = uiLayoutRow(split_block, false);
- /* Using 'align_left' with 'row' avoids stretching the icon along the width of column. */
- uiLayoutSetAlignment(layout, UI_LAYOUT_ALIGN_LEFT);
- uiDefButAlert(block, ALERT_ICON_QUESTION, 0, 0, icon_size, icon_size);
- /* The rest of the content on the right. */
- layout = uiLayoutColumn(split_block, false);
+ uiLayout *layout = uiItemsAlertBox(block, 34, ALERT_ICON_QUESTION);
/* Title. */
uiItemL_ex(layout, TIP_("Save changes before closing?"), ICON_NONE, true, false);
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 926e61f4a0e..7984c2fd879 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -412,9 +412,7 @@ void WM_init_splash(bContext *C)
/* free strings of open recent files */
static void free_openrecent(void)
{
- struct RecentFile *recent;
-
- for (recent = G.recent_files.first; recent; recent = recent->next) {
+ LISTBASE_FOREACH (RecentFile *, recent, &G.recent_files) {
MEM_freeN(recent->filepath);
}
@@ -656,6 +654,7 @@ void WM_exit_ex(bContext *C, const bool do_python)
* pieces of Blender using sound may exit cleanly, see also T50676. */
BKE_sound_exit();
+ BKE_appdir_exit();
CLG_exit();
BKE_blender_atexit();
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index a1140c01d44..443a6fd1979 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -222,10 +222,8 @@ wmJob *WM_jobs_get(
/* returns true if job runs, for UI (progress) indicators */
bool WM_jobs_test(wmWindowManager *wm, void *owner, int job_type)
{
- wmJob *wm_job;
-
/* job can be running or about to run (suspended) */
- for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) {
+ LISTBASE_FOREACH (wmJob *, wm_job, &wm->jobs) {
if (wm_job->owner == owner) {
if (ELEM(job_type, WM_JOB_TYPE_ANY, wm_job->job_type)) {
if (wm_job->running || wm_job->suspended) {
@@ -266,17 +264,14 @@ static void wm_jobs_update_progress_bars(wmWindowManager *wm)
/* if there are running jobs, set the global progress indicator */
if (jobs_progress > 0) {
- wmWindow *win;
float progress = total_progress / (float)jobs_progress;
- for (win = wm->windows.first; win; win = win->next) {
+ LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
WM_progress_set(win, progress);
}
}
else {
- wmWindow *win;
-
- for (win = wm->windows.first; win; win = win->next) {
+ LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
WM_progress_clear(win);
}
}
@@ -400,7 +395,6 @@ static void *do_job_thread(void *job_v)
/* don't allow same startjob to be executed twice */
static void wm_jobs_test_suspend_stop(wmWindowManager *wm, wmJob *test)
{
- wmJob *wm_job;
bool suspend = false;
/* job added with suspend flag, we wait 1 timer step before activating it */
@@ -410,7 +404,7 @@ static void wm_jobs_test_suspend_stop(wmWindowManager *wm, wmJob *test)
}
else {
/* check other jobs */
- for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) {
+ LISTBASE_FOREACH (wmJob *, wm_job, &wm->jobs) {
/* obvious case, no test needed */
if (wm_job == test || !wm_job->running) {
continue;
@@ -568,11 +562,7 @@ void WM_jobs_kill_all(wmWindowManager *wm)
/* wait until every job ended, except for one owner (used in undo to keep screen job alive) */
void WM_jobs_kill_all_except(wmWindowManager *wm, void *owner)
{
- wmJob *wm_job, *next_job;
-
- for (wm_job = wm->jobs.first; wm_job; wm_job = next_job) {
- next_job = wm_job->next;
-
+ LISTBASE_FOREACH_MUTABLE (wmJob *, wm_job, &wm->jobs) {
if (wm_job->owner != owner) {
wm_jobs_kill_job(wm, wm_job);
}
@@ -581,11 +571,7 @@ void WM_jobs_kill_all_except(wmWindowManager *wm, void *owner)
void WM_jobs_kill_type(struct wmWindowManager *wm, void *owner, int job_type)
{
- wmJob *wm_job, *next_job;
-
- for (wm_job = wm->jobs.first; wm_job; wm_job = next_job) {
- next_job = wm_job->next;
-
+ LISTBASE_FOREACH_MUTABLE (wmJob *, wm_job, &wm->jobs) {
if (!owner || wm_job->owner == owner) {
if (ELEM(job_type, WM_JOB_TYPE_ANY, wm_job->job_type)) {
wm_jobs_kill_job(wm, wm_job);
@@ -597,9 +583,7 @@ void WM_jobs_kill_type(struct wmWindowManager *wm, void *owner, int job_type)
/* signal job(s) from this owner or callback to stop, timer is required to get handled */
void WM_jobs_stop(wmWindowManager *wm, void *owner, void *startjob)
{
- wmJob *wm_job;
-
- for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) {
+ LISTBASE_FOREACH (wmJob *, wm_job, &wm->jobs) {
if (wm_job->owner == owner || wm_job->startjob == startjob) {
if (wm_job->running) {
wm_job->stop = true;
@@ -613,17 +597,9 @@ void WM_jobs_kill(wmWindowManager *wm,
void *owner,
void (*startjob)(void *, short int *, short int *, float *))
{
- wmJob *wm_job;
-
- wm_job = wm->jobs.first;
- while (wm_job) {
+ LISTBASE_FOREACH_MUTABLE (wmJob *, wm_job, &wm->jobs) {
if (wm_job->owner == owner || wm_job->startjob == startjob) {
- wmJob *wm_job_kill = wm_job;
- wm_job = wm_job->next;
- wm_jobs_kill_job(wm, wm_job_kill);
- }
- else {
- wm_job = wm_job->next;
+ wm_jobs_kill_job(wm, wm_job);
}
}
}
@@ -631,9 +607,7 @@ void WM_jobs_kill(wmWindowManager *wm,
/* kill job entirely, also removes timer itself */
void wm_jobs_timer_ended(wmWindowManager *wm, wmTimer *wt)
{
- wmJob *wm_job;
-
- for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) {
+ LISTBASE_FOREACH (wmJob *, wm_job, &wm->jobs) {
if (wm_job->wt == wt) {
wm_jobs_kill_job(wm, wm_job);
return;
@@ -644,13 +618,8 @@ void wm_jobs_timer_ended(wmWindowManager *wm, wmTimer *wt)
/* hardcoded to event TIMERJOBS */
void wm_jobs_timer(wmWindowManager *wm, wmTimer *wt)
{
- wmJob *wm_job, *wm_jobnext;
-
- for (wm_job = wm->jobs.first; wm_job; wm_job = wm_jobnext) {
- wm_jobnext = wm_job->next;
-
+ LISTBASE_FOREACH_MUTABLE (wmJob *, wm_job, &wm->jobs) {
if (wm_job->wt == wt) {
-
/* running threads */
if (wm_job->threads.first) {
@@ -735,9 +704,7 @@ void wm_jobs_timer(wmWindowManager *wm, wmTimer *wt)
bool WM_jobs_has_running(wmWindowManager *wm)
{
- wmJob *wm_job;
-
- for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) {
+ LISTBASE_FOREACH (wmJob *, wm_job, &wm->jobs) {
if (wm_job->running) {
return true;
}
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 1daab07812d..1f730be8c82 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -392,8 +392,6 @@ static wmKeyMap *wm_keymap_new(const char *idname, int spaceid, int regionid)
static wmKeyMap *wm_keymap_copy(wmKeyMap *keymap)
{
wmKeyMap *keymapn = MEM_dupallocN(keymap);
- wmKeyMapItem *kmi, *kmin;
- wmKeyMapDiffItem *kmdi, *kmdin;
keymapn->modal_items = keymap->modal_items;
keymapn->poll = keymap->poll;
@@ -401,14 +399,14 @@ static wmKeyMap *wm_keymap_copy(wmKeyMap *keymap)
BLI_listbase_clear(&keymapn->items);
keymapn->flag &= ~(KEYMAP_UPDATE | KEYMAP_EXPANDED);
- for (kmdi = keymap->diff_items.first; kmdi; kmdi = kmdi->next) {
- kmdin = wm_keymap_diff_item_copy(kmdi);
- BLI_addtail(&keymapn->items, kmdin);
+ LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &keymap->diff_items) {
+ wmKeyMapDiffItem *kmdi_new = wm_keymap_diff_item_copy(kmdi);
+ BLI_addtail(&keymapn->items, kmdi_new);
}
- for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
- kmin = wm_keymap_item_copy(kmi);
- BLI_addtail(&keymapn->items, kmin);
+ LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) {
+ wmKeyMapItem *kmi_new = wm_keymap_item_copy(kmi);
+ BLI_addtail(&keymapn->items, kmi_new);
}
return keymapn;
@@ -416,14 +414,11 @@ static wmKeyMap *wm_keymap_copy(wmKeyMap *keymap)
void WM_keymap_clear(wmKeyMap *keymap)
{
- wmKeyMapItem *kmi;
- wmKeyMapDiffItem *kmdi;
-
- for (kmdi = keymap->diff_items.first; kmdi; kmdi = kmdi->next) {
+ LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &keymap->diff_items) {
wm_keymap_diff_item_free(kmdi);
}
- for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
+ LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) {
wm_keymap_item_free(kmi);
}
@@ -558,20 +553,16 @@ bool WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi)
static void wm_keymap_addon_add(wmKeyMap *keymap, wmKeyMap *addonmap)
{
- wmKeyMapItem *kmi, *kmin;
-
- for (kmi = addonmap->items.first; kmi; kmi = kmi->next) {
- kmin = wm_keymap_item_copy(kmi);
- keymap_item_set_id(keymap, kmin);
- BLI_addhead(&keymap->items, kmin);
+ LISTBASE_FOREACH (wmKeyMapItem *, kmi, &addonmap->items) {
+ wmKeyMapItem *kmi_new = wm_keymap_item_copy(kmi);
+ keymap_item_set_id(keymap, kmi_new);
+ BLI_addhead(&keymap->items, kmi_new);
}
}
static wmKeyMapItem *wm_keymap_find_item_equals(wmKeyMap *km, wmKeyMapItem *needle)
{
- wmKeyMapItem *kmi;
-
- for (kmi = km->items.first; kmi; kmi = kmi->next) {
+ LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
if (wm_keymap_item_equals(kmi, needle)) {
return kmi;
}
@@ -582,9 +573,7 @@ static wmKeyMapItem *wm_keymap_find_item_equals(wmKeyMap *km, wmKeyMapItem *need
static wmKeyMapItem *wm_keymap_find_item_equals_result(wmKeyMap *km, wmKeyMapItem *needle)
{
- wmKeyMapItem *kmi;
-
- for (kmi = km->items.first; kmi; kmi = kmi->next) {
+ LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
if (wm_keymap_item_equals_result(kmi, needle)) {
return kmi;
}
@@ -596,21 +585,18 @@ static wmKeyMapItem *wm_keymap_find_item_equals_result(wmKeyMap *km, wmKeyMapIte
static void wm_keymap_diff(
wmKeyMap *diff_km, wmKeyMap *from_km, wmKeyMap *to_km, wmKeyMap *orig_km, wmKeyMap *addon_km)
{
- wmKeyMapItem *kmi, *to_kmi, *orig_kmi;
- wmKeyMapDiffItem *kmdi;
-
- for (kmi = from_km->items.first; kmi; kmi = kmi->next) {
- to_kmi = WM_keymap_item_find_id(to_km, kmi->id);
+ LISTBASE_FOREACH (wmKeyMapItem *, kmi, &from_km->items) {
+ wmKeyMapItem *to_kmi = WM_keymap_item_find_id(to_km, kmi->id);
if (!to_kmi) {
/* remove item */
- kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
+ wmKeyMapDiffItem *kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
kmdi->remove_item = wm_keymap_item_copy(kmi);
BLI_addtail(&diff_km->diff_items, kmdi);
}
else if (to_kmi && !wm_keymap_item_equals(kmi, to_kmi)) {
/* replace item */
- kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
+ wmKeyMapDiffItem *kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
kmdi->remove_item = wm_keymap_item_copy(kmi);
kmdi->add_item = wm_keymap_item_copy(to_kmi);
BLI_addtail(&diff_km->diff_items, kmdi);
@@ -618,7 +604,7 @@ static void wm_keymap_diff(
/* sync expanded flag back to original so we don't lose it on repatch */
if (to_kmi) {
- orig_kmi = WM_keymap_item_find_id(orig_km, kmi->id);
+ wmKeyMapItem *orig_kmi = WM_keymap_item_find_id(orig_km, kmi->id);
if (!orig_kmi && addon_km) {
orig_kmi = wm_keymap_find_item_equals(addon_km, kmi);
@@ -631,10 +617,10 @@ static void wm_keymap_diff(
}
}
- for (kmi = to_km->items.first; kmi; kmi = kmi->next) {
+ LISTBASE_FOREACH (wmKeyMapItem *, kmi, &to_km->items) {
if (kmi->id < 0) {
/* add item */
- kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
+ wmKeyMapDiffItem *kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
kmdi->add_item = wm_keymap_item_copy(kmi);
BLI_addtail(&diff_km->diff_items, kmdi);
}
@@ -643,12 +629,9 @@ static void wm_keymap_diff(
static void wm_keymap_patch(wmKeyMap *km, wmKeyMap *diff_km)
{
- wmKeyMapDiffItem *kmdi;
- wmKeyMapItem *kmi_remove, *kmi_add;
-
- for (kmdi = diff_km->diff_items.first; kmdi; kmdi = kmdi->next) {
+ LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &diff_km->diff_items) {
/* find item to remove */
- kmi_remove = NULL;
+ wmKeyMapItem *kmi_remove = NULL;
if (kmdi->remove_item) {
kmi_remove = wm_keymap_find_item_equals(km, kmdi->remove_item);
if (!kmi_remove) {
@@ -660,7 +643,7 @@ static void wm_keymap_patch(wmKeyMap *km, wmKeyMap *diff_km)
if (kmdi->add_item) {
/* Do not re-add an already existing keymap item! See T42088. */
/* We seek only for exact copy here! See T42137. */
- kmi_add = wm_keymap_find_item_equals(km, kmdi->add_item);
+ wmKeyMapItem *kmi_add = wm_keymap_find_item_equals(km, kmdi->add_item);
/** If kmi_add is same as kmi_remove (can happen in some cases,
* typically when we got kmi_remove from #wm_keymap_find_item_equals_result()),
@@ -712,11 +695,11 @@ static wmKeyMap *wm_keymap_patch_update(ListBase *lb,
wmKeyMap *addonmap,
wmKeyMap *usermap)
{
- wmKeyMap *km;
int expanded = 0;
/* remove previous keymap in list, we will replace it */
- km = WM_keymap_list_find(lb, defaultmap->idname, defaultmap->spaceid, defaultmap->regionid);
+ wmKeyMap *km = WM_keymap_list_find(
+ lb, defaultmap->idname, defaultmap->spaceid, defaultmap->regionid);
if (km) {
expanded = (km->flag & (KEYMAP_EXPANDED | KEYMAP_CHILDREN_EXPANDED));
WM_keymap_clear(km);
@@ -727,13 +710,12 @@ static wmKeyMap *wm_keymap_patch_update(ListBase *lb,
if (usermap && !(usermap->flag & KEYMAP_DIFF)) {
/* for compatibility with old user preferences with non-diff
* keymaps we override the original entirely */
- wmKeyMapItem *kmi, *orig_kmi;
km = wm_keymap_copy(usermap);
/* try to find corresponding id's for items */
- for (kmi = km->items.first; kmi; kmi = kmi->next) {
- orig_kmi = wm_keymap_find_item_equals(defaultmap, kmi);
+ LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
+ wmKeyMapItem *orig_kmi = wm_keymap_find_item_equals(defaultmap, kmi);
if (!orig_kmi) {
orig_kmi = wm_keymap_find_item_equals_result(defaultmap, kmi);
}
@@ -779,10 +761,8 @@ static void wm_keymap_diff_update(ListBase *lb,
wmKeyMap *addonmap,
wmKeyMap *km)
{
- wmKeyMap *diffmap, *prevmap, *origmap;
-
/* create temporary default + addon keymap for diff */
- origmap = defaultmap;
+ wmKeyMap *origmap = defaultmap;
if (addonmap) {
defaultmap = wm_keymap_copy(defaultmap);
@@ -790,14 +770,14 @@ static void wm_keymap_diff_update(ListBase *lb,
}
/* remove previous diff keymap in list, we will replace it */
- prevmap = WM_keymap_list_find(lb, km->idname, km->spaceid, km->regionid);
+ wmKeyMap *prevmap = WM_keymap_list_find(lb, km->idname, km->spaceid, km->regionid);
if (prevmap) {
WM_keymap_clear(prevmap);
BLI_freelinkN(lb, prevmap);
}
/* create diff keymap */
- diffmap = wm_keymap_new(km->idname, km->spaceid, km->regionid);
+ wmKeyMap *diffmap = wm_keymap_new(km->idname, km->spaceid, km->regionid);
diffmap->flag |= KEYMAP_DIFF;
if (defaultmap->flag & KEYMAP_MODAL) {
diffmap->flag |= KEYMAP_MODAL;
@@ -833,9 +813,7 @@ static void wm_keymap_diff_update(ListBase *lb,
wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int regionid)
{
- wmKeyMap *km;
-
- for (km = lb->first; km; km = km->next) {
+ LISTBASE_FOREACH (wmKeyMap *, km, lb) {
if (km->spaceid == spaceid && km->regionid == regionid) {
if (STREQLEN(idname, km->idname, KMAP_MAX_NAME)) {
return km;
@@ -851,9 +829,7 @@ wmKeyMap *WM_keymap_list_find_spaceid_or_empty(ListBase *lb,
int spaceid,
int regionid)
{
- wmKeyMap *km;
-
- for (km = lb->first; km; km = km->next) {
+ LISTBASE_FOREACH (wmKeyMap *, km, lb) {
if (ELEM(km->spaceid, spaceid, SPACE_EMPTY) && km->regionid == regionid) {
if (STREQLEN(idname, km->idname, KMAP_MAX_NAME)) {
return km;
@@ -928,17 +904,16 @@ wmKeyMap *WM_modalkeymap_ensure(wmKeyConfig *keyconf,
wmKeyMap *WM_modalkeymap_find(wmKeyConfig *keyconf, const char *idname)
{
- wmKeyMap *km;
-
- for (km = keyconf->keymaps.first; km; km = km->next) {
+ LISTBASE_FOREACH (wmKeyMap *, km, &keyconf->keymaps) {
if (km->flag & KEYMAP_MODAL) {
if (STREQLEN(idname, km->idname, KMAP_MAX_NAME)) {
+ return km;
break;
}
}
}
- return km;
+ return NULL;
}
wmKeyMapItem *WM_modalkeymap_add_item(
@@ -1015,17 +990,13 @@ static void wm_user_modal_keymap_set_items(wmWindowManager *wm, wmKeyMap *km)
{
/* here we convert propvalue string values delayed, due to python keymaps
* being created before the actual modal keymaps, so no modal_items */
- wmKeyMap *defaultkm;
- wmKeyMapItem *kmi;
- int propvalue;
if (km && (km->flag & KEYMAP_MODAL) && !km->modal_items) {
if (wm->defaultconf == NULL) {
return;
}
- defaultkm = WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, 0, 0);
-
+ wmKeyMap *defaultkm = WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, 0, 0);
if (!defaultkm) {
return;
}
@@ -1035,8 +1006,9 @@ static void wm_user_modal_keymap_set_items(wmWindowManager *wm, wmKeyMap *km)
km->poll_modal_item = defaultkm->poll_modal_item;
if (km->modal_items) {
- for (kmi = km->items.first; kmi; kmi = kmi->next) {
+ LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
if (kmi->propvalue_str[0]) {
+ int propvalue;
if (RNA_enum_value_from_id(km->modal_items, kmi->propvalue_str, &propvalue)) {
kmi->propvalue = propvalue;
}
@@ -1510,8 +1482,6 @@ static wmKeyMapItem *wm_keymap_item_find(const bContext *C,
const struct wmKeyMapItemFind_Params *params,
wmKeyMap **r_keymap)
{
- wmKeyMapItem *found;
-
/* XXX Hack! Macro operators in menu entry have their whole props defined,
* which is not the case for relevant keymap entries.
* Could be good to check and harmonize this,
@@ -1521,7 +1491,8 @@ static wmKeyMapItem *wm_keymap_item_find(const bContext *C,
is_strict = is_strict && ((ot->flag & OPTYPE_MACRO) == 0);
}
- found = wm_keymap_item_find_props(C, opname, opcontext, properties, is_strict, params, r_keymap);
+ wmKeyMapItem *found = wm_keymap_item_find_props(
+ C, opname, opcontext, properties, is_strict, params, r_keymap);
/* This block is *only* useful in one case: when op uses an enum menu in its prop member
* (then, we want to rerun a comparison with that 'prop' unset). Note this remains brittle,
@@ -1556,8 +1527,6 @@ static wmKeyMapItem *wm_keymap_item_find(const bContext *C,
/* Debug only, helps spotting mismatches between menu entries and shortcuts! */
if (G.debug & G_DEBUG_WM) {
if (!found && is_strict && properties) {
- wmKeyMap *km;
- wmKeyMapItem *kmi;
if (ot) {
/* make a copy of the properties and set unset ones to their default values. */
PointerRNA opptr;
@@ -1566,7 +1535,8 @@ static wmKeyMapItem *wm_keymap_item_find(const bContext *C,
RNA_pointer_create(NULL, ot->srna, properties_default, &opptr);
WM_operator_properties_default(&opptr, true);
- kmi = wm_keymap_item_find_props(
+ wmKeyMap *km;
+ wmKeyMapItem *kmi = wm_keymap_item_find_props(
C, opname, opcontext, properties_default, is_strict, params, &km);
if (kmi) {
char kmi_str[128];
@@ -1687,15 +1657,13 @@ wmKeyMapItem *WM_key_event_operator_from_keymap(wmKeyMap *keymap,
bool WM_keymap_item_compare(wmKeyMapItem *k1, wmKeyMapItem *k2)
{
- int k1type, k2type;
-
if (k1->flag & KMI_INACTIVE || k2->flag & KMI_INACTIVE) {
return 0;
}
/* take event mapping into account */
- k1type = WM_userdef_event_map(k1->type);
- k2type = WM_userdef_event_map(k2->type);
+ int k1type = WM_userdef_event_map(k1->type);
+ int k2type = WM_userdef_event_map(k2->type);
if (k1type != KM_ANY && k2type != KM_ANY && k1type != k2type) {
return 0;
@@ -1777,13 +1745,10 @@ void WM_keyconfig_update_operatortype(void)
static bool wm_keymap_test_and_clear_update(wmKeyMap *km)
{
- wmKeyMapItem *kmi;
- int update;
-
- update = (km->flag & KEYMAP_UPDATE);
+ int update = (km->flag & KEYMAP_UPDATE);
km->flag &= ~KEYMAP_UPDATE;
- for (kmi = km->items.first; kmi; kmi = kmi->next) {
+ LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
update = update || (kmi->flag & KMI_UPDATE);
kmi->flag &= ~KMI_UPDATE;
}
@@ -1794,9 +1759,7 @@ static bool wm_keymap_test_and_clear_update(wmKeyMap *km)
static wmKeyMap *wm_keymap_preset(wmWindowManager *wm, wmKeyMap *km)
{
wmKeyConfig *keyconf = WM_keyconfig_active(wm);
- wmKeyMap *keymap;
-
- keymap = WM_keymap_list_find(&keyconf->keymaps, km->idname, km->spaceid, km->regionid);
+ wmKeyMap *keymap = WM_keymap_list_find(&keyconf->keymaps, km->idname, km->spaceid, km->regionid);
if (!keymap && wm->defaultconf) {
keymap = WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, km->spaceid, km->regionid);
}
@@ -1806,9 +1769,6 @@ static wmKeyMap *wm_keymap_preset(wmWindowManager *wm, wmKeyMap *km)
void WM_keyconfig_update(wmWindowManager *wm)
{
- wmKeyMap *km, *defaultmap, *addonmap, *usermap, *kmn;
- wmKeyMapItem *kmi;
- wmKeyMapDiffItem *kmdi;
bool compat_update = false;
if (G.background) {
@@ -1822,8 +1782,6 @@ void WM_keyconfig_update(wmWindowManager *wm)
if (wm_keymap_update_flag & WM_KEYMAP_UPDATE_OPERATORTYPE) {
/* an operatortype has been removed, this wont happen often
* but when it does we have to check _every_ keymap item */
- wmKeyConfig *kc;
-
ListBase *keymaps_lb[] = {
&U.user_keymaps,
&wm->userconf->keymaps,
@@ -1838,7 +1796,7 @@ void WM_keyconfig_update(wmWindowManager *wm)
wm_keymap_item_properties_update_ot_from_list(keymaps_lb[i]);
}
- for (kc = wm->keyconfigs.first; kc; kc = kc->next) {
+ LISTBASE_FOREACH (wmKeyConfig *, kc, &wm->keyconfigs) {
wm_keymap_item_properties_update_ot_from_list(&kc->keymaps);
}
@@ -1850,9 +1808,9 @@ void WM_keyconfig_update(wmWindowManager *wm)
}
/* update operator properties for non-modal user keymaps */
- for (km = U.user_keymaps.first; km; km = km->next) {
+ LISTBASE_FOREACH (wmKeyMap *, km, &U.user_keymaps) {
if ((km->flag & KEYMAP_MODAL) == 0) {
- for (kmdi = km->diff_items.first; kmdi; kmdi = kmdi->next) {
+ LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &km->diff_items) {
if (kmdi->add_item) {
wm_keymap_item_properties_set(kmdi->add_item);
}
@@ -1861,19 +1819,19 @@ void WM_keyconfig_update(wmWindowManager *wm)
}
}
- for (kmi = km->items.first; kmi; kmi = kmi->next) {
+ LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
wm_keymap_item_properties_set(kmi);
}
}
}
/* update U.user_keymaps with user key configuration changes */
- for (km = wm->userconf->keymaps.first; km; km = km->next) {
+ LISTBASE_FOREACH (wmKeyMap *, km, &wm->userconf->keymaps) {
/* only diff if the user keymap was modified */
if (wm_keymap_test_and_clear_update(km)) {
/* find keymaps */
- defaultmap = wm_keymap_preset(wm, km);
- addonmap = WM_keymap_list_find(
+ wmKeyMap *defaultmap = wm_keymap_preset(wm, km);
+ wmKeyMap *addonmap = WM_keymap_list_find(
&wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid);
/* diff */
@@ -1884,18 +1842,20 @@ void WM_keyconfig_update(wmWindowManager *wm)
}
/* create user key configuration from preset + addon + user preferences */
- for (km = wm->defaultconf->keymaps.first; km; km = km->next) {
+ LISTBASE_FOREACH (wmKeyMap *, km, &wm->defaultconf->keymaps) {
/* find keymaps */
- defaultmap = wm_keymap_preset(wm, km);
- addonmap = WM_keymap_list_find(&wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid);
- usermap = WM_keymap_list_find(&U.user_keymaps, km->idname, km->spaceid, km->regionid);
+ wmKeyMap *defaultmap = wm_keymap_preset(wm, km);
+ wmKeyMap *addonmap = WM_keymap_list_find(
+ &wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid);
+ wmKeyMap *usermap = WM_keymap_list_find(
+ &U.user_keymaps, km->idname, km->spaceid, km->regionid);
/* For now only the default map defines modal key-maps,
* if we support modal keymaps for 'addonmap', these will need to be enabled too. */
wm_user_modal_keymap_set_items(wm, defaultmap);
/* add */
- kmn = wm_keymap_patch_update(&wm->userconf->keymaps, defaultmap, addonmap, usermap);
+ wmKeyMap *kmn = wm_keymap_patch_update(&wm->userconf->keymaps, defaultmap, addonmap, usermap);
if (kmn) {
kmn->modal_items = km->modal_items;
@@ -1928,14 +1888,12 @@ void WM_keyconfig_update(wmWindowManager *wm)
wmKeyMap *WM_keymap_active(const wmWindowManager *wm, wmKeyMap *keymap)
{
- wmKeyMap *km;
-
if (!keymap) {
return NULL;
}
/* first user defined keymaps */
- km = WM_keymap_list_find(
+ wmKeyMap *km = WM_keymap_list_find(
&wm->userconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
if (km) {
@@ -1955,16 +1913,13 @@ wmKeyMap *WM_keymap_active(const wmWindowManager *wm, wmKeyMap *keymap)
void WM_keymap_item_restore_to_default(wmWindowManager *wm, wmKeyMap *keymap, wmKeyMapItem *kmi)
{
- wmKeyMap *defaultmap, *addonmap;
- wmKeyMapItem *orig;
-
if (!keymap) {
return;
}
/* construct default keymap from preset + addons */
- defaultmap = wm_keymap_preset(wm, keymap);
- addonmap = WM_keymap_list_find(
+ wmKeyMap *defaultmap = wm_keymap_preset(wm, keymap);
+ wmKeyMap *addonmap = WM_keymap_list_find(
&wm->addonconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
if (addonmap) {
@@ -1973,7 +1928,7 @@ void WM_keymap_item_restore_to_default(wmWindowManager *wm, wmKeyMap *keymap, wm
}
/* find original item */
- orig = WM_keymap_item_find_id(defaultmap, kmi->id);
+ wmKeyMapItem *orig = WM_keymap_item_find_id(defaultmap, kmi->id);
if (orig) {
/* restore to original */
@@ -2030,9 +1985,7 @@ void WM_keymap_restore_to_default(wmKeyMap *keymap, wmWindowManager *wm)
wmKeyMapItem *WM_keymap_item_find_id(wmKeyMap *keymap, int id)
{
- wmKeyMapItem *kmi;
-
- for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
+ LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) {
if (kmi->id == id) {
return kmi;
}
diff --git a/source/blender/windowmanager/intern/wm_operator_type.c b/source/blender/windowmanager/intern/wm_operator_type.c
index 7621862708e..4c4fd2b1a8e 100644
--- a/source/blender/windowmanager/intern/wm_operator_type.c
+++ b/source/blender/windowmanager/intern/wm_operator_type.c
@@ -572,9 +572,7 @@ wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char
static void wm_operatortype_free_macro(wmOperatorType *ot)
{
- wmOperatorTypeMacro *otmacro;
-
- for (otmacro = ot->macro.first; otmacro; otmacro = otmacro->next) {
+ LISTBASE_FOREACH (wmOperatorTypeMacro *, otmacro, &ot->macro) {
if (otmacro->ptr) {
WM_operator_properties_free(otmacro->ptr);
MEM_freeN(otmacro->ptr);
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 9eedd5b2faa..a5d23365df3 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -84,6 +84,7 @@
#include "IMB_imbuf_types.h"
+#include "ED_fileselect.h"
#include "ED_numinput.h"
#include "ED_screen.h"
#include "ED_undo.h"
@@ -496,7 +497,7 @@ static const char *wm_context_member_from_ptr(bContext *C, const PointerRNA *ptr
}
case SPACE_FILE: {
const SpaceFile *sfile = (SpaceFile *)space_data;
- const FileSelectParams *params = sfile->params;
+ const FileSelectParams *params = ED_fileselect_get_active_params(sfile);
TEST_PTR_DATA_TYPE("space_data", RNA_FileSelectParams, ptr, params);
break;
}
diff --git a/source/blender/windowmanager/intern/wm_splash_screen.c b/source/blender/windowmanager/intern/wm_splash_screen.c
index d732393b631..a3619a69152 100644
--- a/source/blender/windowmanager/intern/wm_splash_screen.c
+++ b/source/blender/windowmanager/intern/wm_splash_screen.c
@@ -256,71 +256,62 @@ void WM_OT_splash(wmOperatorType *ot)
static uiBlock *wm_block_create_about(bContext *C, ARegion *region, void *UNUSED(arg))
{
const uiStyle *style = UI_style_get_dpi();
- const short logo_size = 128 * U.dpi_fac;
const int text_points_max = MAX2(style->widget.points, style->widgetlabel.points);
- const int dialog_width = logo_size + (text_points_max * 32 * U.dpi_fac);
-
- /* Calculate icon column factor. */
- const float split_factor = (float)logo_size / (float)(dialog_width - style->columnspace);
+ const int dialog_width = text_points_max * 42 * U.dpi_fac;
uiBlock *block = UI_block_begin(C, region, "about", UI_EMBOSS);
- UI_block_flag_enable(
- block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_LOOP | UI_BLOCK_NO_WIN_CLIP | UI_BLOCK_NUMSELECT);
+ UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_LOOP | UI_BLOCK_NO_WIN_CLIP);
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
- UI_block_emboss_set(block, UI_EMBOSS);
- uiLayout *block_layout = UI_block_layout(
+ uiLayout *layout = UI_block_layout(
block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, dialog_width, 0, 0, style);
- /* Split layout to put Blender logo on left side. */
- uiLayout *split_block = uiLayoutSplit(block_layout, split_factor, false);
-
- /* Blender Logo. */
- uiLayout *layout = uiLayoutColumn(split_block, false);
- uiDefButAlert(block, ALERT_ICON_BLENDER, 0, 0, 0, logo_size);
-
- /* The rest of the content on the right. */
- layout = uiLayoutColumn(split_block, false);
-
- uiLayoutSetScaleY(layout, 0.7f);
-
- uiItemS_ex(layout, 1.0f);
-
- /* Title. */
- uiItemL_ex(layout, "Blender", ICON_NONE, true, false);
+ /* Blender logo. */
+#ifndef WITH_HEADLESS
+ extern char datatoc_blender_logo_png[];
+ extern int datatoc_blender_logo_png_size;
- /* Version. */
- uiItemL(layout, BKE_blender_version_string(), ICON_NONE);
+ const uchar *blender_logo_data = (const uchar *)datatoc_blender_logo_png;
+ size_t blender_logo_data_size = datatoc_blender_logo_png_size;
+ ImBuf *ibuf = IMB_ibImageFromMemory(
+ blender_logo_data, blender_logo_data_size, IB_rect, NULL, "blender_logo");
- uiItemS_ex(layout, 3.0f);
+ if (ibuf) {
+ int width = 0.5 * dialog_width;
+ int height = (width * ibuf->y) / ibuf->x;
-#ifdef WITH_BUILDINFO
+ IMB_premultiply_alpha(ibuf);
+ IMB_scaleImBuf(ibuf, width, height);
- extern char build_hash[], build_commit_date[], build_commit_time[], build_branch[];
+ bTheme *btheme = UI_GetTheme();
+ const uchar *color = btheme->tui.wcol_menu_back.text_sel;
- char str_buf[256] = "\0";
- BLI_snprintf(str_buf, sizeof(str_buf), "Date: %s %s", build_commit_date, build_commit_time);
- uiItemL(layout, str_buf, ICON_NONE);
+ /* The top margin. */
+ uiLayout *row = uiLayoutRow(layout, false);
+ uiItemS_ex(row, 0.2f);
- BLI_snprintf(str_buf, sizeof(str_buf), "Hash: %s", build_hash);
- uiItemL(layout, str_buf, ICON_NONE);
+ /* The logo image. */
+ row = uiLayoutRow(layout, false);
+ uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
+ uiDefButImage(block, ibuf, 0, U.widget_unit, width, height, color);
- BLI_snprintf(str_buf, sizeof(str_buf), "Branch: %s", build_branch);
- uiItemL(layout, str_buf, ICON_NONE);
+ /* Padding below the logo. */
+ row = uiLayoutRow(layout, false);
+ uiItemS_ex(row, 2.7f);
+ }
+#endif /* WITH_HEADLESS */
-#endif /* WITH_BUILDINFO */
+ uiLayout *col = uiLayoutColumn(layout, true);
- uiItemS_ex(layout, 1.5f);
+ uiItemL_ex(col, N_("Blender"), ICON_NONE, true, false);
MenuType *mt = WM_menutype_find("WM_MT_splash_about", true);
if (mt) {
- UI_menutype_draw(C, mt, layout);
+ UI_menutype_draw(C, mt, col);
}
- uiItemS_ex(layout, 2.0f);
-
- UI_block_bounds_set_centered(block, 14 * U.dpi_fac);
+ UI_block_bounds_set_centered(block, 22 * U.dpi_fac);
return block;
}
diff --git a/source/blender/windowmanager/intern/wm_surface.c b/source/blender/windowmanager/intern/wm_surface.c
index 4139574460b..715f72d70cf 100644
--- a/source/blender/windowmanager/intern/wm_surface.c
+++ b/source/blender/windowmanager/intern/wm_surface.c
@@ -116,8 +116,7 @@ void wm_surfaces_free(void)
{
wm_surface_clear_drawable();
- for (wmSurface *surf = global_surface_list.first, *surf_next; surf; surf = surf_next) {
- surf_next = surf->next;
+ LISTBASE_FOREACH_MUTABLE (wmSurface *, surf, &global_surface_list) {
wm_surface_remove(surf);
}
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 589b8e2f156..14798653a31 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -2261,6 +2261,17 @@ Scene *WM_windows_scene_get_from_screen(const wmWindowManager *wm, const bScreen
return NULL;
}
+ViewLayer *WM_windows_view_layer_get_from_screen(const wmWindowManager *wm, const bScreen *screen)
+{
+ LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
+ if (WM_window_get_active_screen(win) == screen) {
+ return WM_window_get_active_view_layer(win);
+ }
+ }
+
+ return NULL;
+}
+
WorkSpace *WM_windows_workspace_get_from_screen(const wmWindowManager *wm, const bScreen *screen)
{
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c
index c6a1c565350..2651ec2554f 100644
--- a/source/creator/creator_args.c
+++ b/source/creator/creator_args.c
@@ -667,9 +667,6 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo
# else
printf(" $TMP or $TMPDIR Store temporary files here.\n");
# endif
-# ifdef WITH_SDL
- printf(" $SDL_AUDIODRIVER LibSDL audio driver - alsa, esd, dma.\n");
-# endif
exit(0);
diff --git a/source/tools b/source/tools
-Subproject 7011d02c292ac1c91a5c9cc1a075ea2727982ce
+Subproject d7d7e9d41f7499aa4639f96c843156ff834385b
diff --git a/tests/python/bl_blendfile_io.py b/tests/python/bl_blendfile_io.py
index 49814ea5902..2c27b60f34e 100644
--- a/tests/python/bl_blendfile_io.py
+++ b/tests/python/bl_blendfile_io.py
@@ -20,7 +20,9 @@ class TestBlendFileSaveLoadBasic(TestHelper):
output_dir = self.args.output_dir
self.ensure_path(output_dir)
- output_path = os.path.join(output_dir, "blendfile.blend")
+
+ # Take care to keep the name unique so multiple test jobs can run at once.
+ output_path = os.path.join(output_dir, "blendfile_io.blend")
orig_data = self.blender_data_to_tuple(bpy.data, "orig_data 1")
diff --git a/tests/python/bl_blendfile_liblink.py b/tests/python/bl_blendfile_liblink.py
index b48deb7bd7b..fc618314216 100644
--- a/tests/python/bl_blendfile_liblink.py
+++ b/tests/python/bl_blendfile_liblink.py
@@ -21,6 +21,7 @@ class TestBlendLibLinkSaveLoadBasic(TestHelper):
output_dir = self.args.output_dir
self.ensure_path(output_dir)
+ # Take care to keep the name unique so multiple test jobs can run at once.
output_path = os.path.join(output_dir, "blendlib.blend")
bpy.ops.wm.save_as_mainfile(filepath=output_path, check_existing=False, compress=False)
diff --git a/tests/python/bl_constraints.py b/tests/python/bl_constraints.py
index 4deabc5f541..279c896c6af 100644
--- a/tests/python/bl_constraints.py
+++ b/tests/python/bl_constraints.py
@@ -301,6 +301,80 @@ class ObjectSolverTest(AbstractConstraintTests):
self.matrix_test('Object Solver.owner', initial_matrix)
+class CustomSpaceTest(AbstractConstraintTests):
+ layer_collection = 'Custom Space'
+
+ def test_loc_like_object(self):
+ """Custom Space: basic custom space evaluation for objects"""
+ loc_like_constraint = bpy.data.objects["Custom Space.object.owner"].constraints["Copy Location"]
+ loc_like_constraint.use_x = True
+ loc_like_constraint.use_y = True
+ loc_like_constraint.use_z = True
+ self.matrix_test('Custom Space.object.owner', Matrix((
+ (1.0, 0.0, -2.9802322387695312e-08, -0.01753106713294983),
+ (0.0, 1.0, 0.0, -0.08039519190788269),
+ (-2.9802322387695312e-08, 5.960464477539063e-08, 1.0, 0.1584688425064087),
+ (0.0, 0.0, 0.0, 1.0),
+ )))
+ loc_like_constraint.use_x = False
+ self.matrix_test('Custom Space.object.owner', Matrix((
+ (1.0, 0.0, -2.9802322387695312e-08, 0.18370598554611206),
+ (0.0, 1.0, 0.0, 0.47120195627212524),
+ (-2.9802322387695312e-08, 5.960464477539063e-08, 1.0, -0.16521614789962769),
+ (0.0, 0.0, 0.0, 1.0),
+ )))
+ loc_like_constraint.use_y = False
+ self.matrix_test('Custom Space.object.owner', Matrix((
+ (1.0, 0.0, -2.9802322387695312e-08, -0.46946945786476135),
+ (0.0, 1.0, 0.0, 0.423120379447937),
+ (-2.9802322387695312e-08, 5.960464477539063e-08, 1.0, -0.6532361507415771),
+ (0.0, 0.0, 0.0, 1.0),
+ )))
+ loc_like_constraint.use_z = False
+ loc_like_constraint.use_y = True
+ self.matrix_test('Custom Space.object.owner', Matrix((
+ (1.0, 0.0, -2.9802322387695312e-08, -0.346824586391449),
+ (0.0, 1.0, 0.0, 1.0480815172195435),
+ (-2.9802322387695312e-08, 5.960464477539063e-08, 1.0, 0.48802000284194946),
+ (0.0, 0.0, 0.0, 1.0),
+ )))
+
+ def test_loc_like_armature(self):
+ """Custom Space: basic custom space evaluation for bones"""
+ loc_like_constraint = bpy.data.objects["Custom Space.armature.owner"].pose.bones["Bone"].constraints["Copy Location"]
+ loc_like_constraint.use_x = True
+ loc_like_constraint.use_y = True
+ loc_like_constraint.use_z = True
+ self.bone_matrix_test('Custom Space.armature.owner', 'Bone', Matrix((
+ (0.4556015729904175, -0.03673229366540909, -0.8894257545471191, -0.01753103733062744),
+ (-0.45956411957740784, -0.8654094934463501, -0.19966775178909302, -0.08039522171020508),
+ (-0.762383222579956, 0.49971696734428406, -0.4111628830432892, 0.1584688425064087),
+ (0.0, 0.0, 0.0, 1.0),
+ )))
+ loc_like_constraint.use_x = False
+ self.bone_matrix_test('Custom Space.armature.owner', 'Bone', Matrix((
+ (0.4556015729904175, -0.03673229366540909, -0.8894257545471191, -0.310153603553772),
+ (-0.45956411957740784, -0.8654094934463501, -0.19966775178909302, -0.8824828863143921),
+ (-0.762383222579956, 0.49971696734428406, -0.4111628830432892, 0.629145085811615),
+ (0.0, 0.0, 0.0, 1.0),
+ )))
+ loc_like_constraint.use_y = False
+ self.bone_matrix_test('Custom Space.armature.owner', 'Bone', Matrix((
+ (0.4556015729904175, -0.03673229366540909, -0.8894257545471191, -1.0574829578399658),
+ (-0.45956411957740784, -0.8654094934463501, -0.19966775178909302, -0.937495231628418),
+ (-0.762383222579956, 0.49971696734428406, -0.4111628830432892, 0.07077804207801819),
+ (0.0, 0.0, 0.0, 1.0),
+ )))
+ loc_like_constraint.use_z = False
+ loc_like_constraint.use_y = True
+ self.bone_matrix_test('Custom Space.armature.owner', 'Bone', Matrix((
+ (0.4556015729904175, -0.03673229366540909, -0.8894257545471191, -0.25267064571380615),
+ (-0.45956411957740784, -0.8654094934463501, -0.19966775178909302, -0.9449876546859741),
+ (-0.762383222579956, 0.49971696734428406, -0.4111628830432892, 0.5583670735359192),
+ (0.0, 0.0, 0.0, 1.0),
+ )))
+
+
def main():
global args
import argparse
diff --git a/tests/python/eevee_render_tests.py b/tests/python/eevee_render_tests.py
index 4f1eba3348f..6a21afc7c9a 100644
--- a/tests/python/eevee_render_tests.py
+++ b/tests/python/eevee_render_tests.py
@@ -137,7 +137,7 @@ def main():
report = render_report.Report("Eevee", output_dir, idiff)
report.set_pixelated(True)
report.set_reference_dir("eevee_renders")
- report.set_compare_engines('cycles', 'CPU')
+ report.set_compare_engine('cycles', 'CPU')
ok = report.run(test_dir, blender, get_arguments, batch=True)
sys.exit(not ok)