diff --git a/CMakeLists.txt b/CMakeLists.txt index f64285314a6..dc514a28905 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1026,9 +1026,13 @@ elseif(WIN32) set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib) set(OPENIMAGEIO_DEFINITIONS) endif() - + set(PLATFORM_LINKFLAGS "-Xlinker --stack=2097152") + ## DISABLE - causes linking errors + ## for re-distrobution, so users dont need mingw installed + # set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -static-libgcc -static-libstdc++") + endif() # used in many places so include globally, like OpenGL diff --git a/build_files/scons/config/win32-mingw-config.py b/build_files/scons/config/win32-mingw-config.py index e4f8827b7c8..9fac0a31029 100644 --- a/build_files/scons/config/win32-mingw-config.py +++ b/build_files/scons/config/win32-mingw-config.py @@ -190,6 +190,10 @@ LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32 PLATFORM_LINKFLAGS = ['-Xlinker', '--stack=2097152'] +## DISABLED, causes linking errors! +## for re-distrobution, so users dont need mingw installed +# PLATFORM_LINKFLAGS += ["-static-libgcc", "-static-libstdc++"] + BF_DEBUG = False BF_DEBUG_CCFLAGS= ['-g', '-D_DEBUG'] diff --git a/doc/python_api/examples/bpy.types.Operator.4.py b/doc/python_api/examples/bpy.types.Operator.4.py index 4cb7b02fdc6..861496c6d18 100644 --- a/doc/python_api/examples/bpy.types.Operator.4.py +++ b/doc/python_api/examples/bpy.types.Operator.4.py @@ -22,7 +22,7 @@ class CustomDrawOperator(bpy.types.Operator): my_string = bpy.props.StringProperty(name="String Value") def execute(self, context): - print() + print("Test", self) return {'FINISHED'} def invoke(self, context, event): diff --git a/doc/python_api/examples/bpy.types.Operator.5.py b/doc/python_api/examples/bpy.types.Operator.5.py index 7d1a98d4c34..e123768431b 100644 --- a/doc/python_api/examples/bpy.types.Operator.5.py +++ b/doc/python_api/examples/bpy.types.Operator.5.py @@ -31,6 +31,7 @@ class ModalOperator(bpy.types.Operator): def execute(self, context): context.object.location.x = self.value / 100.0 + return {'FINISHED'} def modal(self, context, event): if event.type == 'MOUSEMOVE': # Apply diff --git a/doc/python_api/rst/info_best_practice.rst b/doc/python_api/rst/info_best_practice.rst index 9e310711bf3..16fd030b42a 100644 --- a/doc/python_api/rst/info_best_practice.rst +++ b/doc/python_api/rst/info_best_practice.rst @@ -83,7 +83,7 @@ Even though you're not looping on the list data **python is**, so you need to be Modifying Lists ^^^^^^^^^^^^^^^ -In python we can add and remove from a list, This is slower when the list length is modifier, especially at the start of the list, since all the data after the index of modification needs to be moved up or down 1 place. +In python we can add and remove from a list, This is slower when the list length is modified, especially at the start of the list, since all the data after the index of modification needs to be moved up or down 1 place. The most simple way to add onto the end of the list is to use ``my_list.append(list_item)`` or ``my_list.extend(some_list)`` and the fastest way to remove an item is ``my_list.pop()`` or ``del my_list[-1]``. diff --git a/intern/cycles/app/cycles_server.cpp b/intern/cycles/app/cycles_server.cpp index bcf4d3ea769..e6a13e04b48 100644 --- a/intern/cycles/app/cycles_server.cpp +++ b/intern/cycles/app/cycles_server.cpp @@ -34,8 +34,9 @@ int main(int argc, const char **argv) /* device types */ string devices = ""; string devicename = "cpu"; + bool list = false; - vector types = Device::available_types(); + vector& types = Device::available_types(); foreach(DeviceType type, types) { if(devices != "") @@ -49,6 +50,7 @@ int main(int argc, const char **argv) ap.options ("Usage: cycles_server [options]", "--device %s", &devicename, ("Devices to use: " + devices).c_str(), + "--list-devices", &list, "List information about all available devices", NULL); if(ap.parse(argc, argv) < 0) { @@ -56,11 +58,34 @@ int main(int argc, const char **argv) ap.usage(); exit(EXIT_FAILURE); } + else if(list) { + vector& devices = Device::available_devices(); - DeviceType dtype = Device::type_from_string(devicename.c_str()); + printf("Devices:\n"); + + foreach(DeviceInfo& info, devices) { + printf(" %s%s\n", + info.description.c_str(), + (info.display_device)? " (display)": ""); + } + + exit(EXIT_SUCCESS); + } + + /* find matching device */ + DeviceType device_type = Device::type_from_string(devicename.c_str()); + vector& devices = Device::available_devices(); + DeviceInfo device_info; + + foreach(DeviceInfo& device, devices) { + if(device_type == device.type) { + device_info = device; + break; + } + } while(1) { - Device *device = Device::create(dtype); + Device *device = Device::create(device_info); printf("Cycles Server with device: %s\n", device->description().c_str()); device->server_run(); delete device; diff --git a/intern/cycles/app/cycles_test.cpp b/intern/cycles/app/cycles_test.cpp index d9386f75141..0b8853d7036 100644 --- a/intern/cycles/app/cycles_test.cpp +++ b/intern/cycles/app/cycles_test.cpp @@ -203,17 +203,18 @@ static void options_parse(int argc, const char **argv) options.session = NULL; options.quiet = false; - /* devices */ - string devices = ""; + /* device names */ + string device_names = ""; string devicename = "cpu"; + bool list = false; - vector types = Device::available_types(); + vector& types = Device::available_types(); foreach(DeviceType type, types) { - if(devices != "") - devices += ", "; + if(device_names != "") + device_names += ", "; - devices += Device::string_from_type(type); + device_names += Device::string_from_type(type); } /* shading system */ @@ -230,7 +231,7 @@ static void options_parse(int argc, const char **argv) ap.options ("Usage: cycles_test [options] file.xml", "%*", files_parse, "", - "--device %s", &devicename, ("Devices to use: " + devices).c_str(), + "--device %s", &devicename, ("Devices to use: " + device_names).c_str(), "--shadingsys %s", &ssname, "Shading system to use: svm, osl", "--background", &options.session_params.background, "Render in background, without user interface", "--quiet", &options.quiet, "In background mode, don't print progress messages", @@ -239,6 +240,7 @@ static void options_parse(int argc, const char **argv) "--threads %d", &options.session_params.threads, "CPU Rendering Threads", "--width %d", &options.width, "Window width in pixel", "--height %d", &options.height, "Window height in pixel", + "--list-devices", &list, "List information about all available devices", "--help", &help, "Print help message", NULL); @@ -247,26 +249,44 @@ static void options_parse(int argc, const char **argv) ap.usage(); exit(EXIT_FAILURE); } + else if(list) { + vector& devices = Device::available_devices(); + printf("Devices:\n"); + + foreach(DeviceInfo& info, devices) { + printf(" %s%s\n", + info.description.c_str(), + (info.display_device)? " (display)": ""); + } + + exit(EXIT_SUCCESS); + } else if(help || options.filepath == "") { ap.usage(); exit(EXIT_SUCCESS); } - options.session_params.device_type = Device::type_from_string(devicename.c_str()); - if(ssname == "osl") options.scene_params.shadingsystem = SceneParams::OSL; else if(ssname == "svm") options.scene_params.shadingsystem = SceneParams::SVM; + /* find matching device */ + DeviceType device_type = Device::type_from_string(devicename.c_str()); + vector& devices = Device::available_devices(); + DeviceInfo device_info; + bool device_available = false; + + foreach(DeviceInfo& device, devices) { + if(device_type == device.type) { + options.session_params.device = device; + device_available = true; + break; + } + } + /* handle invalid configurations */ - bool type_available = false; - - foreach(DeviceType dtype, types) - if(options.session_params.device_type == dtype) - type_available = true; - - if(options.session_params.device_type == DEVICE_NONE || !type_available) { + if(options.session_params.device.type == DEVICE_NONE || !device_available) { fprintf(stderr, "Unknown device: %s\n", devicename.c_str()); exit(EXIT_FAILURE); } @@ -278,7 +298,7 @@ static void options_parse(int argc, const char **argv) fprintf(stderr, "Unknown shading system: %s\n", ssname.c_str()); exit(EXIT_FAILURE); } - else if(options.scene_params.shadingsystem == SceneParams::OSL && options.session_params.device_type != DEVICE_CPU) { + else if(options.scene_params.shadingsystem == SceneParams::OSL && options.session_params.device.type != DEVICE_CPU) { fprintf(stderr, "OSL shading system only works with CPU device\n"); exit(EXIT_FAILURE); } diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 286a9b5b24f..8f54f291cfb 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -248,10 +248,10 @@ bool BlenderSync::get_session_pause(BL::Scene b_scene, bool background) return (background)? false: get_boolean(cscene, "preview_pause"); } -static bool device_type_available(vector& types, DeviceType dtype) +static bool device_type_available(vector& devices, DeviceType dtype) { - foreach(DeviceType dt, types) - if(dt == dtype) + foreach(DeviceInfo& info, devices) + if(info.type == dtype) return true; return false; @@ -266,24 +266,28 @@ SessionParams BlenderSync::get_session_params(BL::Scene b_scene, bool background params.experimental = (RNA_enum_get(&cscene, "feature_set") != 0); /* device type */ - params.device_type = DEVICE_CPU; + vector devices = Device::available_devices(); + DeviceType device_type = DEVICE_CPU; if(RNA_enum_get(&cscene, "device") != 0) { - vector types = Device::available_types(); - DeviceType dtype; if(!params.experimental || RNA_enum_get(&cscene, "gpu_type") == 0) - dtype = DEVICE_CUDA; + device_type = DEVICE_CUDA; else - dtype = DEVICE_OPENCL; + device_type = DEVICE_OPENCL; - if(device_type_available(types, dtype)) - params.device_type = dtype; - else if(params.experimental && device_type_available(types, DEVICE_OPENCL)) - params.device_type = DEVICE_OPENCL; - else if(device_type_available(types, DEVICE_CUDA)) - params.device_type = DEVICE_CUDA; + if(device_type_available(devices, device_type)) + ; + else if(params.experimental && device_type_available(devices, DEVICE_OPENCL)) + device_type = DEVICE_OPENCL; + else if(device_type_available(devices, DEVICE_CUDA)) + device_type = DEVICE_CUDA; } + + params.device = devices[0]; + foreach(DeviceInfo& info, devices) + if(info.type == device_type) + params.device = info; /* Background */ params.background = background; diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp index 55fc3bacbba..83600120fdd 100644 --- a/intern/cycles/device/device.cpp +++ b/intern/cycles/device/device.cpp @@ -118,7 +118,7 @@ void Device::pixels_free(device_memory& mem) mem_free(mem); } -void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int width, int height, bool transparent) +void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent) { pixels_copy_from(rgba, y, w, h); @@ -128,7 +128,7 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int width, in } glPixelZoom((float)width/(float)w, (float)height/(float)h); - glRasterPos2f(0, y); + glRasterPos2f(0, dy); uint8_t *pixels = (uint8_t*)rgba.data_pointer; @@ -145,36 +145,36 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int width, in glDisable(GL_BLEND); } -Device *Device::create(DeviceType type, bool background, int threads) +Device *Device::create(DeviceInfo& info, bool background, int threads) { Device *device; - switch(type) { + switch(info.type) { case DEVICE_CPU: - device = device_cpu_create(threads); + device = device_cpu_create(info, threads); break; #ifdef WITH_CUDA case DEVICE_CUDA: if(cuLibraryInit()) - device = device_cuda_create(background); + device = device_cuda_create(info, background); else device = NULL; break; #endif #ifdef WITH_MULTI case DEVICE_MULTI: - device = device_multi_create(background); + device = device_multi_create(info, background); break; #endif #ifdef WITH_NETWORK case DEVICE_NETWORK: - device = device_network_create("127.0.0.1"); + device = device_network_create(info, "127.0.0.1"); break; #endif #ifdef WITH_OPENCL case DEVICE_OPENCL: if(clLibraryInit()) - device = device_opencl_create(background); + device = device_opencl_create(info, background); else device = NULL; break; @@ -218,31 +218,68 @@ string Device::string_from_type(DeviceType type) return ""; } -vector Device::available_types() +vector& Device::available_types() { - vector types; + static vector types; + static bool types_init = false; - types.push_back(DEVICE_CPU); + if(!types_init) { + types.push_back(DEVICE_CPU); #ifdef WITH_CUDA - if(cuLibraryInit()) - types.push_back(DEVICE_CUDA); + if(cuLibraryInit()) + types.push_back(DEVICE_CUDA); #endif #ifdef WITH_OPENCL - if(clLibraryInit()) - types.push_back(DEVICE_OPENCL); + if(clLibraryInit()) + types.push_back(DEVICE_OPENCL); #endif #ifdef WITH_NETWORK - types.push_back(DEVICE_NETWORK); + types.push_back(DEVICE_NETWORK); #endif #ifdef WITH_MULTI - types.push_back(DEVICE_MULTI); + types.push_back(DEVICE_MULTI); #endif + types_init = true; + } + return types; } +vector& Device::available_devices() +{ + static vector devices; + static bool devices_init = false; + + if(!devices_init) { + device_cpu_info(devices); + +#ifdef WITH_CUDA + if(cuLibraryInit()) + device_cuda_info(devices); +#endif + +#ifdef WITH_OPENCL + if(clLibraryInit()) + device_opencl_info(devices); +#endif + +#ifdef WITH_MULTI + device_multi_info(devices); +#endif + +#ifdef WITH_NETWORK + device_network_info(devices); +#endif + + devices_init = true; + } + + return devices; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index af9bb694c1b..51505aa9cb9 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -33,6 +33,8 @@ CCL_NAMESPACE_BEGIN class Progress; +/* Device Types */ + enum DeviceType { DEVICE_NONE, DEVICE_CPU, @@ -42,10 +44,22 @@ enum DeviceType { DEVICE_MULTI }; -enum MemoryType { - MEM_READ_ONLY, - MEM_WRITE_ONLY, - MEM_READ_WRITE +class DeviceInfo { +public: + DeviceType type; + string description; + string id; + int num; + bool display_device; + vector multi_devices; + + DeviceInfo() + { + type = DEVICE_CPU; + id = "CPU"; + num = 0; + display_device = false; + } }; /* Device Task */ @@ -91,7 +105,7 @@ public: /* info */ virtual string description() = 0; - const string& error_message() { return error_msg; } + virtual const string& error_message() { return error_msg; } /* regular memory */ virtual void mem_alloc(device_memory& mem, MemoryType type) = 0; @@ -127,7 +141,7 @@ public: /* opengl drawing */ virtual void draw_pixels(device_memory& mem, int y, int w, int h, - int width, int height, bool transparent); + int dy, int width, int height, bool transparent); #ifdef WITH_NETWORK /* networking */ @@ -135,11 +149,12 @@ public: #endif /* static */ - static Device *create(DeviceType type, bool background = true, int threads = 0); + static Device *create(DeviceInfo& info, bool background = true, int threads = 0); static DeviceType type_from_string(const char *name); static string string_from_type(DeviceType type); - static vector available_types(); + static vector& available_types(); + static vector& available_devices(); }; CCL_NAMESPACE_END diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp index 145eab9ff59..c93c6ff17da 100644 --- a/intern/cycles/device/device_cpu.cpp +++ b/intern/cycles/device/device_cpu.cpp @@ -258,10 +258,22 @@ public: } }; -Device *device_cpu_create(int threads) +Device *device_cpu_create(DeviceInfo& info, int threads) { return new CPUDevice(threads); } +void device_cpu_info(vector& devices) +{ + DeviceInfo info; + + info.type = DEVICE_CPU; + info.description = system_cpu_brand_string(); + info.id = "CPU"; + info.num = 0; + + devices.push_back(info); +} + CCL_NAMESPACE_END diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index 3c5aafd3f60..73d87ae4a2e 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -159,11 +159,11 @@ public: cuda_assert(cuCtxSetCurrent(NULL)); } - CUDADevice(bool background_) + CUDADevice(DeviceInfo& info, bool background_) { background = background_; - cuDevId = 0; + cuDevId = info.num; cuDevice = 0; cuContext = 0; @@ -205,7 +205,7 @@ public: string description() { /* print device information */ - char deviceName[100]; + char deviceName[256]; cuda_push_context(); cuDeviceGetName(deviceName, 256, cuDevId); @@ -768,7 +768,7 @@ public: } } - void draw_pixels(device_memory& mem, int y, int w, int h, int width, int height, bool transparent) + void draw_pixels(device_memory& mem, int y, int w, int h, int dy, int width, int height, bool transparent) { if(!background) { PixelMem pmem = pixel_mem_map[mem.device_pointer]; @@ -794,7 +794,7 @@ public: glColor3f(1.0f, 1.0f, 1.0f); glPushMatrix(); - glTranslatef(0.0f, (float)y, 0.0f); + glTranslatef(0.0f, (float)dy, 0.0f); glBegin(GL_QUADS); @@ -822,7 +822,7 @@ public: return; } - Device::draw_pixels(mem, y, w, h, width, height, transparent); + Device::draw_pixels(mem, y, w, h, dy, width, height, transparent); } void task_add(DeviceTask& task) @@ -849,9 +849,40 @@ public: } }; -Device *device_cuda_create(bool background) +Device *device_cuda_create(DeviceInfo& info, bool background) { - return new CUDADevice(background); + return new CUDADevice(info, background); +} + +void device_cuda_info(vector& devices) +{ + int count = 0; + + if(cuInit(0) != CUDA_SUCCESS) + return; + if(cuDeviceGetCount(&count) != CUDA_SUCCESS) + return; + + for(int num = 0; num < count; num++) { + char name[256]; + int attr; + + if(cuDeviceGetName(name, 256, num) != CUDA_SUCCESS) + continue; + + DeviceInfo info; + + info.type = DEVICE_CUDA; + info.description = string(name); + info.id = string_printf("CUDA_%d", num); + info.num = num; + + /* if device has a kernel timeout, assume it is used for display */ + if(cuDeviceGetAttribute(&attr, CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT, num) == CUDA_SUCCESS && attr == 1) + info.display_device = true; + + devices.push_back(info); + } } CCL_NAMESPACE_END diff --git a/intern/cycles/device/device_intern.h b/intern/cycles/device/device_intern.h index e098ac1f0e3..e3601aa8ad4 100644 --- a/intern/cycles/device/device_intern.h +++ b/intern/cycles/device/device_intern.h @@ -23,11 +23,17 @@ CCL_NAMESPACE_BEGIN class Device; -Device *device_cpu_create(int threads); -Device *device_opencl_create(bool background); -Device *device_cuda_create(bool background); -Device *device_network_create(const char *address); -Device *device_multi_create(bool background); +Device *device_cpu_create(DeviceInfo& info, int threads); +Device *device_opencl_create(DeviceInfo& info, bool background); +Device *device_cuda_create(DeviceInfo& info, bool background); +Device *device_network_create(DeviceInfo& info, const char *address); +Device *device_multi_create(DeviceInfo& info, bool background); + +void device_cpu_info(vector& devices); +void device_opencl_info(vector& devices); +void device_cuda_info(vector& devices); +void device_network_info(vector& devices); +void device_multi_info(vector& devices); CCL_NAMESPACE_END diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h index 516a6bd0739..3223ca91b9e 100644 --- a/intern/cycles/device/device_memory.h +++ b/intern/cycles/device/device_memory.h @@ -36,6 +36,12 @@ CCL_NAMESPACE_BEGIN +enum MemoryType { + MEM_READ_ONLY, + MEM_WRITE_ONLY, + MEM_READ_WRITE +}; + /* Supported Data Types */ enum DataType { diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp index 7f24e5789cc..f8b512f209c 100644 --- a/intern/cycles/device/device_multi.cpp +++ b/intern/cycles/device/device_multi.cpp @@ -44,32 +44,18 @@ public: list devices; device_ptr unique_ptr; - MultiDevice(bool background_) + MultiDevice(DeviceInfo& info, bool background_) : unique_ptr(1) { Device *device; + background = background_; - /* add CPU device */ - device = Device::create(DEVICE_CPU, background); - devices.push_back(SubDevice(device)); - -#ifdef WITH_CUDA - /* try to add GPU device */ - device = Device::create(DEVICE_CUDA, background); - if(device) { + foreach(DeviceInfo& subinfo, info.multi_devices) { + device = Device::create(subinfo, background); devices.push_back(SubDevice(device)); } - else -#endif - { -#ifdef WITH_OPENCL - device = Device::create(DEVICE_OPENCL, background); - if(device) - devices.push_back(SubDevice(device)); -#endif - } -#ifdef WITH_NETWORK +#if 0 //def WITH_NETWORK /* try to add network devices */ ServerDiscovery discovery(true); time_sleep(1.0); @@ -77,7 +63,7 @@ public: list servers = discovery.get_server_list(); foreach(string& server, servers) { - device = device_network_create(server.c_str()); + device = device_network_create(info, server.c_str()); if(device) devices.push_back(SubDevice(device)); } @@ -100,6 +86,19 @@ public: return true; } + const string& error_message() + { + foreach(SubDevice& sub, devices) { + if(sub.device->error_message() != "") { + if(error_msg == "") + error_msg = sub.device->error_message(); + break; + } + } + + return error_msg; + } + string description() { /* create map to find duplicate descriptions */ @@ -274,7 +273,7 @@ public: mem.device_pointer = tmp; } - void draw_pixels(device_memory& rgba, int y, int w, int h, int width, int height, bool transparent) + void draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent) { device_ptr tmp = rgba.device_pointer; int i = 0, sub_h = h/devices.size(); @@ -284,10 +283,11 @@ public: int sy = y + i*sub_h; int sh = (i == (int)devices.size() - 1)? h - sub_h*i: sub_h; int sheight = (i == (int)devices.size() - 1)? height - sub_height*i: sub_height; + int sdy = dy + i*sub_height; /* adjust math for w/width */ rgba.device_pointer = sub.ptr_map[tmp]; - sub.device->draw_pixels(rgba, sy, w, sh, width, sheight, transparent); + sub.device->draw_pixels(rgba, sy, w, sh, sdy, width, sheight, transparent); i++; } @@ -327,9 +327,103 @@ public: } }; -Device *device_multi_create(bool background) +Device *device_multi_create(DeviceInfo& info, bool background) { - return new MultiDevice(background); + return new MultiDevice(info, background); +} + +static void device_multi_add(vector& devices, DeviceType type, bool skip_display, const char *id_fmt, int num) +{ + DeviceInfo info; + + /* create map to find duplicate descriptions */ + map dupli_map; + map::iterator dt; + int num_added = 0, num_skipped = 0; + + foreach(DeviceInfo& subinfo, devices) { + if(subinfo.type == type) { + if(skip_display && subinfo.display_device) { + num_skipped++; + } + else { + string key = subinfo.description; + + if(dupli_map.find(key) == dupli_map.end()) + dupli_map[key] = 1; + else + dupli_map[key]++; + + info.multi_devices.push_back(subinfo); + if(subinfo.display_device) + info.display_device = true; + num_added++; + } + } + } + + if(num_added <= 1 || (skip_display && num_skipped == 0)) + return; + + /* generate string */ + stringstream desc; + vector last_tokens; + bool first = true; + + for(dt = dupli_map.begin(); dt != dupli_map.end(); dt++) { + if(!first) desc << " + "; + first = false; + + /* get name and count */ + string name = dt->first; + int count = dt->second; + + /* strip common prefixes */ + vector tokens; + string_split(tokens, dt->first); + + if(tokens.size() > 1) { + int i; + + for(i = 0; i < tokens.size() && i < last_tokens.size(); i++) + if(tokens[i] != last_tokens[i]) + break; + + name = ""; + for(; i < tokens.size(); i++) { + name += tokens[i]; + if(i != tokens.size() - 1) + name += " "; + } + } + + last_tokens = tokens; + + /* add */ + if(count > 1) + desc << name << " (" << count << "x)"; + else + desc << name; + } + + /* add info */ + info.type = DEVICE_MULTI; + info.description = desc.str(); + info.id = string_printf(id_fmt, num); + info.num = 0; + + devices.push_back(info); +} + +void device_multi_info(vector& devices) +{ + int num = 0; + device_multi_add(devices, DEVICE_CUDA, true, "CUDA_MULTI_%d", num++); + device_multi_add(devices, DEVICE_CUDA, false, "CUDA_MULTI_%d", num++); + + num = 0; + device_multi_add(devices, DEVICE_OPENCL, true, "OPENCL_MULTI_%d", num++); + device_multi_add(devices, DEVICE_OPENCL, false, "OPENCL_MULTI_%d", num++); } CCL_NAMESPACE_END diff --git a/intern/cycles/device/device_network.cpp b/intern/cycles/device/device_network.cpp index a5ad84831fc..4347d7eecd8 100644 --- a/intern/cycles/device/device_network.cpp +++ b/intern/cycles/device/device_network.cpp @@ -220,11 +220,22 @@ public: } }; -Device *device_network_create(const char *address) +Device *device_network_create(DeviceInfo& info, const char *address) { return new NetworkDevice(address); } +void device_network_info(vector& devices) +{ + DeviceInfo info; + + info.type = DEVICE_NETWORK; + info.description = "Network Device"; + info.id = "NETWORK"; + info.num = 0; + + devices.push_back(info); +} void Device::server_run() { diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index 6014dd0fdb7..41844d37f50 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -141,7 +141,7 @@ public: } } - OpenCLDevice(bool background_) + OpenCLDevice(DeviceInfo& info, bool background_) { background = background_; cpPlatform = NULL; @@ -153,10 +153,9 @@ public: null_mem = 0; device_initialized = false; - vector platform_ids; + /* setup platform */ cl_uint num_platforms; - /* setup device */ ciErr = clGetPlatformIDs(0, NULL, &num_platforms); if(opencl_error(ciErr)) return; @@ -166,14 +165,7 @@ public: return; } - platform_ids.resize(num_platforms); - ciErr = clGetPlatformIDs(num_platforms, &platform_ids[0], NULL); - if(opencl_error(ciErr)) - return; - - cpPlatform = platform_ids[0]; /* todo: pick specified platform && device */ - - ciErr = clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, 1, &cdDevice, NULL); + ciErr = clGetPlatformIDs(num_platforms, &cpPlatform, NULL); if(opencl_error(ciErr)) return; @@ -181,6 +173,29 @@ public: clGetPlatformInfo(cpPlatform, CL_PLATFORM_NAME, sizeof(name), &name, NULL); platform_name = name; + /* get devices */ + vector device_ids; + cl_uint num_devices; + + if(opencl_error(clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, 0, NULL, &num_devices))) + return; + + if(info.num > num_devices) { + if(num_devices == 0) + opencl_error("OpenCL: no devices found."); + else + opencl_error("OpenCL: specified device not found."); + return; + } + + device_ids.resize(num_devices); + + if(opencl_error(clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, num_devices, &device_ids[0], NULL))) + return; + + cdDevice = device_ids[info.num]; + + /* create context */ cxContext = clCreateContext(0, 1, &cdDevice, NULL, NULL, &ciErr); if(opencl_error(ciErr)) return; @@ -689,9 +704,50 @@ public: } }; -Device *device_opencl_create(bool background) +Device *device_opencl_create(DeviceInfo& info, bool background) { - return new OpenCLDevice(background); + return new OpenCLDevice(info, background); +} + +void device_opencl_info(vector& devices) +{ + vector device_ids; + cl_uint num_devices; + cl_platform_id platform_id; + cl_uint num_platforms; + + /* get devices */ + if(clGetPlatformIDs(0, NULL, &num_platforms) != CL_SUCCESS || num_platforms == 0) + return; + + if(clGetPlatformIDs(num_platforms, &platform_id, NULL) != CL_SUCCESS) + return; + + if(clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, 0, NULL, &num_devices) != CL_SUCCESS) + return; + + device_ids.resize(num_devices); + + if(clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, num_devices, &device_ids[0], NULL) != CL_SUCCESS) + return; + + /* add devices */ + for(int num = 0; num < num_devices; num++) { + cl_device_id device_id = device_ids[num]; + char name[1024]; + + if(clGetDeviceInfo(device_id, CL_DEVICE_NAME, sizeof(name), &name, NULL) != CL_SUCCESS) + continue; + + DeviceInfo info; + + info.type = DEVICE_OPENCL; + info.description = string(name); + info.id = string_printf("OPENCL_%d", num); + info.num = num; + + devices.push_back(info); + } } CCL_NAMESPACE_END diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp index 29141b25b59..dd78ccd8f32 100644 --- a/intern/cycles/render/buffers.cpp +++ b/intern/cycles/render/buffers.cpp @@ -183,7 +183,7 @@ void DisplayBuffer::draw(Device *device) if(transparent) draw_transparency_grid(); - device->draw_pixels(rgba, 0, draw_width, draw_height, params.width, params.height, transparent); + device->draw_pixels(rgba, 0, draw_width, draw_height, 0, params.width, params.height, transparent); } } diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index be2e493dc7f..4634e4de0d8 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -35,9 +35,9 @@ Session::Session(const SessionParams& params_) : params(params_), tile_manager(params.progressive, params.samples, params.tile_size, params.min_size) { - device_use_gl = ((params.device_type != DEVICE_CPU) && !params.background); + device_use_gl = ((params.device.type != DEVICE_CPU) && !params.background); - device = Device::create(params.device_type, params.background, params.threads); + device = Device::create(params.device, params.background, params.threads); buffers = new RenderBuffers(device); display = new DisplayBuffer(device); diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h index 89979b8c451..a662948c15b 100644 --- a/intern/cycles/render/session.h +++ b/intern/cycles/render/session.h @@ -40,7 +40,7 @@ class Scene; class SessionParams { public: - DeviceType device_type; + DeviceInfo device; bool background; string output_path; @@ -57,7 +57,6 @@ public: SessionParams() { - device_type = DEVICE_CPU; background = false; output_path = ""; @@ -74,7 +73,8 @@ public: } bool modified(const SessionParams& params) - { return !(device_type == params.device_type + { return !(device.type == params.device.type + && device.id == params.device.id && background == params.background && output_path == params.output_path /* && samples == params.samples */ diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp index 40833e5b08b..04e48d44029 100644 --- a/intern/cycles/render/tile.cpp +++ b/intern/cycles/render/tile.cpp @@ -71,8 +71,8 @@ void TileManager::set_tiles() int resolution = state.resolution; int image_w = max(1, params.width/resolution); int image_h = max(1, params.height/resolution); - int tile_w = (image_w + tile_size - 1)/tile_size; - int tile_h = (image_h + tile_size - 1)/tile_size; + int tile_w = (tile_size >= image_w)? 1: (image_w + tile_size - 1)/tile_size; + int tile_h = (tile_size >= image_h)? 1: (image_h + tile_size - 1)/tile_size; int sub_w = image_w/tile_w; int sub_h = image_h/tile_h; diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py index cf66baa03c4..57adfa1fa20 100644 --- a/release/scripts/startup/bl_ui/properties_object_constraint.py +++ b/release/scripts/startup/bl_ui/properties_object_constraint.py @@ -778,6 +778,10 @@ class ConstraintButtonsPanel(): layout.prop(con, "camera") + row = layout.row() + row.active = not con.use_3d_position + row.prop(con, "depth_object") + layout.operator("clip.constraint_to_fcurve") def CAMERA_SOLVER(self, context, layout, con): diff --git a/release/scripts/startup/bl_ui/space_logic.py b/release/scripts/startup/bl_ui/space_logic.py index 1fc58475ace..1d0e2221ce2 100644 --- a/release/scripts/startup/bl_ui/space_logic.py +++ b/release/scripts/startup/bl_ui/space_logic.py @@ -36,11 +36,34 @@ class LOGIC_PT_properties(Panel): ob = context.active_object game = ob.game + is_font = (ob.type == 'FONT') + + if is_font: + prop_index = game.properties.find("Text") + if prop_index != -1: + layout.operator("object.game_property_remove", text="Renove Text Game Property", icon='X').index = prop_index + row = layout.row() + sub = row.row() + sub.enabled = 0 + prop = game.properties[prop_index] + sub.prop(prop, "name", text="") + row.prop(prop, "type", text="") + # get the property from the body, not the game property + # note, dont do this - its too slow and body can potentually be a really long string. + # row.prop(ob.data, "body", text="") + row.label("See Font Object") + else: + props = layout.operator("object.game_property_new", text="Add Text Game Property", icon='ZOOMIN') + props.name = 'Text' + props.type = 'STRING' layout.operator("object.game_property_new", text="Add Game Property", icon='ZOOMIN') for i, prop in enumerate(game.properties): + if is_font and i == prop_index: + continue + box = layout.box() row = box.row() row.prop(prop, "name", text="") diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h index 57746f3a68f..fdf1d09559d 100644 --- a/source/blender/blenkernel/BKE_sound.h +++ b/source/blender/blenkernel/BKE_sound.h @@ -94,14 +94,17 @@ void sound_update_fps(struct Scene *scene); void sound_update_scene_listener(struct Scene *scene); void* sound_scene_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip); +void* sound_scene_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence); void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip); +void* sound_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence); void sound_remove_scene_sound(struct Scene *scene, void* handle); void sound_mute_scene_sound(void* handle, char mute); void sound_move_scene_sound(struct Scene *scene, void* handle, int startframe, int endframe, int frameskip); +void sound_move_scene_sound_defaults(struct Scene *scene, struct Sequence *sequence); void sound_update_scene_sound(void* handle, struct bSound* sound); diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 99b2d96ba10..029911d26d7 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -41,6 +41,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_editVert.h" +#include "BLI_kdopbvh.h" #include "BLI_utildefines.h" #include "DNA_armature_types.h" @@ -64,6 +65,7 @@ #include "BKE_anim.h" /* for the curve calculation part */ #include "BKE_armature.h" #include "BKE_blender.h" +#include "BKE_bvhutils.h" #include "BKE_camera.h" #include "BKE_constraint.h" #include "BKE_displist.h" @@ -3952,6 +3954,7 @@ static void followtrack_id_looper (bConstraint *con, ConstraintIDFunc func, void func(con, (ID**)&data->clip, userdata); func(con, (ID**)&data->camera, userdata); + func(con, (ID**)&data->depth_ob, userdata); } static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets)) @@ -3987,7 +3990,6 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase if (data->flag & FOLLOWTRACK_USE_3D_POSITION) { if (track->flag & TRACK_HAS_BUNDLE) { - MovieTracking *tracking= &clip->tracking; float obmat[4][4], mat[4][4]; copy_m4_m4(obmat, cob->matrix); @@ -4010,9 +4012,8 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]); } } - } + } else { - MovieClipUser user; MovieTrackingMarker *marker; float vec[3], disp[3], axis[3], mat[4][4]; float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp); @@ -4037,8 +4038,7 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase CameraParams params; float pos[2], rmat[4][4]; - user.framenr= scene->r.cfra; - marker= BKE_tracking_get_marker(track, user.framenr); + marker= BKE_tracking_get_marker(track, scene->r.cfra); add_v2_v2v2(pos, marker->pos, track->offset); @@ -4080,6 +4080,34 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase copy_v3_v3(cob->matrix[3], disp); } + + if(data->depth_ob && data->depth_ob->derivedFinal) { + Object *depth_ob= data->depth_ob; + BVHTreeFromMesh treeData= NULL_BVHTreeFromMesh; + BVHTreeRayHit hit; + float ray_start[3], ray_end[3], ray_nor[3], imat[4][4]; + int result; + + invert_m4_m4(imat, depth_ob->obmat); + + mul_v3_m4v3(ray_start, imat, camob->obmat[3]); + mul_v3_m4v3(ray_end, imat, cob->matrix[3]); + + sub_v3_v3v3(ray_nor, ray_end, ray_start); + + bvhtree_from_mesh_faces(&treeData, depth_ob->derivedFinal, 0.0f, 4, 6); + + hit.dist= FLT_MAX; + hit.index= -1; + + result= BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_nor, 0.0f, &hit, treeData.raycast_callback, &treeData); + + if(result != -1) { + mul_v3_m4v3(cob->matrix[3], depth_ob->obmat, hit.co); + } + + free_bvhtree_from_mesh(&treeData); + } } } } diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 3cb2f8ce738..762aaf3efc1 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -657,6 +657,11 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O if((data->clip || data->flag&FOLLOWTRACK_ACTIVECLIP) && data->track[0]) depends_on_camera= 1; + + if(data->depth_ob) { + node2 = dag_get_node(dag, data->depth_ob); + dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB, cti->name); + } } else if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) depends_on_camera= 1; diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index ab963f1e78c..4c78ab13874 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -860,7 +860,9 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip undist_marker.pos[1]/= height*aspy; } - tmpibuf= BKE_tracking_get_pattern_imbuf(ibuf, track, &undist_marker, 1, 1, scopes->track_pos, NULL); + /* NOTE: margin should be kept in sync with value from ui_draw_but_TRACKPREVIEW */ + tmpibuf= BKE_tracking_get_pattern_imbuf(ibuf, track, &undist_marker, 2 /* margin */, + 1 /* anchor */, scopes->track_pos, NULL); if(tmpibuf->rect_float) IMB_rect_from_float(tmpibuf); diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index cc4b8917a32..6da9199ddc4 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -3070,10 +3070,10 @@ void seq_sound_init(Scene *scene, Sequence *seq) } else { if(seq->sound) { - seq->scene_sound = sound_add_scene_sound(scene, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seq->scene_sound = sound_add_scene_sound_defaults(scene, seq); } if(seq->scene) { - sound_scene_add_scene_sound(scene, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + sound_scene_add_scene_sound_defaults(scene, seq); } } } @@ -3227,10 +3227,8 @@ void seq_update_sound_bounds_all(Scene *scene) void seq_update_sound_bounds(Scene* scene, Sequence *seq) { - if(seq->scene_sound) { - sound_move_scene_sound(scene, seq->scene_sound, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); - /* mute is set in seq_update_muting_recursive */ - } + sound_move_scene_sound_defaults(scene, seq); + /* mute is set in seq_update_muting_recursive */ } static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, int mute) @@ -3772,7 +3770,7 @@ static Sequence *seq_dupli(struct Scene *scene, struct Scene *scene_to, Sequence } else if(seq->type == SEQ_SCENE) { seqn->strip->stripdata = NULL; if(seq->scene_sound) - seqn->scene_sound = sound_scene_add_scene_sound(sce_audio, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seqn->scene_sound = sound_scene_add_scene_sound_defaults(sce_audio, seqn); } else if(seq->type == SEQ_MOVIE) { seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); @@ -3781,7 +3779,7 @@ static Sequence *seq_dupli(struct Scene *scene, struct Scene *scene_to, Sequence seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); if(seq->scene_sound) - seqn->scene_sound = sound_add_scene_sound(sce_audio, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seqn->scene_sound = sound_add_scene_sound_defaults(sce_audio, seqn); seqn->sound->id.us++; } else if(seq->type == SEQ_IMAGE) { diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index ceaba2502d9..80485c12b1a 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -449,6 +449,13 @@ void* sound_scene_add_scene_sound(struct Scene *scene, struct Sequence* sequence return NULL; } +void* sound_scene_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence) +{ + return sound_scene_add_scene_sound(scene, sequence, + sequence->startdisp, sequence->enddisp, + sequence->startofs + sequence->anim_startofs); +} + void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip) { void* handle = AUD_addSequence(scene->sound_scene, sequence->sound->playback_handle, startframe / FPS, endframe / FPS, frameskip / FPS); @@ -459,6 +466,13 @@ void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int return handle; } +void* sound_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence) +{ + return sound_add_scene_sound(scene, sequence, + sequence->startdisp, sequence->enddisp, + sequence->startofs + sequence->anim_startofs); +} + void sound_remove_scene_sound(struct Scene *scene, void* handle) { AUD_removeSequence(scene->sound_scene, handle); @@ -474,6 +488,13 @@ void sound_move_scene_sound(struct Scene *scene, void* handle, int startframe, i AUD_moveSequence(handle, startframe / FPS, endframe / FPS, frameskip / FPS); } +void sound_move_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence) +{ + sound_move_scene_sound(scene, sequence->scene_sound, + sequence->startdisp, sequence->enddisp, + sequence->startofs + sequence->anim_startofs); +} + void sound_update_scene_sound(void* handle, struct bSound* sound) { AUD_updateSequenceSound(handle, sound->playback_handle); @@ -781,11 +802,13 @@ void sound_create_scene(struct Scene *UNUSED(scene)) {} void sound_destroy_scene(struct Scene *UNUSED(scene)) {} void sound_mute_scene(struct Scene *UNUSED(scene), int UNUSED(muted)) {} void* sound_scene_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; } +void* sound_scene_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence)) { return NULL; } void* sound_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; } +void* sound_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence)) { return NULL; } void sound_remove_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle)) {} void sound_mute_scene_sound(void* UNUSED(handle), char UNUSED(mute)) {} void sound_move_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) {} -static void sound_start_play_scene(struct Scene *UNUSED(scene)) {} +void sound_move_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence)) {} void sound_play_scene(struct Scene *UNUSED(scene)) {} void sound_stop_scene(struct Scene *UNUSED(scene)) {} void sound_seek_scene(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene)) {} diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 7bfc7a8ef87..ff76fc14755 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -999,17 +999,24 @@ static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTracki if(anchored) add_v2_v2(mpos, track->offset); + if(pos) + zero_v2(pos); + x= mpos[0]*ibuf->x; y= mpos[1]*ibuf->y; - x1= x-(int)(-min[0]*ibuf->x); - y1= y-(int)(-min[1]*ibuf->y); - x2= x+(int)(max[0]*ibuf->x); - y2= y+(int)(max[1]*ibuf->y); + + w= (max[0]-min[0])*ibuf->x; + h= (max[1]-min[1])*ibuf->y; + + w= w|1; + h= h|1; + + x1= x-(int)(w/2.0f); + y1= y-(int)(h/2.0f); + x2= x+(int)(w/2.0f); + y2= y+(int)(h/2.0f); /* dimensions should be odd */ - w= (x2-x1)|1; - h= (y2-y1)|1; - tmpibuf= IMB_allocImBuf(w+margin*2, h+margin*2, 32, IB_rect); IMB_rectcpy(tmpibuf, ibuf, 0, 0, x1-margin, y1-margin, w+margin*2, h+margin*2); @@ -1023,13 +1030,17 @@ static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTracki origin[1]= y1-margin; } - if ((track->flag & TRACK_PREVIEW_GRAYSCALE) || - (track->flag & TRACK_DISABLE_RED) || - (track->flag & TRACK_DISABLE_GREEN) || - (track->flag & TRACK_DISABLE_BLUE) ) { + if((track->flag & TRACK_PREVIEW_GRAYSCALE) || + (track->flag & TRACK_DISABLE_RED) || + (track->flag & TRACK_DISABLE_GREEN) || + (track->flag & TRACK_DISABLE_BLUE)) + { disable_imbuf_channels(tmpibuf, track, 1 /* grayscale */); } + tmpibuf->ftype= PNG; + IMB_saveiff(tmpibuf, "/tmp/1.png", IB_rect); + return tmpibuf; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 122e66160d6..162d3102cb6 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -39,6 +39,7 @@ #include // for open #include // for strrchr strncmp strstr #include // for fabs +#include /* for va_start/end */ #ifndef WIN32 #include // for read close @@ -251,6 +252,31 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname); static void direct_link_modifiers(FileData *fd, ListBase *lb); static void convert_tface_mt(FileData *fd, Main *main); +/* this function ensures that reports are printed, + * in the case of libraray linking errors this is important! + * + * bit kludge but better then doubling up on prints, + * we could alternatively have a versions of a report function which foces printing - campbell + */ +static void BKE_reportf_wrap(ReportList *reports, ReportType type, const char *format, ...) +{ + char fixed_buf[1024]; /* should be long enough */ + + va_list args; + + va_start(args, format); + vsnprintf(fixed_buf, sizeof(fixed_buf), format, args); + va_end(args); + + fixed_buf[sizeof(fixed_buf) - 1] = '\0'; + + BKE_report(reports, type, fixed_buf); + + if(G.background==0) { + printf("%s\n", fixed_buf); + } +} + static OldNewMap *oldnewmap_new(void) { OldNewMap *onm= MEM_callocN(sizeof(*onm), "OldNewMap"); @@ -4194,8 +4220,9 @@ static void lib_link_object(FileData *fd, Main *main) ob= ob->id.next; } - if(warn) + if(warn) { BKE_report(fd->reports, RPT_WARNING, "Warning in console"); + } } @@ -4776,8 +4803,9 @@ static void lib_link_scene(FileData *fd, Main *main) base->object= newlibadr_us(fd, sce->id.lib, base->object); if(base->object==NULL) { - BKE_reportf(fd->reports, RPT_ERROR, "LIB ERROR: Object lost from scene:'%s\'\n", sce->id.name+2); - if(G.background==0) printf("LIB ERROR: base removed from scene:'%s\'\n", sce->id.name+2); + BKE_reportf_wrap(fd->reports, RPT_ERROR, + "LIB ERROR: Object lost from scene:'%s\'\n", + sce->id.name+2); BLI_remlink(&sce->base, base); if(base==sce->basact) sce->basact= NULL; MEM_freeN(base); @@ -4790,7 +4818,7 @@ static void lib_link_scene(FileData *fd, Main *main) if(seq->scene) { seq->scene= newlibadr(fd, sce->id.lib, seq->scene); if(seq->scene) { - seq->scene_sound = sound_scene_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seq->scene_sound = sound_scene_add_scene_sound_defaults(sce, seq); } } if(seq->scene_camera) seq->scene_camera= newlibadr(fd, sce->id.lib, seq->scene_camera); @@ -4802,7 +4830,7 @@ static void lib_link_scene(FileData *fd, Main *main) seq->sound= newlibadr(fd, sce->id.lib, seq->sound); if (seq->sound) { seq->sound->id.us++; - seq->scene_sound = sound_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seq->scene_sound = sound_add_scene_sound_defaults(sce, seq); } } seq->anim= NULL; @@ -5877,8 +5905,9 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main) for(newmain= fd->mainlist.first; newmain; newmain= newmain->next) { if(newmain->curlib) { if(BLI_path_cmp(newmain->curlib->filepath, lib->filepath) == 0) { - printf("Fixed error in file; multiple instances of lib:\n %s\n", lib->filepath); - BKE_reportf(fd->reports, RPT_WARNING, "Library '%s', '%s' had multiple instances, save and reload!", lib->name, lib->filepath); + BKE_reportf_wrap(fd->reports, RPT_WARNING, + "Library '%s', '%s' had multiple instances, save and reload!", + lib->name, lib->filepath); change_idid_adr(&fd->mainlist, fd, lib, newmain->curlib); // change_idid_adr_fd(fd, lib, newmain->curlib); @@ -12912,6 +12941,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } } + { + /* Warn the user if he is using ["Text"] properties for Font objects */ + Object *ob; + bProperty *prop; + + for (ob= main->object.first; ob; ob= ob->id.next) { + if (ob->type == OB_FONT) { + prop = get_ob_property(ob, "Text"); + if (prop) { + BKE_reportf_wrap(fd->reports, RPT_WARNING, + "Game property name conflict in object: \"%s\".\nText objects reserve the " + "[\"Text\"] game property to change their content through Logic Bricks.\n", + ob->id.name+2); + } + } + } + } } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ @@ -14364,8 +14410,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) if(fd==NULL) { /* printf and reports for now... its important users know this */ - BKE_reportf(basefd->reports, RPT_INFO, "read library: '%s', '%s'\n", mainptr->curlib->filepath, mainptr->curlib->name); - if(!G.background && basefd->reports) printf("read library: '%s', '%s'\n", mainptr->curlib->filepath, mainptr->curlib->name); + BKE_reportf_wrap(basefd->reports, RPT_INFO, + "read library: '%s', '%s'\n", + mainptr->curlib->filepath, mainptr->curlib->name); fd= blo_openblenderfile(mainptr->curlib->filepath, basefd->reports); @@ -14410,8 +14457,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) else mainptr->curlib->filedata= NULL; if (fd==NULL) { - BKE_reportf(basefd->reports, RPT_ERROR, "Can't find lib '%s'\n", mainptr->curlib->filepath); - if(!G.background && basefd->reports) printf("ERROR: can't find lib %s \n", mainptr->curlib->filepath); + BKE_reportf_wrap(basefd->reports, RPT_ERROR, + "Can't find lib '%s'\n", + mainptr->curlib->filepath); } } if(fd) { @@ -14428,8 +14476,10 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) append_id_part(fd, mainptr, id, &realid); if (!realid) { - BKE_reportf(fd->reports, RPT_ERROR, "LIB ERROR: %s:'%s' missing from '%s'\n", BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); - if(!G.background && basefd->reports) printf("LIB ERROR: %s:'%s' missing from '%s'\n", BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); + BKE_reportf_wrap(fd->reports, RPT_ERROR, + "LIB ERROR: %s:'%s' missing from '%s'\n", + BKE_idcode_to_name(GS(id->name)), + id->name+2, mainptr->curlib->filepath); } change_idid_adr(mainlist, basefd, id, realid); @@ -14465,13 +14515,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) ID *idn= id->next; if(id->flag & LIB_READ) { BLI_remlink(lbarray[a], id); - BKE_reportf(basefd->reports, RPT_ERROR, - "LIB ERROR: %s:'%s' unread libblock missing from '%s'\n", - BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); - if (!G.background && basefd->reports) { - printf("LIB ERROR: %s:'%s' unread libblock missing from '%s'\n", - BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); - } + BKE_reportf_wrap(basefd->reports, RPT_ERROR, + "LIB ERROR: %s:'%s' unread libblock missing from '%s'\n", + BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); change_idid_adr(mainlist, basefd, id, NULL); MEM_freeN(id); diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 6ebb67af67a..1f1228a9bc5 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1465,21 +1465,16 @@ static ImBuf *scale_trackpreview_ibuf(ImBuf *ibuf, float zoomx, float zoomy) { ImBuf *scaleibuf; int x, y, w= ibuf->x*zoomx, h= ibuf->y*zoomy; - const float max_x= ibuf->x-1.0f; - const float max_y= ibuf->y-1.0f; const float scalex= 1.0f/zoomx; const float scaley= 1.0f/zoomy; scaleibuf= IMB_allocImBuf(w, h, 32, IB_rect); - for(y= 0; yy; y++) { - for (x= 0; xx; x++) { + for(y= 0; ytrack_preview) { - int a, off_x, off_y; - float zoomx, zoomy; + /* additional margin around image */ + /* NOTE: should be kept in sync with value from BKE_movieclip_update_scopes */ + const int margin= 2; + float zoomx, zoomy, track_pos[2], off_x, off_y; + int a; ImBuf *drawibuf; glPushMatrix(); + track_pos[0]= scopes->track_pos[0]-margin; + track_pos[1]= scopes->track_pos[1]-margin; + /* draw content of pattern area */ glScissor(ar->winrct.xmin+rect.xmin, ar->winrct.ymin+rect.ymin, scissor[2], scissor[3]); - zoomx= (rect.xmax-rect.xmin) / (scopes->track_preview->x-2.0f); - zoomy= (rect.ymax-rect.ymin) / (scopes->track_preview->y-2.0f); + zoomx= (rect.xmax-rect.xmin) / (scopes->track_preview->x-2*margin); + zoomy= (rect.ymax-rect.ymin) / (scopes->track_preview->y-2*margin); - off_x= ((int)scopes->track_pos[0]-scopes->track_pos[0]-0.5f)*zoomx; - off_y= ((int)scopes->track_pos[1]-scopes->track_pos[1]-0.5f)*zoomy; + off_x= ((int)track_pos[0]-track_pos[0]+0.5)*zoomx; + off_y= ((int)track_pos[1]-track_pos[1]+0.5)*zoomy; drawibuf= scale_trackpreview_ibuf(scopes->track_preview, zoomx, zoomy); - glaDrawPixelsSafe(off_x+rect.xmin, off_y+rect.ymin, rect.xmax-rect.xmin+1.f-off_x, rect.ymax-rect.ymin+1.f-off_y, drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect); - + glaDrawPixelsSafe(off_x+rect.xmin-zoomx*(margin-0.5f), off_y+rect.ymin-zoomy*(margin-0.5f), + rect.xmax-rect.xmin+2+(int)(zoomx*(margin-0.5f)-off_x), + rect.ymax-rect.ymin+2+(int)(zoomy*(margin-0.5f)-off_y), + drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect); IMB_freeImBuf(drawibuf); /* draw cross for pizel position */ - glTranslatef(off_x+rect.xmin+scopes->track_pos[0]*zoomx, off_y+rect.ymin+scopes->track_pos[1]*zoomy, 0.f); + glTranslatef(off_x+rect.xmin+track_pos[0]*zoomx, off_y+rect.ymin+track_pos[1]*zoomy, 0.f); glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin+rect.ymin, rect.xmax-rect.xmin, rect.ymax-rect.ymin); for(a= 0; a< 2; a++) { diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index b3e5232cfdc..fcb6e3c3610 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1937,16 +1937,21 @@ void ED_object_toggle_modes(bContext *C, int mode) /************************ Game Properties ***********************/ -static int game_property_new(bContext *C, wmOperator *UNUSED(op)) +static int game_property_new(bContext *C, wmOperator *op) { Object *ob= CTX_data_active_object(C); bProperty *prop; + char name[32]; + int type= RNA_enum_get(op->ptr, "type"); - if(!ob) - return OPERATOR_CANCELLED; - - prop= new_property(PROP_FLOAT); + prop= new_property(type); BLI_addtail(&ob->prop, prop); + + RNA_string_get(op->ptr, "name", name); + if (name[0] != '\0') { + BLI_strncpy(prop->name, name, sizeof(prop->name)); + } + unique_property(NULL, prop, 0); // make_unique_prop_names(prop->name); WM_event_add_notifier(C, NC_LOGIC, NULL); @@ -1967,6 +1972,9 @@ void OBJECT_OT_game_property_new(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", gameproperty_type_items, 2, "Type", "Type of game property to add"); + RNA_def_string(ot->srna, "name", "", 32, "Name", "Name of the game property to add"); } static int game_property_remove(bContext *C, wmOperator *op) diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 5fd3d3b45d6..56c2e0ee4d1 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2711,8 +2711,8 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op) calc_sequence(scene, seq_act); calc_sequence(scene, seq_other); - if(seq_act->sound) sound_add_scene_sound(scene, seq_act, seq_act->startdisp, seq_act->enddisp, seq_act->startofs + seq_act->anim_startofs); - if(seq_other->sound) sound_add_scene_sound(scene, seq_other, seq_other->startdisp, seq_other->enddisp, seq_other->startofs + seq_other->anim_startofs); + if(seq_act->sound) sound_add_scene_sound_defaults(scene, seq_act); + if(seq_other->sound) sound_add_scene_sound_defaults(scene, seq_other); WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 8fdbde60bab..c829d5be294 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -417,6 +417,7 @@ typedef struct bFollowTrackConstraint { int flag, pad; char object[24]; struct Object *camera; + struct Object *depth_ob; } bFollowTrackConstraint; /* Camera Solver constraints */ diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index 91e5d06fe5e..72917600d05 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -104,6 +104,8 @@ extern EnumPropertyItem property_type_items[]; extern EnumPropertyItem property_subtype_items[]; extern EnumPropertyItem property_unit_items[]; +extern EnumPropertyItem gameproperty_type_items[]; + extern EnumPropertyItem viewport_shade_items[]; extern EnumPropertyItem nodetree_type_items[]; diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 6439d22e808..3258b8c3dcb 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -358,6 +358,34 @@ static void rna_Constraint_followTrack_camera_set(PointerRNA *ptr, PointerRNA va } } +static void rna_Constraint_followTrack_depthObject_set(PointerRNA *ptr, PointerRNA value) +{ + bConstraint *con= (bConstraint*)ptr->data; + bFollowTrackConstraint *data= (bFollowTrackConstraint*)con->data; + Object *ob= (Object*)value.data; + + if (ob) { + if (ob->type == OB_MESH && ob != (Object*)ptr->id.data) { + data->depth_ob= ob; + } + } else { + data->depth_ob= NULL; + } +} + +static int rna_Constraint_followTrack_depthObject_poll(PointerRNA *ptr, PointerRNA value) +{ + Object *ob= (Object*)value.data; + + if(ob) { + if (ob->type == OB_MESH && ob != (Object*)ptr->id.data) { + return 1; + } + } + + return 0; +} + static void rna_Constraint_objectSolver_camera_set(PointerRNA *ptr, PointerRNA value) { bConstraint *con= (bConstraint*)ptr->data; @@ -2126,6 +2154,14 @@ static void rna_def_constraint_follow_track(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); RNA_def_property_pointer_funcs(prop, NULL, "rna_Constraint_followTrack_camera_set", NULL, "rna_Constraint_cameraObject_poll"); + + /* depth object */ + prop= RNA_def_property(srna, "depth_object", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "depth_ob"); + RNA_def_property_ui_text(prop, "Depth Object", "Object used to define depth in camera space by projecting onto surface of this object"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_Constraint_followTrack_depthObject_set", NULL, "rna_Constraint_followTrack_depthObject_poll"); } static void rna_def_constraint_camera_solver(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_property.c b/source/blender/makesrna/intern/rna_property.c index e8ef61b6d74..dfdc175d18b 100644 --- a/source/blender/makesrna/intern/rna_property.c +++ b/source/blender/makesrna/intern/rna_property.c @@ -35,6 +35,15 @@ #include "WM_types.h" +EnumPropertyItem gameproperty_type_items[] ={ + {GPROP_BOOL, "BOOL", 0, "Boolean", "Boolean Property"}, + {GPROP_INT, "INT", 0, "Integer", "Integer Property"}, + {GPROP_FLOAT, "FLOAT", 0, "Float", "Floating-Point Property"}, + {GPROP_STRING, "STRING", 0, "String", "String Property"}, + {GPROP_TIME, "TIMER", 0, "Timer", "Timer Property"}, + {0, NULL, 0, NULL, NULL}}; + + #ifdef RNA_RUNTIME #include "BKE_property.h" @@ -98,14 +107,6 @@ void RNA_def_gameproperty(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem gameproperty_type_items[] ={ - {GPROP_BOOL, "BOOL", 0, "Boolean", "Boolean Property"}, - {GPROP_INT, "INT", 0, "Integer", "Integer Property"}, - {GPROP_FLOAT, "FLOAT", 0, "Float", "Floating-Point Property"}, - {GPROP_STRING, "STRING", 0, "String", "String Property"}, - {GPROP_TIME, "TIMER", 0, "Timer", "Timer Property"}, - {0, NULL, 0, NULL, NULL}}; - /* Base Struct for GameProperty */ srna= RNA_def_struct(brna, "GameProperty", NULL); RNA_def_struct_ui_text(srna , "Game Property", "Game engine user defined object property"); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index d911fcb99b1..9dfbe64e905 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -4073,7 +4073,6 @@ static PyObject *pyrna_struct_as_pointer(BPy_StructRNA *self) return PyLong_FromVoidPtr(self->ptr.data); } -/* TODO, get (string, lib) pair */ PyDoc_STRVAR(pyrna_prop_collection_get_doc, ".. method:: get(key, default=None)\n" "\n" @@ -4120,6 +4119,51 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args return Py_INCREF(def), def; } +PyDoc_STRVAR(pyrna_prop_collection_find_doc, +".. method:: find(key)\n" +"\n" +" Returns the index of a key in a collection or -1 when not found\n" +" (matches pythons string find function of the same name).\n" +"\n" +" :arg key: The identifier for the collection member.\n" +" :type key: string\n" +" :return: index of the key.\n" +" :rtype: int\n" +); +static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key_ob) +{ + Py_ssize_t key_len_ssize_t; + const char *key = _PyUnicode_AsStringAndSize(key_ob, &key_len_ssize_t); + const int key_len = (int)key_len_ssize_t; /* comare with same type */ + + char name[256], *nameptr; + int namelen; + int i = 0; + int index = -1; + + PYRNA_PROP_CHECK_OBJ(self); + + RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { + nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); + + if (nameptr) { + if ((key_len == namelen) && memcmp(nameptr, key, key_len) == 0) { + index = i; + break; + } + + if (name != nameptr) { + MEM_freeN(nameptr); + } + } + + i++; + } + RNA_PROP_END; + + return PyLong_FromSsize_t(index); +} + static void foreach_attr_type( BPy_PropertyRNA *self, const char *attr, /* values to assign */ RawPropertyType *raw_type, int *attr_tot, int *attr_signed) @@ -4503,6 +4547,7 @@ static struct PyMethodDef pyrna_prop_collection_methods[] = { {"values", (PyCFunction)pyrna_prop_collection_values, METH_NOARGS, pyrna_prop_collection_values_doc}, {"get", (PyCFunction)pyrna_prop_collection_get, METH_VARARGS, pyrna_prop_collection_get_doc}, + {"find", (PyCFunction)pyrna_prop_collection_find, METH_O, pyrna_prop_collection_find_doc}, {NULL, NULL, 0, NULL} }; diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 555d5c12a86..0068407a7df 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -2538,9 +2538,17 @@ static void do_render_seq(Render * re) recurs_depth++; - context = seq_new_render_data(re->main, re->scene, - re->result->rectx, re->result->recty, - 100); + if((re->r.mode & R_BORDER) && (re->r.mode & R_CROP)==0) { + /* if border rendering is used and cropping is disabled, final buffer should + be as large as the whole frame */ + context = seq_new_render_data(re->main, re->scene, + re->winx, re->winy, + 100); + } else { + context = seq_new_render_data(re->main, re->scene, + re->result->rectx, re->result->recty, + 100); + } ibuf = give_ibuf_seq(context, cfra, 0); diff --git a/source/creator/creator.c b/source/creator/creator.c index 27bf95c3e80..1eac930a691 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -955,6 +955,12 @@ static int load_file(int UNUSED(argc), const char **argv, void *data) /* Make the path absolute because its needed for relative linked blends to be found */ char filename[FILE_MAX]; + + /* note, we could skip these, but so far we always tried to load these files */ + if (argv[0][0] == '-') { + fprintf(stderr, "unknown argument, loading as file: %s\n", argv[0]); + } + BLI_strncpy(filename, argv[0], sizeof(filename)); BLI_path_cwd(filename); diff --git a/source/gameengine/Converter/KX_ConvertProperties.cpp b/source/gameengine/Converter/KX_ConvertProperties.cpp index 7a574276eb4..8eea39c4956 100644 --- a/source/gameengine/Converter/KX_ConvertProperties.cpp +++ b/source/gameengine/Converter/KX_ConvertProperties.cpp @@ -48,11 +48,21 @@ #include "SCA_TimeEventManager.h" #include "SCA_IScene.h" +#include "KX_FontObject.h" +#include "DNA_curve_types.h" + /* This little block needed for linking to Blender... */ #ifdef WIN32 #include "BLI_winstuff.h" #endif +extern "C" { + #include "BKE_property.h" +} + +/* prototype */ +void BL_ConvertTextProperty(Object* object, KX_FontObject* fontobj,SCA_TimeEventManager* timemgr,SCA_IScene* scene, bool isInActiveLayer); + void BL_ConvertProperties(Object* object,KX_GameObject* gameobj,SCA_TimeEventManager* timemgr,SCA_IScene* scene, bool isInActiveLayer) { @@ -155,4 +165,80 @@ void BL_ConvertProperties(Object* object,KX_GameObject* gameobj,SCA_TimeEventMan // reserve name for object state scene->AddDebugProperty(gameobj,STR_String("__state__")); } + + /* Font Objects need to 'copy' the Font Object data body to ["Text"] */ + if (object->type == OB_FONT) + { + BL_ConvertTextProperty(object, (KX_FontObject *)gameobj, timemgr, scene, isInActiveLayer); + } } + +void BL_ConvertTextProperty(Object* object, KX_FontObject* fontobj,SCA_TimeEventManager* timemgr,SCA_IScene* scene, bool isInActiveLayer) +{ + CValue* tprop = fontobj->GetProperty("Text"); + if(!tprop) return; + bProperty* prop = get_ob_property(object, "Text"); + if(!prop) return; + + Curve *curve = static_cast(object->data); + STR_String str = curve->str; + CValue* propval = NULL; + + switch(prop->type) { + case GPROP_BOOL: + { + int value = atoi(str); + propval = new CBoolValue((bool)(value != 0)); + tprop->SetValue(propval); + break; + } + case GPROP_INT: + { + int value = atoi(str); + propval = new CIntValue(value); + tprop->SetValue(propval); + break; + } + case GPROP_FLOAT: + { + float floatprop = atof(str); + propval = new CFloatValue(floatprop); + tprop->SetValue(propval); + break; + } + case GPROP_STRING: + { + propval = new CStringValue(str, ""); + tprop->SetValue(propval); + break; + } + case GPROP_TIME: + { + float floatprop = atof(str); + + CValue* timeval = new CFloatValue(floatprop); + // set a subproperty called 'timer' so that + // we can register the replica of this property + // at the time a game object is replicated (AddObjectActuator triggers this) + CValue *bval = new CBoolValue(true); + timeval->SetProperty("timer",bval); + bval->Release(); + if (isInActiveLayer) + { + timemgr->AddTimeProperty(timeval); + } + + propval = timeval; + tprop->SetValue(timeval); + } + default: + { + // todo make an assert etc. + } + } + + if (propval) { + propval->Release(); + } +} + diff --git a/source/gameengine/Ketsji/KX_FontObject.cpp b/source/gameengine/Ketsji/KX_FontObject.cpp index 5a4d9065605..8cce9471587 100644 --- a/source/gameengine/Ketsji/KX_FontObject.cpp +++ b/source/gameengine/Ketsji/KX_FontObject.cpp @@ -34,6 +34,14 @@ #include "KX_Scene.h" #include "KX_PythonInit.h" #include "BLI_math.h" +#include "StringValue.h" + +/* paths needed for font load */ +#include "BLI_blenlib.h" +#include "BKE_global.h" +#include "BKE_font.h" +#include "BKE_main.h" +#include "DNA_packedFile_types.h" extern "C" { #include "BLF_api.h" @@ -41,6 +49,9 @@ extern "C" { #define BGE_FONT_RES 100 +/* proptotype */ +int GetFontId(VFont *font); + std::vector split_string(STR_String str) { std::vector text = std::vector(); @@ -61,6 +72,7 @@ std::vector split_string(STR_String str) return text; } + KX_FontObject::KX_FontObject( void* sgReplicationInfo, SG_Callbacks callbacks, RAS_IRenderTools* rendertools, @@ -76,20 +88,9 @@ KX_FontObject::KX_FontObject( void* sgReplicationInfo, m_fsize = text->fsize; m_line_spacing = text->linedist; m_offset = MT_Vector3(text->xof, text->yof, 0); - - /* FO_BUILTIN_NAME != "default" */ - /* I hope at some point Blender (2.5x) can have a single font */ - /* with unicode support for ui and OB_FONT */ - /* once we have packed working we can load the FO_BUILTIN_NAME font */ - const char* filepath = text->vfont->name; - if (strcmp(FO_BUILTIN_NAME, filepath) == 0) - filepath = "default"; - - /* XXX - if it's packed it will not work. waiting for bdiego (Diego) fix for that. */ - m_fontid = BLF_load(filepath); - if (m_fontid == -1) - m_fontid = BLF_load("default"); - + + m_fontid = GetFontId(text->vfont); + /* initialize the color with the object color and store it in the KX_Object class This is a workaround waiting for the fix: [#25487] BGE: Object Color only works when it has a keyed frame */ @@ -115,6 +116,50 @@ void KX_FontObject::ProcessReplica() KX_GetActiveScene()->AddFont(this); } +int GetFontId (VFont *font) { + PackedFile *packedfile=NULL; + int fontid = -1; + + if (font->packedfile) { + packedfile= font->packedfile; + fontid= BLF_load_mem(font->name, (unsigned char*)packedfile->data, packedfile->size); + + if (fontid == -1) { + printf("ERROR: packed font \"%s\" could not be loaded.\n", font->name); + fontid = BLF_load("default"); + } + return fontid; + } + + /* once we have packed working we can load the FO_BUILTIN_NAME font */ + const char *filepath = font->name; + if (strcmp(FO_BUILTIN_NAME, filepath) == 0) { + fontid = BLF_load("default"); + + /* XXX the following code is supposed to work (after you add get_builtin_packedfile to BKE_font.h ) + * unfortunately it's crashing on blf_glyph.c:173 because gc->max_glyph_width is 0 + */ + // packedfile=get_builtin_packedfile(); + // fontid= BLF_load_mem(font->name, (unsigned char*)packedfile->data, packedfile->size); + // return fontid; + + return BLF_load("default"); + } + + /* convert from absolute to relative */ + char expanded[256]; // font names can be bigger than FILE_MAX (240) + BLI_strncpy(expanded, filepath, 256); + BLI_path_abs(expanded, G.main->name); + + fontid = BLF_load(expanded); + + /* fallback */ + if (fontid == -1) + fontid = BLF_load("default"); + + return fontid; +} + void KX_FontObject::DrawText() { /* Allow for some logic brick control */ @@ -224,7 +269,18 @@ int KX_FontObject::pyattr_set_text(void *self_v, const KX_PYATTRIBUTE_DEF *attrd if(!PyUnicode_Check(value)) return PY_SET_ATTR_FAIL; char* chars = _PyUnicode_AsString(value); - self->m_text = split_string(STR_String(chars)); + + /* Allow for some logic brick control */ + CValue* tprop = self->GetProperty("Text"); + if(tprop) { + CValue *newstringprop = new CStringValue(STR_String(chars), "Text"); + self->SetProperty("Text", newstringprop); + newstringprop->Release(); + } + else { + self->m_text = split_string(STR_String(chars)); + } + return PY_SET_ATTR_SUCCESS; }