diff options
author | Sybren A. Stüvel <sybren@stuvel.eu> | 2017-04-28 16:52:07 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@stuvel.eu> | 2017-04-28 16:52:07 +0300 |
commit | 074c5f0d26b20fbb69e558af3e9a6f4183a2ad29 (patch) | |
tree | c724af247c52754db1c8426c2ded278859a8b35c | |
parent | 08142dde2c87b14da505c126350bb49054cf054f (diff) | |
parent | aa88796a6cb6cb65b87508d87c51f1d58234f2ee (diff) |
Merge branch 'master' into blender2.8
28 files changed, 352 insertions, 275 deletions
diff --git a/intern/cycles/kernel/kernel_globals.h b/intern/cycles/kernel/kernel_globals.h index b1f3283d5fc..f95f0d98c52 100644 --- a/intern/cycles/kernel/kernel_globals.h +++ b/intern/cycles/kernel/kernel_globals.h @@ -20,7 +20,7 @@ #define __KERNEL_GLOBALS_H__ #ifdef __KERNEL_CPU__ -#include "util/util_vector.h" +# include "util/util_vector.h" #endif CCL_NAMESPACE_BEGIN diff --git a/intern/cycles/kernel/kernel_image_opencl.h b/intern/cycles/kernel/kernel_image_opencl.h index 15579f55a41..795f2e3149f 100644 --- a/intern/cycles/kernel/kernel_image_opencl.h +++ b/intern/cycles/kernel/kernel_image_opencl.h @@ -64,23 +64,34 @@ ccl_device_inline float svm_image_texture_frac(float x, int *ix) return x - (float)i; } +ccl_device_inline uint kernel_decode_image_interpolation(uint4 info) +{ + return (info.w & (1 << 0)) ? INTERPOLATION_CLOSEST : INTERPOLATION_LINEAR; +} + +ccl_device_inline uint kernel_decode_image_extension(uint4 info) +{ + if(info.w & (1 << 1)) { + return EXTENSION_REPEAT; + } + else if(info.w & (1 << 2)) { + return EXTENSION_EXTEND; + } + else { + return EXTENSION_CLIP; + } +} + ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, float y) { uint4 info = kernel_tex_fetch(__tex_image_packed_info, id*2); uint width = info.x; uint height = info.y; uint offset = info.z; - - /* Image Options */ - uint interpolation = (info.w & (1 << 0)) ? INTERPOLATION_CLOSEST : INTERPOLATION_LINEAR; - uint extension; - if(info.w & (1 << 1)) - extension = EXTENSION_REPEAT; - else if(info.w & (1 << 2)) - extension = EXTENSION_EXTEND; - else - extension = EXTENSION_CLIP; - + /* Decode image options. */ + uint interpolation = kernel_decode_image_interpolation(info); + uint extension = kernel_decode_image_extension(info); + /* Actual sampling. */ float4 r; int ix, iy, nix, niy; if(interpolation == INTERPOLATION_CLOSEST) { @@ -133,7 +144,6 @@ ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, fl r += ty*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix + niy*width); r += ty*tx*svm_image_texture_read(kg, id, offset + nix + niy*width); } - return r; } @@ -145,17 +155,10 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x, uint height = info.y; uint offset = info.z; uint depth = kernel_tex_fetch(__tex_image_packed_info, id*2+1).x; - - /* Image Options */ - uint interpolation = (info.w & (1 << 0)) ? INTERPOLATION_CLOSEST : INTERPOLATION_LINEAR; - uint extension; - if(info.w & (1 << 1)) - extension = EXTENSION_REPEAT; - else if(info.w & (1 << 2)) - extension = EXTENSION_EXTEND; - else - extension = EXTENSION_CLIP; - + /* Decode image options. */ + uint interpolation = kernel_decode_image_interpolation(info); + uint extension = kernel_decode_image_extension(info); + /* Actual sampling. */ float4 r; int ix, iy, iz, nix, niy, niz; if(interpolation == INTERPOLATION_CLOSEST) { @@ -172,7 +175,7 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x, if(extension == EXTENSION_CLIP) { if(x < 0.0f || y < 0.0f || z < 0.0f || x > 1.0f || y > 1.0f || z > 1.0f) - { + { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); } } @@ -199,12 +202,13 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x, niz = svm_image_texture_wrap_periodic(iz+1, depth); } else { - if(extension == EXTENSION_CLIP) + if(extension == EXTENSION_CLIP) { if(x < 0.0f || y < 0.0f || z < 0.0f || x > 1.0f || y > 1.0f || z > 1.0f) { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); } + } /* Fall through. */ /* EXTENSION_EXTEND */ nix = svm_image_texture_wrap_clamp(ix+1, width); @@ -225,8 +229,6 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x, r += tz*(1.0f - ty)*tx*svm_image_texture_read(kg, id, offset + nix + iy*width + niz*width*height); r += tz*ty*(1.0f - tx)*svm_image_texture_read(kg, id, offset + ix + niy*width + niz*width*height); r += tz*ty*tx*svm_image_texture_read(kg, id, offset + nix + niy*width + niz*width*height); - } - return r; } diff --git a/intern/cycles/kernel/kernels/cpu/kernel.cpp b/intern/cycles/kernel/kernels/cpu/kernel.cpp index db2de6836d3..998619ac897 100644 --- a/intern/cycles/kernel/kernels/cpu/kernel.cpp +++ b/intern/cycles/kernel/kernels/cpu/kernel.cpp @@ -115,7 +115,7 @@ void kernel_tex_copy(KernelGlobals *kg, texture_image_float *tex = NULL; int id = atoi(name + strlen("__tex_image_float_")); int array_index = kernel_tex_index(id); - + if(array_index >= 0) { if(array_index >= kg->texture_float_images.size()) { kg->texture_float_images.resize(array_index+1); @@ -134,7 +134,7 @@ void kernel_tex_copy(KernelGlobals *kg, texture_image_uchar4 *tex = NULL; int id = atoi(name + strlen("__tex_image_byte4_")); int array_index = kernel_tex_index(id); - + if(array_index >= 0) { if(array_index >= kg->texture_byte4_images.size()) { kg->texture_byte4_images.resize(array_index+1); @@ -153,7 +153,7 @@ void kernel_tex_copy(KernelGlobals *kg, texture_image_uchar *tex = NULL; int id = atoi(name + strlen("__tex_image_byte_")); int array_index = kernel_tex_index(id); - + if(array_index >= 0) { if(array_index >= kg->texture_byte_images.size()) { kg->texture_byte_images.resize(array_index+1); @@ -172,7 +172,7 @@ void kernel_tex_copy(KernelGlobals *kg, texture_image_half4 *tex = NULL; int id = atoi(name + strlen("__tex_image_half4_")); int array_index = kernel_tex_index(id); - + if(array_index >= 0) { if(array_index >= kg->texture_half4_images.size()) { kg->texture_half4_images.resize(array_index+1); @@ -191,7 +191,7 @@ void kernel_tex_copy(KernelGlobals *kg, texture_image_half *tex = NULL; int id = atoi(name + strlen("__tex_image_half_")); int array_index = kernel_tex_index(id); - + if(array_index >= 0) { if(array_index >= kg->texture_half_images.size()) { kg->texture_half_images.resize(array_index+1); diff --git a/intern/cycles/kernel/svm/svm_voxel.h b/intern/cycles/kernel/svm/svm_voxel.h index 1d97e8344bd..f4a5b2b2994 100644 --- a/intern/cycles/kernel/svm/svm_voxel.h +++ b/intern/cycles/kernel/svm/svm_voxel.h @@ -46,8 +46,13 @@ ccl_device void svm_node_tex_voxel(KernelGlobals *kg, # if defined(__KERNEL_CUDA__) # if __CUDA_ARCH__ >= 300 CUtexObject tex = kernel_tex_fetch(__bindless_mapping, id); - if(kernel_tex_type(id) == IMAGE_DATA_TYPE_FLOAT4 || kernel_tex_type(id) == IMAGE_DATA_TYPE_BYTE4 || kernel_tex_type(id) == IMAGE_DATA_TYPE_HALF4) + const int texture_type = kernel_tex_type(id); + if(texture_type == IMAGE_DATA_TYPE_FLOAT4 || + texture_type == IMAGE_DATA_TYPE_BYTE4 || + texture_type == IMAGE_DATA_TYPE_HALF4) + { r = kernel_tex_image_interp_3d_float4(tex, co.x, co.y, co.z); + } else { float f = kernel_tex_image_interp_3d_float(tex, co.x, co.y, co.z); r = make_float4(f, f, f, 1.0f); diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 697b9f75658..04c86732622 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -52,7 +52,7 @@ ImageManager::ImageManager(const DeviceInfo& info) max_num_images = TEX_NUM_MAX; has_half_images = true; cuda_fermi_limits = false; - + if(device_type == DEVICE_CUDA) { if(!info.has_bindless_textures) { /* CUDA Fermi hardware (SM 2.x) has a hard limit on the number of textures */ @@ -63,7 +63,7 @@ ImageManager::ImageManager(const DeviceInfo& info) else if(device_type == DEVICE_OPENCL) { has_half_images = false; } - + for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) { tex_num_images[type] = 0; } @@ -104,8 +104,8 @@ bool ImageManager::set_animation_frame_update(int frame) } ImageDataType ImageManager::get_image_metadata(const string& filename, - void *builtin_data, - bool& is_linear) + void *builtin_data, + bool& is_linear) { bool is_float = false, is_half = false; is_linear = false; @@ -196,12 +196,21 @@ ImageDataType ImageManager::get_image_metadata(const string& filename, } } +int ImageManager::max_flattened_slot(ImageDataType type) +{ + if(tex_num_images[type] == 0) { + /* No textures for the type, no slots needs allocation. */ + return 0; + } + return type_index_to_flattened_slot(tex_num_images[type], type); +} + /* The lower three bits of a device texture slot number indicate its type. * These functions convert the slot ids from ImageManager "images" ones - * to device ones and vice versa. + * to device ones and vice verse. * * There are special cases for CUDA Fermi, since there we have only 90 image texture - * slots available and shold keep the flattended numbers in the 0-89 range. + * slots available and should keep the flattended numbers in the 0-89 range. */ int ImageManager::type_index_to_flattened_slot(int slot, ImageDataType type) { @@ -354,7 +363,7 @@ int ImageManager::add_image(const string& filename, return -1; } } - + if(slot == images[type].size()) { images[type].resize(images[type].size() + 1); } @@ -372,7 +381,7 @@ int ImageManager::add_image(const string& filename, img->use_alpha = use_alpha; images[type][slot] = img; - + ++tex_num_images[type]; need_update = true; @@ -1017,159 +1026,101 @@ void ImageManager::device_update_slot(Device *device, uint8_t ImageManager::pack_image_options(ImageDataType type, size_t slot) { uint8_t options = 0; - /* Image Options are packed into one uint: * bit 0 -> Interpolation - * bit 1 + 2 + 3-> Extension */ - if(images[type][slot]->interpolation == INTERPOLATION_CLOSEST) + * bit 1 + 2 + 3 -> Extension + */ + if(images[type][slot]->interpolation == INTERPOLATION_CLOSEST) { options |= (1 << 0); - - if(images[type][slot]->extension == EXTENSION_REPEAT) + } + if(images[type][slot]->extension == EXTENSION_REPEAT) { options |= (1 << 1); - else if(images[type][slot]->extension == EXTENSION_EXTEND) + } + else if(images[type][slot]->extension == EXTENSION_EXTEND) { options |= (1 << 2); - else /* EXTENSION_CLIP */ + } + else /* EXTENSION_CLIP */ { options |= (1 << 3); - + } return options; } -void ImageManager::device_pack_images(Device *device, - DeviceScene *dscene, - Progress& /*progess*/) +template<typename T> +void ImageManager::device_pack_images_type( + ImageDataType type, + const vector<device_vector<T>*>& cpu_textures, + device_vector<T> *device_image, + uint4 *info) { - /* For OpenCL, we pack all image textures into a single large texture, and - * do our own interpolation in the kernel. */ size_t size = 0, offset = 0; - ImageDataType type; - - int info_size = tex_num_images[IMAGE_DATA_TYPE_FLOAT4] + tex_num_images[IMAGE_DATA_TYPE_BYTE4] - + tex_num_images[IMAGE_DATA_TYPE_FLOAT] + tex_num_images[IMAGE_DATA_TYPE_BYTE]; - uint4 *info = dscene->tex_image_packed_info.resize(info_size*2); - - /* Byte4 Textures*/ - type = IMAGE_DATA_TYPE_BYTE4; - - for(size_t slot = 0; slot < images[type].size(); slot++) { - if(!images[type][slot]) - continue; - - device_vector<uchar4>& tex_img = *dscene->tex_byte4_image[slot]; - size += tex_img.size(); - } - - uchar4 *pixels_byte4 = dscene->tex_image_byte4_packed.resize(size); - - for(size_t slot = 0; slot < images[type].size(); slot++) { - if(!images[type][slot]) - continue; - - device_vector<uchar4>& tex_img = *dscene->tex_byte4_image[slot]; - - uint8_t options = pack_image_options(type, slot); - - int index = type_index_to_flattened_slot(slot, type) * 2; - info[index] = make_uint4(tex_img.data_width, tex_img.data_height, offset, options); - info[index+1] = make_uint4(tex_img.data_depth, 0, 0, 0); - - memcpy(pixels_byte4+offset, (void*)tex_img.data_pointer, tex_img.memory_size()); - offset += tex_img.size(); - } - - /* Float4 Textures*/ - type = IMAGE_DATA_TYPE_FLOAT4; - size = 0, offset = 0; - - for(size_t slot = 0; slot < images[type].size(); slot++) { - if(!images[type][slot]) - continue; - - device_vector<float4>& tex_img = *dscene->tex_float4_image[slot]; - size += tex_img.size(); - } - - float4 *pixels_float4 = dscene->tex_image_float4_packed.resize(size); - - for(size_t slot = 0; slot < images[type].size(); slot++) { - if(!images[type][slot]) - continue; - - device_vector<float4>& tex_img = *dscene->tex_float4_image[slot]; - - /* todo: support 3D textures, only CPU for now */ - - uint8_t options = pack_image_options(type, slot); - - int index = type_index_to_flattened_slot(slot, type) * 2; - info[index] = make_uint4(tex_img.data_width, tex_img.data_height, offset, options); - info[index+1] = make_uint4(tex_img.data_depth, 0, 0, 0); - - memcpy(pixels_float4+offset, (void*)tex_img.data_pointer, tex_img.memory_size()); - offset += tex_img.size(); - } - - /* Byte Textures*/ - type = IMAGE_DATA_TYPE_BYTE; - size = 0, offset = 0; - + /* First step is to calculate size of the texture we need. */ for(size_t slot = 0; slot < images[type].size(); slot++) { - if(!images[type][slot]) + if(images[type][slot] == NULL) { continue; - - device_vector<uchar>& tex_img = *dscene->tex_byte_image[slot]; + } + device_vector<T>& tex_img = *cpu_textures[slot]; size += tex_img.size(); } - - uchar *pixels_byte = dscene->tex_image_byte_packed.resize(size); - + /* Now we know how much memory we need, so we can allocate and fill. */ + T *pixels = device_image->resize(size); for(size_t slot = 0; slot < images[type].size(); slot++) { - if(!images[type][slot]) + if(images[type][slot] == NULL) { continue; - - device_vector<uchar>& tex_img = *dscene->tex_byte_image[slot]; - + } + device_vector<T>& tex_img = *cpu_textures[slot]; uint8_t options = pack_image_options(type, slot); - - int index = type_index_to_flattened_slot(slot, type) * 2; - info[index] = make_uint4(tex_img.data_width, tex_img.data_height, offset, options); + const int index = type_index_to_flattened_slot(slot, type) * 2; + info[index] = make_uint4(tex_img.data_width, + tex_img.data_height, + offset, + options); info[index+1] = make_uint4(tex_img.data_depth, 0, 0, 0); - - memcpy(pixels_byte+offset, (void*)tex_img.data_pointer, tex_img.memory_size()); + memcpy(pixels + offset, + (void*)tex_img.data_pointer, + tex_img.memory_size()); offset += tex_img.size(); } +} - /* Float Textures*/ - type = IMAGE_DATA_TYPE_FLOAT; - size = 0, offset = 0; - - for(size_t slot = 0; slot < images[type].size(); slot++) { - if(!images[type][slot]) - continue; - - device_vector<float>& tex_img = *dscene->tex_float_image[slot]; - size += tex_img.size(); - } - - float *pixels_float = dscene->tex_image_float_packed.resize(size); - - for(size_t slot = 0; slot < images[type].size(); slot++) { - if(!images[type][slot]) - continue; - - device_vector<float>& tex_img = *dscene->tex_float_image[slot]; - - /* todo: support 3D textures, only CPU for now */ - - uint8_t options = pack_image_options(type, slot); - - int index = type_index_to_flattened_slot(slot, type) * 2; - info[index] = make_uint4(tex_img.data_width, tex_img.data_height, offset, options); - info[index+1] = make_uint4(tex_img.data_depth, 0, 0, 0); +void ImageManager::device_pack_images(Device *device, + DeviceScene *dscene, + Progress& /*progess*/) +{ + /* For OpenCL, we pack all image textures into a single large texture, and + * do our own interpolation in the kernel. + */ - memcpy(pixels_float+offset, (void*)tex_img.data_pointer, tex_img.memory_size()); - offset += tex_img.size(); - } + /* TODO(sergey): This will over-allocate a bit, but this is constant memory + * so should be fine for a short term. + */ + const size_t info_size = max4(max_flattened_slot(IMAGE_DATA_TYPE_FLOAT4), + max_flattened_slot(IMAGE_DATA_TYPE_BYTE4), + max_flattened_slot(IMAGE_DATA_TYPE_FLOAT), + max_flattened_slot(IMAGE_DATA_TYPE_BYTE)); + uint4 *info = dscene->tex_image_packed_info.resize(info_size*2); + /* Pack byte4 textures. */ + device_pack_images_type(IMAGE_DATA_TYPE_BYTE4, + dscene->tex_byte4_image, + &dscene->tex_image_byte4_packed, + info); + /* Pack float4 textures. */ + device_pack_images_type(IMAGE_DATA_TYPE_FLOAT4, + dscene->tex_float4_image, + &dscene->tex_image_float4_packed, + info); + /* Pack byte textures. */ + device_pack_images_type(IMAGE_DATA_TYPE_BYTE, + dscene->tex_byte_image, + &dscene->tex_image_byte_packed, + info); + /* Pack float textures. */ + device_pack_images_type(IMAGE_DATA_TYPE_FLOAT, + dscene->tex_float_image, + &dscene->tex_image_float_packed, + info); + + /* Push textures to the device. */ if(dscene->tex_image_byte4_packed.size()) { if(dscene->tex_image_byte4_packed.device_pointer) { thread_scoped_lock device_lock(device_mutex); diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 76c2cc46f12..5550d019868 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -134,6 +134,7 @@ private: int texture_limit, device_vector<DeviceType>& tex_img); + int max_flattened_slot(ImageDataType type); int type_index_to_flattened_slot(int slot, ImageDataType type); int flattened_slot_to_type_index(int flat_slot, ImageDataType *type); string name_from_type(int type); @@ -151,6 +152,13 @@ private: ImageDataType type, int slot); + template<typename T> + void device_pack_images_type( + ImageDataType type, + const vector<device_vector<T>*>& cpu_textures, + device_vector<T> *device_image, + uint4 *info); + void device_pack_images(Device *device, DeviceScene *dscene, Progress& progess); diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index b02f9f35393..4c2c4f5fcc3 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -114,13 +114,13 @@ public: device_vector<uint> sobol_directions; /* cpu images */ - std::vector<device_vector<float4>* > tex_float4_image; - std::vector<device_vector<uchar4>* > tex_byte4_image; - std::vector<device_vector<half4>* > tex_half4_image; - std::vector<device_vector<float>* > tex_float_image; - std::vector<device_vector<uchar>* > tex_byte_image; - std::vector<device_vector<half>* > tex_half_image; - + vector<device_vector<float4>* > tex_float4_image; + vector<device_vector<uchar4>* > tex_byte4_image; + vector<device_vector<half4>* > tex_half4_image; + vector<device_vector<float>* > tex_float_image; + vector<device_vector<uchar>* > tex_byte_image; + vector<device_vector<half>* > tex_half_image; + /* opencl images */ device_vector<float4> tex_image_float4_packed; device_vector<uchar4> tex_image_byte4_packed; diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h index 296343ecfd3..aacf7c1bd8e 100644 --- a/intern/cycles/util/util_types.h +++ b/intern/cycles/util/util_types.h @@ -156,7 +156,7 @@ enum InterpolationType { /* Texture types * Since we store the type in the lower bits of a flat index, - * the shift and bit mask constant below need to be kept in sync. + * the shift and bit mask constant below need to be kept in sync. */ enum ImageDataType { @@ -166,7 +166,7 @@ enum ImageDataType { IMAGE_DATA_TYPE_FLOAT = 3, IMAGE_DATA_TYPE_BYTE = 4, IMAGE_DATA_TYPE_HALF = 5, - + IMAGE_DATA_NUM_TYPES }; diff --git a/source/blender/alembic/intern/abc_camera.cc b/source/blender/alembic/intern/abc_camera.cc index 4f70b2a972c..16416205983 100644 --- a/source/blender/alembic/intern/abc_camera.cc +++ b/source/blender/alembic/intern/abc_camera.cc @@ -117,11 +117,27 @@ bool AbcCameraReader::valid() const return m_schema.valid(); } -void AbcCameraReader::readObjectData(Main *bmain, float time) +bool AbcCameraReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header, + const Object *const ob, + const char **err_str) const +{ + if (!Alembic::AbcGeom::ICamera::matches(alembic_header)) { + *err_str = "Object type mismatch, Alembic object path pointed to Camera when importing, but not any more."; + return false; + } + + if (ob->type != OB_CAMERA) { + *err_str = "Object type mismatch, Alembic object path points to Camera."; + return false; + } + + return true; +} + +void AbcCameraReader::readObjectData(Main *bmain, const ISampleSelector &sample_sel) { Camera *bcam = static_cast<Camera *>(BKE_camera_add(bmain, m_data_name.c_str())); - ISampleSelector sample_sel(time); CameraSample cam_sample; m_schema.get(cam_sample, sample_sel); diff --git a/source/blender/alembic/intern/abc_camera.h b/source/blender/alembic/intern/abc_camera.h index 1c4b7f77949..16c5cccd5ea 100644 --- a/source/blender/alembic/intern/abc_camera.h +++ b/source/blender/alembic/intern/abc_camera.h @@ -54,8 +54,11 @@ public: AbcCameraReader(const Alembic::Abc::IObject &object, ImportSettings &settings); bool valid() const; + bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header, + const Object *const ob, + const char **err_str) const; - void readObjectData(Main *bmain, float time); + void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel); }; #endif /* __ABC_CAMERA_H__ */ diff --git a/source/blender/alembic/intern/abc_curves.cc b/source/blender/alembic/intern/abc_curves.cc index bf485c7ef61..67b2cb8ae8c 100644 --- a/source/blender/alembic/intern/abc_curves.cc +++ b/source/blender/alembic/intern/abc_curves.cc @@ -211,7 +211,24 @@ bool AbcCurveReader::valid() const return m_curves_schema.valid(); } -void AbcCurveReader::readObjectData(Main *bmain, float time) +bool AbcCurveReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header, + const Object *const ob, + const char **err_str) const +{ + if (!Alembic::AbcGeom::ICurves::matches(alembic_header)) { + *err_str = "Object type mismatch, Alembic object path pointed to Curves when importing, but not any more."; + return false; + } + + if (ob->type != OB_EMPTY) { + *err_str = "Object type mismatch, Alembic object path points to Curves."; + return false; + } + + return true; +} + +void AbcCurveReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel) { Curve *cu = BKE_curve_add(bmain, m_data_name.c_str(), OB_CURVE); @@ -219,8 +236,6 @@ void AbcCurveReader::readObjectData(Main *bmain, float time) cu->actvert = CU_ACT_NONE; cu->resolu = 1; - const ISampleSelector sample_sel(time); - ICompoundProperty user_props = m_curves_schema.getUserProperties(); if (user_props) { const PropertyHeader *header = user_props.getPropertyHeader(ABC_CURVE_RESOLUTION_U_PROPNAME); @@ -389,9 +404,11 @@ void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const ISampleSele * object directly and create a new DerivedMesh from that. Also we might need to * create new or delete existing NURBS in the curve. */ -DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh * /*dm*/, const float time, int /*read_flag*/, const char ** /*err_str*/) +DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh * /*dm*/, + const ISampleSelector &sample_sel, + int /*read_flag*/, + const char ** /*err_str*/) { - ISampleSelector sample_sel(time); const ICurvesSchema::Sample sample = m_curves_schema.getValue(sample_sel); const P3fArraySamplePtr &positions = sample.getPositions(); diff --git a/source/blender/alembic/intern/abc_curves.h b/source/blender/alembic/intern/abc_curves.h index 71b0d205820..a9231f947b2 100644 --- a/source/blender/alembic/intern/abc_curves.h +++ b/source/blender/alembic/intern/abc_curves.h @@ -54,9 +54,15 @@ public: AbcCurveReader(const Alembic::Abc::IObject &object, ImportSettings &settings); bool valid() const; + bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header, + const Object *const ob, + const char **err_str) const; - void readObjectData(Main *bmain, float time); - DerivedMesh *read_derivedmesh(DerivedMesh *, const float time, int read_flag, const char **err_str); + void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel); + DerivedMesh *read_derivedmesh(DerivedMesh *dm, + const Alembic::Abc::ISampleSelector &sample_sel, + int read_flag, + const char **err_str); }; /* ************************************************************************** */ diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc index a0b175dbcdc..15a72cf4453 100644 --- a/source/blender/alembic/intern/abc_mesh.cc +++ b/source/blender/alembic/intern/abc_mesh.cc @@ -1020,17 +1020,15 @@ bool AbcMeshReader::valid() const return m_schema.valid(); } -void AbcMeshReader::readObjectData(Main *bmain, float time) +void AbcMeshReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel) { Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str()); m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str()); m_object->data = mesh; - const ISampleSelector sample_sel(time); - DerivedMesh *dm = CDDM_from_mesh(mesh); - DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL, NULL); + DerivedMesh *ndm = this->read_derivedmesh(dm, sample_sel, MOD_MESHSEQ_READ_ALL, NULL); if (ndm != dm) { dm->release(dm); @@ -1049,9 +1047,28 @@ void AbcMeshReader::readObjectData(Main *bmain, float time) } } -DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str) +bool AbcMeshReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header, + const Object *const ob, + const char **err_str) const +{ + if (!Alembic::AbcGeom::IPolyMesh::matches(alembic_header)) { + *err_str = "Object type mismatch, Alembic object path pointed to PolyMesh when importing, but not any more."; + return false; + } + + if (ob->type != OB_MESH) { + *err_str = "Object type mismatch, Alembic object path points to PolyMesh."; + return false; + } + + return true; +} + +DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, + const ISampleSelector &sample_sel, + int read_flag, + const char **err_str) { - ISampleSelector sample_sel(time); const IPolyMeshSchema::Sample sample = m_schema.getValue(sample_sel); const P3fArraySamplePtr &positions = sample.getPositions(); @@ -1091,7 +1108,7 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, const float time, } CDStreamConfig config = get_config(new_dm ? new_dm : dm); - config.time = time; + config.time = sample_sel.getRequestedTime(); bool do_normals = false; read_mesh_sample(&settings, m_schema, sample_sel, config, do_normals); @@ -1238,7 +1255,24 @@ bool AbcSubDReader::valid() const return m_schema.valid(); } -void AbcSubDReader::readObjectData(Main *bmain, float time) +bool AbcSubDReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header, + const Object *const ob, + const char **err_str) const +{ + if (!Alembic::AbcGeom::ISubD::matches(alembic_header)) { + *err_str = "Object type mismatch, Alembic object path pointed to SubD when importing, but not any more."; + return false; + } + + if (ob->type != OB_MESH) { + *err_str = "Object type mismatch, Alembic object path points to SubD."; + return false; + } + + return true; +} + +void AbcSubDReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel) { Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str()); @@ -1246,7 +1280,7 @@ void AbcSubDReader::readObjectData(Main *bmain, float time) m_object->data = mesh; DerivedMesh *dm = CDDM_from_mesh(mesh); - DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL, NULL); + DerivedMesh *ndm = this->read_derivedmesh(dm, sample_sel, MOD_MESHSEQ_READ_ALL, NULL); if (ndm != dm) { dm->release(dm); @@ -1254,7 +1288,6 @@ void AbcSubDReader::readObjectData(Main *bmain, float time) DM_to_mesh(ndm, mesh, m_object, CD_MASK_MESH, true); - const ISampleSelector sample_sel(time); const ISubDSchema::Sample sample = m_schema.getValue(sample_sel); Int32ArraySamplePtr indices = sample.getCreaseIndices(); Alembic::Abc::FloatArraySamplePtr sharpnesses = sample.getCreaseSharpnesses(); @@ -1285,9 +1318,11 @@ void AbcSubDReader::readObjectData(Main *bmain, float time) } } -DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str) +DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, + const ISampleSelector &sample_sel, + int read_flag, + const char **err_str) { - ISampleSelector sample_sel(time); const ISubDSchema::Sample sample = m_schema.getValue(sample_sel); const P3fArraySamplePtr &positions = sample.getPositions(); @@ -1327,7 +1362,7 @@ DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, const float time, /* Only read point data when streaming meshes, unless we need to create new ones. */ CDStreamConfig config = get_config(new_dm ? new_dm : dm); - config.time = time; + config.time = sample_sel.getRequestedTime(); read_subd_sample(&settings, m_schema, sample_sel, config); if (new_dm) { diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h index 64a3109232c..6bf1dde3d1d 100644 --- a/source/blender/alembic/intern/abc_mesh.h +++ b/source/blender/alembic/intern/abc_mesh.h @@ -99,10 +99,15 @@ public: AbcMeshReader(const Alembic::Abc::IObject &object, ImportSettings &settings); bool valid() const; + bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header, + const Object *const ob, + const char **err_str) const; + void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel); - void readObjectData(Main *bmain, float time); - - DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str); + DerivedMesh *read_derivedmesh(DerivedMesh *dm, + const Alembic::Abc::ISampleSelector &sample_sel, + int read_flag, + const char **err_str); private: void readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start, @@ -120,9 +125,14 @@ public: AbcSubDReader(const Alembic::Abc::IObject &object, ImportSettings &settings); bool valid() const; - - void readObjectData(Main *bmain, float time); - DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str); + bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header, + const Object *const ob, + const char **err_str) const; + void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel); + DerivedMesh *read_derivedmesh(DerivedMesh *dm, + const Alembic::Abc::ISampleSelector &sample_sel, + int read_flag, + const char **err_str); }; /* ************************************************************************** */ diff --git a/source/blender/alembic/intern/abc_nurbs.cc b/source/blender/alembic/intern/abc_nurbs.cc index d0b9561f679..eaef06fd6d1 100644 --- a/source/blender/alembic/intern/abc_nurbs.cc +++ b/source/blender/alembic/intern/abc_nurbs.cc @@ -239,7 +239,7 @@ static bool set_knots(const FloatArraySamplePtr &knots, float *&nu_knots) return true; } -void AbcNurbsReader::readObjectData(Main *bmain, float time) +void AbcNurbsReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel) { Curve *cu = static_cast<Curve *>(BKE_curve_add(bmain, "abc_curve", OB_SURF)); cu->actvert = CU_ACT_NONE; @@ -253,7 +253,6 @@ void AbcNurbsReader::readObjectData(Main *bmain, float time) nu->resolu = cu->resolu; nu->resolv = cu->resolv; - const ISampleSelector sample_sel(time); const INuPatchSchema &schema = it->first; const INuPatchSchema::Sample smp = schema.getValue(sample_sel); diff --git a/source/blender/alembic/intern/abc_nurbs.h b/source/blender/alembic/intern/abc_nurbs.h index 1b2e7a8391f..abe460a8988 100644 --- a/source/blender/alembic/intern/abc_nurbs.h +++ b/source/blender/alembic/intern/abc_nurbs.h @@ -54,7 +54,7 @@ public: bool valid() const; - void readObjectData(Main *bmain, float time); + void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel); private: void getNurbsPatches(const Alembic::Abc::IObject &obj); diff --git a/source/blender/alembic/intern/abc_object.cc b/source/blender/alembic/intern/abc_object.cc index 28a4d185014..8b169988096 100644 --- a/source/blender/alembic/intern/abc_object.cc +++ b/source/blender/alembic/intern/abc_object.cc @@ -215,9 +215,9 @@ Imath::M44d get_matrix(const IXformSchema &schema, const float time) } DerivedMesh *AbcObjectReader::read_derivedmesh(DerivedMesh *dm, - const float UNUSED(time), - int UNUSED(read_flag), - const char **UNUSED(err_str)) + const Alembic::Abc::ISampleSelector &UNUSED(sample_sel), + int UNUSED(read_flag), + const char **UNUSED(err_str)) { return dm; } diff --git a/source/blender/alembic/intern/abc_object.h b/source/blender/alembic/intern/abc_object.h index ade232b11e7..1462f93a422 100644 --- a/source/blender/alembic/intern/abc_object.h +++ b/source/blender/alembic/intern/abc_object.h @@ -169,11 +169,14 @@ public: const std::string & data_name() const { return m_data_name; } virtual bool valid() const = 0; + virtual bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header, + const Object *const ob, + const char **err_str) const = 0; - virtual void readObjectData(Main *bmain, float time) = 0; + virtual void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel) = 0; virtual DerivedMesh *read_derivedmesh(DerivedMesh *dm, - const float time, + const Alembic::Abc::ISampleSelector &sample_sel, int read_flag, const char **err_str); diff --git a/source/blender/alembic/intern/abc_points.cc b/source/blender/alembic/intern/abc_points.cc index fc84759b1d9..3a2ca8a1b47 100644 --- a/source/blender/alembic/intern/abc_points.cc +++ b/source/blender/alembic/intern/abc_points.cc @@ -151,12 +151,29 @@ bool AbcPointsReader::valid() const return m_schema.valid(); } -void AbcPointsReader::readObjectData(Main *bmain, float time) +bool AbcPointsReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header, + const Object *const ob, + const char **err_str) const +{ + if (!Alembic::AbcGeom::IPoints::matches(alembic_header)) { + *err_str = "Object type mismatch, Alembic object path pointed to Points when importing, but not any more."; + return false; + } + + if (ob->type != OB_EMPTY) { + *err_str = "Object type mismatch, Alembic object path points to Points."; + return false; + } + + return true; +} + +void AbcPointsReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel) { Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str()); DerivedMesh *dm = CDDM_from_mesh(mesh); - DerivedMesh *ndm = this->read_derivedmesh(dm, time, 0, NULL); + DerivedMesh *ndm = this->read_derivedmesh(dm, sample_sel, 0, NULL); if (ndm != dm) { dm->release(dm); @@ -178,8 +195,7 @@ void AbcPointsReader::readObjectData(Main *bmain, float time) void read_points_sample(const IPointsSchema &schema, const ISampleSelector &selector, - CDStreamConfig &config, - float time) + CDStreamConfig &config) { Alembic::AbcGeom::IPointsSchema::Sample sample = schema.getValue(selector); @@ -189,7 +205,7 @@ void read_points_sample(const IPointsSchema &schema, N3fArraySamplePtr vnormals; if (has_property(prop, "N")) { - const Alembic::Util::uint32_t itime = static_cast<Alembic::Util::uint32_t>(time); + const Alembic::Util::uint32_t itime = static_cast<Alembic::Util::uint32_t>(selector.getRequestedTime()); const IN3fArrayProperty &normals_prop = IN3fArrayProperty(prop, "N", itime); if (normals_prop) { @@ -200,9 +216,11 @@ void read_points_sample(const IPointsSchema &schema, read_mverts(config.mvert, positions, vnormals); } -DerivedMesh *AbcPointsReader::read_derivedmesh(DerivedMesh *dm, const float time, int /*read_flag*/, const char ** /*err_str*/) +DerivedMesh *AbcPointsReader::read_derivedmesh(DerivedMesh *dm, + const ISampleSelector &sample_sel, + int /*read_flag*/, + const char ** /*err_str*/) { - ISampleSelector sample_sel(time); const IPointsSchema::Sample sample = m_schema.getValue(sample_sel); const P3fArraySamplePtr &positions = sample.getPositions(); @@ -214,7 +232,7 @@ DerivedMesh *AbcPointsReader::read_derivedmesh(DerivedMesh *dm, const float time } CDStreamConfig config = get_config(new_dm ? new_dm : dm); - read_points_sample(m_schema, sample_sel, config, time); + read_points_sample(m_schema, sample_sel, config); return new_dm ? new_dm : dm; } diff --git a/source/blender/alembic/intern/abc_points.h b/source/blender/alembic/intern/abc_points.h index cb68dbca4d5..369a802d763 100644 --- a/source/blender/alembic/intern/abc_points.h +++ b/source/blender/alembic/intern/abc_points.h @@ -58,15 +58,20 @@ public: AbcPointsReader(const Alembic::Abc::IObject &object, ImportSettings &settings); bool valid() const; + bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header, + const Object *const ob, + const char **err_str) const; - void readObjectData(Main *bmain, float time); + void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel); - DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str); + DerivedMesh *read_derivedmesh(DerivedMesh *dm, + const Alembic::Abc::ISampleSelector &sample_sel, + int read_flag, + const char **err_str); }; void read_points_sample(const Alembic::AbcGeom::IPointsSchema &schema, const Alembic::AbcGeom::ISampleSelector &selector, - CDStreamConfig &config, - float time); + CDStreamConfig &config); #endif /* __ABC_POINTS_H__ */ diff --git a/source/blender/alembic/intern/abc_transform.cc b/source/blender/alembic/intern/abc_transform.cc index 6e218cac429..e2369e80618 100644 --- a/source/blender/alembic/intern/abc_transform.cc +++ b/source/blender/alembic/intern/abc_transform.cc @@ -36,6 +36,7 @@ extern "C" { using Alembic::AbcGeom::OObject; using Alembic::AbcGeom::OXform; +using Alembic::Abc::ISampleSelector; /* ************************************************************************** */ @@ -153,7 +154,24 @@ bool AbcEmptyReader::valid() const return m_schema.valid(); } -void AbcEmptyReader::readObjectData(Main *bmain, float /*time*/) +bool AbcEmptyReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header, + const Object *const ob, + const char **err_str) const +{ + if (!Alembic::AbcGeom::IXform::matches(alembic_header)) { + *err_str = "Object type mismatch, Alembic object path pointed to XForm when importing, but not any more."; + return false; + } + + if (ob->type != OB_EMPTY) { + *err_str = "Object type mismatch, Alembic object path points to XForm."; + return false; + } + + return true; +} + +void AbcEmptyReader::readObjectData(Main *bmain, const ISampleSelector &UNUSED(sample_sel)) { m_object = BKE_object_add_only_object(bmain, OB_EMPTY, m_object_name.c_str()); diff --git a/source/blender/alembic/intern/abc_transform.h b/source/blender/alembic/intern/abc_transform.h index 59388e155dc..753a4247e9f 100644 --- a/source/blender/alembic/intern/abc_transform.h +++ b/source/blender/alembic/intern/abc_transform.h @@ -68,8 +68,11 @@ public: AbcEmptyReader(const Alembic::Abc::IObject &object, ImportSettings &settings); bool valid() const; + bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header, + const Object *const ob, + const char **err_str) const; - void readObjectData(Main *bmain, float time); + void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel); }; #endif /* __ABC_TRANSFORM_H__ */ diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc index 61b18c7112f..ac195ffc955 100644 --- a/source/blender/alembic/intern/alembic_capi.cc +++ b/source/blender/alembic/intern/alembic_capi.cc @@ -732,12 +732,13 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa chrono_t min_time = std::numeric_limits<chrono_t>::max(); chrono_t max_time = std::numeric_limits<chrono_t>::min(); + ISampleSelector sample_sel(0.0f); std::vector<AbcObjectReader *>::iterator iter; for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) { AbcObjectReader *reader = *iter; if (reader->valid()) { - reader->readObjectData(data->bmain, 0.0f); + reader->readObjectData(data->bmain, sample_sel); min_time = std::min(min_time, reader->minTime()); max_time = std::max(max_time, reader->maxTime()); @@ -970,42 +971,13 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader, } const ObjectHeader &header = iobject.getHeader(); - - if (IPolyMesh::matches(header)) { - if (ob->type != OB_MESH) { - *err_str = "Object type mismatch: object path points to a mesh!"; - return NULL; - } - - return abc_reader->read_derivedmesh(dm, time, read_flag, err_str); - } - else if (ISubD::matches(header)) { - if (ob->type != OB_MESH) { - *err_str = "Object type mismatch: object path points to a subdivision mesh!"; - return NULL; - } - - return abc_reader->read_derivedmesh(dm, time, read_flag, err_str); - } - else if (IPoints::matches(header)) { - if (ob->type != OB_MESH) { - *err_str = "Object type mismatch: object path points to a point cloud (requires a mesh object)!"; - return NULL; - } - - return abc_reader->read_derivedmesh(dm, time, read_flag, err_str); - } - else if (ICurves::matches(header)) { - if (ob->type != OB_CURVE) { - *err_str = "Object type mismatch: object path points to a curve!"; - return NULL; - } - - return abc_reader->read_derivedmesh(dm, time, read_flag, err_str); + if (!abc_reader->accepts_object_type(header, ob, err_str)) { + /* err_str is set by acceptsObjectType() */ + return NULL; } - *err_str = "Unsupported object type: verify object path"; // or poke developer - return NULL; + ISampleSelector sample_sel(time); + return abc_reader->read_derivedmesh(dm, sample_sel, read_flag, err_str); } /* ************************************************************************** */ diff --git a/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c index 2ad097013ef..fde7dccb4ac 100644 --- a/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c +++ b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c @@ -47,6 +47,7 @@ static void node_composit_init_bilateralblur(bNodeTree *UNUSED(ntree), bNode *no { NodeBilateralBlurData *nbbd = MEM_callocN(sizeof(NodeBilateralBlurData), "node bilateral blur data"); node->storage = nbbd; + nbbd->iter = 1; nbbd->sigma_color = 0.3; nbbd->sigma_space = 5.0; } diff --git a/source/blender/nodes/composite/nodes/node_composite_directionalblur.c b/source/blender/nodes/composite/nodes/node_composite_directionalblur.c index 6eb27a228ad..336eb3409ff 100644 --- a/source/blender/nodes/composite/nodes/node_composite_directionalblur.c +++ b/source/blender/nodes/composite/nodes/node_composite_directionalblur.c @@ -46,6 +46,7 @@ static void node_composit_init_dblur(bNodeTree *UNUSED(ntree), bNode *node) { NodeDBlurData *ndbd = MEM_callocN(sizeof(NodeDBlurData), "node dblur data"); node->storage = ndbd; + ndbd->iter = 1; ndbd->center_x = 0.5; ndbd->center_y = 0.5; } diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index d7406588952..3850846b0b9 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -1160,7 +1160,6 @@ static const char arg_handle_threads_set_doc[] = "<threads>\n" "\tUse amount of <threads> for rendering and other operations\n" "\t[1-" STRINGIFY(BLENDER_MAX_THREADS) "], 0 for systems processor count." -"(This must be the first argument)" ; static int arg_handle_threads_set(int argc, const char **argv, void *UNUSED(data)) { diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 9042b804be9..5240a4144c9 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -462,7 +462,7 @@ if(WITH_ALEMBIC) COMMAND "$<TARGET_FILE_DIR:blender>/${BLENDER_VERSION_MAJOR}.${BLENDER_VERSION_MINOR}/python/bin/python$<$<CONFIG:Debug>:_d>" ${CMAKE_CURRENT_LIST_DIR}/alembic_tests.py - --blender "${TEST_BLENDER_EXE_BARE}" + --blender "$<TARGET_FILE:blender>" --testdir "${TEST_SRC_DIR}/alembic" --alembic-root "${ALEMBIC_ROOT_DIR}" ) diff --git a/tests/python/alembic_tests.py b/tests/python/alembic_tests.py index 2a2dd0230cf..e36a6391298 100755 --- a/tests/python/alembic_tests.py +++ b/tests/python/alembic_tests.py @@ -124,6 +124,11 @@ class AbstractAlembicTest(unittest.TestCase): coloured_output = proc.stdout output = self.ansi_remove_re.sub(b'', coloured_output).decode('utf8') + # Because of the ANSI colour codes, we need to remove those first before + # decoding to text. This means that we cannot use the universal_newlines + # parameter to subprocess.run(), and have to do the conversion ourselves + output = output.replace('\r\n', '\n').replace('\r', '\n') + if proc.returncode: raise AbcPropError('Error %d running abcls:\n%s' % (proc.returncode, output)) @@ -217,7 +222,7 @@ class HierarchicalAndFlatExportTest(AbstractAlembicTest): def test_hierarchical_export(self, tempdir: pathlib.Path): abc = tempdir / 'cubes_hierarchical.abc' script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \ - "renderable_only=True, visible_layers_only=True, flatten=False)" % abc + "renderable_only=True, visible_layers_only=True, flatten=False)" % abc.as_posix() self.run_blender('cubes-hierarchy.blend', script) # Now check the resulting Alembic file. @@ -235,7 +240,7 @@ class HierarchicalAndFlatExportTest(AbstractAlembicTest): def test_flat_export(self, tempdir: pathlib.Path): abc = tempdir / 'cubes_flat.abc' script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \ - "renderable_only=True, visible_layers_only=True, flatten=True)" % abc + "renderable_only=True, visible_layers_only=True, flatten=True)" % abc.as_posix() self.run_blender('cubes-hierarchy.blend', script) # Now check the resulting Alembic file. @@ -256,7 +261,7 @@ class DupliGroupExportTest(AbstractAlembicTest): def test_hierarchical_export(self, tempdir: pathlib.Path): abc = tempdir / 'dupligroup_hierarchical.abc' script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \ - "renderable_only=True, visible_layers_only=True, flatten=False)" % abc + "renderable_only=True, visible_layers_only=True, flatten=False)" % abc.as_posix() self.run_blender('dupligroup-scene.blend', script) # Now check the resulting Alembic file. @@ -274,7 +279,7 @@ class DupliGroupExportTest(AbstractAlembicTest): def test_flat_export(self, tempdir: pathlib.Path): abc = tempdir / 'dupligroup_hierarchical.abc' script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \ - "renderable_only=True, visible_layers_only=True, flatten=True)" % abc + "renderable_only=True, visible_layers_only=True, flatten=True)" % abc.as_posix() self.run_blender('dupligroup-scene.blend', script) # Now check the resulting Alembic file. @@ -295,7 +300,7 @@ class CurveExportTest(AbstractAlembicTest): def test_export_single_curve(self, tempdir: pathlib.Path): abc = tempdir / 'single-curve.abc' script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \ - "renderable_only=True, visible_layers_only=True, flatten=False)" % abc + "renderable_only=True, visible_layers_only=True, flatten=False)" % abc.as_posix() self.run_blender('single-curve.blend', script) # Now check the resulting Alembic file. @@ -318,7 +323,7 @@ class HairParticlesExportTest(AbstractAlembicTest): script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \ "renderable_only=True, visible_layers_only=True, flatten=False, " \ "export_hair=%r, export_particles=%r, as_background_job=False)" \ - % (abc, export_hair, export_particles) + % (abc.as_posix(), export_hair, export_particles) self.run_blender('hair-particles.blend', script) return abc @@ -377,7 +382,7 @@ class LongNamesExportTest(AbstractAlembicTest): def test_export_long_names(self, tempdir: pathlib.Path): abc = tempdir / 'long-names.abc' script = "import bpy; bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, " \ - "renderable_only=False, visible_layers_only=False, flatten=False)" % abc + "renderable_only=False, visible_layers_only=False, flatten=False)" % abc.as_posix() self.run_blender('long-names.blend', script) name_parts = [ |