diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2011-12-20 21:24:20 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2011-12-20 21:24:20 +0400 |
commit | 921b2ee2d44ed87363198d7bfa89bb7116b0818b (patch) | |
tree | 3e04fd777b5c32f4814357ff9d18289ee072c962 | |
parent | 1dc74acc123721d366e3628663ed029db5761e4d (diff) | |
parent | 738fdc7b6f43c3e1e838bd4239b36340fa4c2e0f (diff) |
Merging r42723 through r42769 from trunk into soc-2011-tomato
99 files changed, 1699 insertions, 1257 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index af111c27f4f..371b7eb0896 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -723,11 +723,7 @@ elseif(WIN32) set(GETTEXT_LIBRARIES gnu_gettext) endif() - if(CMAKE_CL_64) - set(PNG_LIBRARIES libpng) - else() - set(PNG_LIBRARIES libpng_st) - endif() + set(PNG_LIBRARIES libpng) set(JPEG_LIBRARIES libjpeg) set(PNG "${LIBDIR}/png") diff --git a/SConstruct b/SConstruct index d8db597d1c6..1a038278404 100644 --- a/SConstruct +++ b/SConstruct @@ -726,10 +726,6 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'): # For MinGW and linuxcross static linking will be used dllsources += ['${LCGDIR}/gettext/lib/gnu_gettext.dll'] - #currently win64-vc doesn't appear to have libpng.dll - if env['OURPLATFORM'] != 'win64-vc': - dllsources += ['${BF_PNG_LIBPATH}/libpng.dll'] - dllsources += ['${BF_ZLIB_LIBPATH}/zlib.dll'] # Used when linking to libtiff was dynamic # keep it here until compilation on all platform would be ok diff --git a/build_files/scons/config/win32-mingw-config.py b/build_files/scons/config/win32-mingw-config.py index bc2bbbba07a..6e65e093a46 100644 --- a/build_files/scons/config/win32-mingw-config.py +++ b/build_files/scons/config/win32-mingw-config.py @@ -64,7 +64,7 @@ BF_JPEG_LIB = 'liblibjpeg' BF_JPEG_LIBPATH = '${BF_JPEG}/lib' WITH_BF_PNG = True -BF_PNG = LIBDIR + 'gcc/png' +BF_PNG = LIBDIR + '/gcc/png' BF_PNG_INC = '${BF_PNG}/include' BF_PNG_LIB = 'png' BF_PNG_LIBPATH = '${BF_PNG}/lib' diff --git a/build_files/scons/config/win32-vc-config.py b/build_files/scons/config/win32-vc-config.py index a2e3d11c244..53ac9937885 100644 --- a/build_files/scons/config/win32-vc-config.py +++ b/build_files/scons/config/win32-vc-config.py @@ -72,7 +72,7 @@ BF_JPEG_LIBPATH = '${BF_JPEG}/lib' WITH_BF_PNG = True BF_PNG = LIBDIR + '/png' BF_PNG_INC = '${BF_PNG}/include' -BF_PNG_LIB = 'libpng_st' +BF_PNG_LIB = 'libpng' BF_PNG_LIBPATH = '${BF_PNG}/lib' WITH_BF_TIFF = True diff --git a/intern/cycles/app/cycles_test.cpp b/intern/cycles/app/cycles_test.cpp index 27e53ded6db..83816727404 100644 --- a/intern/cycles/app/cycles_test.cpp +++ b/intern/cycles/app/cycles_test.cpp @@ -82,10 +82,21 @@ static void session_print_status() session_print(status); } +static BufferParams session_buffer_params() +{ + BufferParams buffer_params; + buffer_params.width = options.width; + buffer_params.height = options.height; + buffer_params.full_width = options.width; + buffer_params.full_height = options.height; + + return buffer_params; +} + static void session_init() { options.session = new Session(options.session_params); - options.session->reset(options.width, options.height, options.session_params.samples); + options.session->reset(session_buffer_params(), options.session_params.samples); options.session->scene = options.scene; if(options.session_params.background && !options.quiet) @@ -151,7 +162,7 @@ static void display_info(Progress& progress) static void display() { - options.session->draw(options.width, options.height); + options.session->draw(session_buffer_params()); display_info(options.session->progress); } @@ -162,13 +173,13 @@ static void resize(int width, int height) options.height= height; if(options.session) - options.session->reset(options.width, options.height, options.session_params.samples); + options.session->reset(session_buffer_params(), options.session_params.samples); } void keyboard(unsigned char key) { if(key == 'r') - options.session->reset(options.width, options.height, options.session_params.samples); + options.session->reset(session_buffer_params(), options.session_params.samples); else if(key == 27) // escape options.session->progress.set_cancel("Cancelled"); } diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index 2fedd2c0afa..60b77b23f25 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -62,11 +62,7 @@ def render(engine): def update(engine, data, scene): import bcycles - if scene.render.use_border: - engine.report({'ERROR'}, "Border rendering not supported yet") - free(engine) - else: - bcycles.sync(engine.session) + bcycles.sync(engine.session) def draw(engine, region, v3d, rv3d): diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index 2a2c2a7c643..9777de14b1e 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -207,6 +207,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int /* transform, note the blender camera points along the negative z-axis */ cam->matrix = bcam->matrix * transform_scale(1.0f, 1.0f, -1.0f); + cam->matrix = transform_clear_scale(cam->matrix); /* set update flag */ if(cam->modified(prevcam)) @@ -286,5 +287,29 @@ void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int blender_camera_sync(scene->camera, &bcam, width, height); } +BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, BL::RegionView3D b_rv3d, int width, int height) +{ + BufferParams params; + + params.full_width = width; + params.full_height = height; + + /* border render */ + BL::RenderSettings r = b_scene.render(); + + if(!b_rv3d && r.use_border()) { + params.full_x = r.border_min_x()*width; + params.full_y = r.border_min_y()*height; + params.width = (int)(r.border_max_x()*width) - params.full_x; + params.height = (int)(r.border_max_y()*height) - params.full_y; + } + else { + params.width = width; + params.height = height; + } + + return params; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 4433b1e24f9..1803dd36beb 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -100,7 +100,9 @@ void BlenderSession::create_session() session->set_pause(BlenderSync::get_session_pause(b_scene, background)); /* start rendering */ - session->reset(width, height, session_params.samples); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + + session->reset(buffer_params, session_params.samples); session->start(); } @@ -135,7 +137,10 @@ void BlenderSession::write_render_result() if(!pixels) return; - struct RenderResult *rrp = RE_engine_begin_result((RenderEngine*)b_engine.ptr.data, 0, 0, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + int w = buffer_params.width, h = buffer_params.height; + + struct RenderResult *rrp = RE_engine_begin_result((RenderEngine*)b_engine.ptr.data, 0, 0, w, h); PointerRNA rrptr; RNA_pointer_create(NULL, &RNA_RenderResult, rrp, &rrptr); BL::RenderResult rr(rrptr); @@ -188,8 +193,10 @@ void BlenderSession::synchronize() session->scene->mutex.unlock(); /* reset if needed */ - if(scene->need_reset()) - session->reset(width, height, session_params.samples); + if(scene->need_reset()) { + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + session->reset(buffer_params, session_params.samples); + } } bool BlenderSession::draw(int w, int h) @@ -225,7 +232,9 @@ bool BlenderSession::draw(int w, int h) /* reset if requested */ if(reset) { SessionParams session_params = BlenderSync::get_session_params(b_scene, background); - session->reset(width, height, session_params.samples); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + + session->reset(buffer_params, session_params.samples); } } @@ -233,7 +242,9 @@ bool BlenderSession::draw(int w, int h) update_status_progress(); /* draw */ - return !session->draw(width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + + return !session->draw(buffer_params); } void BlenderSession::get_status(string& status, string& substatus) diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 83c7f70fd59..824904cd81d 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -62,6 +62,7 @@ public: static SceneParams get_scene_params(BL::Scene b_scene, bool background); static SessionParams get_session_params(BL::Scene b_scene, bool background); static bool get_session_pause(BL::Scene b_scene, bool background); + static BufferParams get_buffer_params(BL::Scene b_scene, BL::RegionView3D b_rv3d, int width, int height); private: /* sync */ diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index 5b87b11b6b8..be6a3f144ed 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -60,6 +60,7 @@ public: device_ptr buffer; int sample; int resolution; + int offset, stride; device_ptr displace_input; device_ptr displace_offset; diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp index 990b7cb94b0..a45a4fb69f6 100644 --- a/intern/cycles/device/device_cpu.cpp +++ b/intern/cycles/device/device_cpu.cpp @@ -162,7 +162,8 @@ public: if(system_cpu_support_optimized()) { for(int y = task.y; y < task.y + task.h; y++) { for(int x = task.x; x < task.x + task.w; x++) - kernel_cpu_optimized_path_trace(kg, (float4*)task.buffer, (unsigned int*)task.rng_state, task.sample, x, y); + kernel_cpu_optimized_path_trace(kg, (float4*)task.buffer, (unsigned int*)task.rng_state, + task.sample, x, y, task.offset, task.stride); if(tasks.worker_cancel()) break; @@ -173,7 +174,8 @@ public: { for(int y = task.y; y < task.y + task.h; y++) { for(int x = task.x; x < task.x + task.w; x++) - kernel_cpu_path_trace(kg, (float4*)task.buffer, (unsigned int*)task.rng_state, task.sample, x, y); + kernel_cpu_path_trace(kg, (float4*)task.buffer, (unsigned int*)task.rng_state, + task.sample, x, y, task.offset, task.stride); if(tasks.worker_cancel()) break; @@ -192,14 +194,16 @@ public: if(system_cpu_support_optimized()) { for(int y = task.y; y < task.y + task.h; y++) for(int x = task.x; x < task.x + task.w; x++) - kernel_cpu_optimized_tonemap(kg, (uchar4*)task.rgba, (float4*)task.buffer, task.sample, task.resolution, x, y); + kernel_cpu_optimized_tonemap(kg, (uchar4*)task.rgba, (float4*)task.buffer, + task.sample, task.resolution, x, y, task.offset, task.stride); } else #endif { for(int y = task.y; y < task.y + task.h; y++) for(int x = task.x; x < task.x + task.w; x++) - kernel_cpu_tonemap(kg, (uchar4*)task.rgba, (float4*)task.buffer, task.sample, task.resolution, x, y); + kernel_cpu_tonemap(kg, (uchar4*)task.rgba, (float4*)task.buffer, + task.sample, task.resolution, x, y, task.offset, task.stride); } } diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index 177c90ba2df..dfa2fcb2322 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -520,6 +520,12 @@ public: cuda_assert(cuParamSeti(cuPathTrace, offset, task.h)) offset += sizeof(task.h); + cuda_assert(cuParamSeti(cuPathTrace, offset, task.offset)) + offset += sizeof(task.offset); + + cuda_assert(cuParamSeti(cuPathTrace, offset, task.stride)) + offset += sizeof(task.stride); + cuda_assert(cuParamSetSize(cuPathTrace, offset)) /* launch kernel: todo find optimal size, cache config for fermi */ @@ -581,6 +587,12 @@ public: cuda_assert(cuParamSeti(cuFilmConvert, offset, task.h)) offset += sizeof(task.h); + cuda_assert(cuParamSeti(cuFilmConvert, offset, task.offset)) + offset += sizeof(task.offset); + + cuda_assert(cuParamSeti(cuFilmConvert, offset, task.stride)) + offset += sizeof(task.stride); + cuda_assert(cuParamSetSize(cuFilmConvert, offset)) /* launch kernel: todo find optimal size, cache config for fermi */ diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index 8eaaebc6629..3a1d3032d6e 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -191,7 +191,7 @@ public: { char version[256]; - int major, minor, req_major = 1, req_minor = 1; + int major, minor, req_major = 1, req_minor = 0; clGetPlatformInfo(cpPlatform, CL_PLATFORM_VERSION, sizeof(version), &version, NULL); @@ -541,6 +541,8 @@ public: cl_int d_w = task.w; cl_int d_h = task.h; cl_int d_sample = task.sample; + cl_int d_offset = task.offset; + cl_int d_stride = task.stride; /* sample arguments */ int narg = 0; @@ -559,6 +561,8 @@ public: ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_y), (void*)&d_y); ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_w), (void*)&d_w); ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_h), (void*)&d_h); + ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_offset), (void*)&d_offset); + ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_stride), (void*)&d_stride); opencl_assert(ciErr); @@ -611,6 +615,8 @@ public: cl_int d_h = task.h; cl_int d_sample = task.sample; cl_int d_resolution = task.resolution; + cl_int d_offset = task.offset; + cl_int d_stride = task.stride; /* sample arguments */ int narg = 0; @@ -630,6 +636,8 @@ public: ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_y), (void*)&d_y); ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_w), (void*)&d_w); ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_h), (void*)&d_h); + ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_offset), (void*)&d_offset); + ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_stride), (void*)&d_stride); opencl_assert(ciErr); diff --git a/intern/cycles/kernel/kernel.cl b/intern/cycles/kernel/kernel.cl index c00bc3fe957..90eb7a2513f 100644 --- a/intern/cycles/kernel/kernel.cl +++ b/intern/cycles/kernel/kernel.cl @@ -36,7 +36,7 @@ __kernel void kernel_ocl_path_trace( #include "kernel_textures.h" int sample, - int sx, int sy, int sw, int sh) + int sx, int sy, int sw, int sh, int offset, int stride) { KernelGlobals kglobals, *kg = &kglobals; @@ -50,7 +50,7 @@ __kernel void kernel_ocl_path_trace( int y = sy + get_global_id(1); if(x < sx + sw && y < sy + sh) - kernel_path_trace(kg, buffer, rng_state, sample, x, y); + kernel_path_trace(kg, buffer, rng_state, sample, x, y, offset, stride); } __kernel void kernel_ocl_tonemap( @@ -63,7 +63,7 @@ __kernel void kernel_ocl_tonemap( #include "kernel_textures.h" int sample, int resolution, - int sx, int sy, int sw, int sh) + int sx, int sy, int sw, int sh, int offset, int stride) { KernelGlobals kglobals, *kg = &kglobals; @@ -77,7 +77,7 @@ __kernel void kernel_ocl_tonemap( int y = sy + get_global_id(1); if(x < sx + sw && y < sy + sh) - kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y); + kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride); } /*__kernel void kernel_ocl_displace(__global uint4 *input, __global float3 *offset, int sx) diff --git a/intern/cycles/kernel/kernel.cpp b/intern/cycles/kernel/kernel.cpp index 52a3852aa01..b4c3839dbd0 100644 --- a/intern/cycles/kernel/kernel.cpp +++ b/intern/cycles/kernel/kernel.cpp @@ -204,16 +204,16 @@ void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t /* Path Tracing */ -void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y) +void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y, int offset, int stride) { - kernel_path_trace(kg, buffer, rng_state, sample, x, y); + kernel_path_trace(kg, buffer, rng_state, sample, x, y, offset, stride); } /* Tonemapping */ -void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y) +void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y, int offset, int stride) { - kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y); + kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride); } /* Displacement */ diff --git a/intern/cycles/kernel/kernel.cu b/intern/cycles/kernel/kernel.cu index 75415a00b00..71fc7ac3197 100644 --- a/intern/cycles/kernel/kernel.cu +++ b/intern/cycles/kernel/kernel.cu @@ -26,22 +26,22 @@ #include "kernel_path.h" #include "kernel_displace.h" -extern "C" __global__ void kernel_cuda_path_trace(float4 *buffer, uint *rng_state, int sample, int sx, int sy, int sw, int sh) +extern "C" __global__ void kernel_cuda_path_trace(float4 *buffer, uint *rng_state, int sample, int sx, int sy, int sw, int sh, int offset, int stride) { int x = sx + blockDim.x*blockIdx.x + threadIdx.x; int y = sy + blockDim.y*blockIdx.y + threadIdx.y; if(x < sx + sw && y < sy + sh) - kernel_path_trace(NULL, buffer, rng_state, sample, x, y); + kernel_path_trace(NULL, buffer, rng_state, sample, x, y, offset, stride); } -extern "C" __global__ void kernel_cuda_tonemap(uchar4 *rgba, float4 *buffer, int sample, int resolution, int sx, int sy, int sw, int sh) +extern "C" __global__ void kernel_cuda_tonemap(uchar4 *rgba, float4 *buffer, int sample, int resolution, int sx, int sy, int sw, int sh, int offset, int stride) { int x = sx + blockDim.x*blockIdx.x + threadIdx.x; int y = sy + blockDim.y*blockIdx.y + threadIdx.y; if(x < sx + sw && y < sy + sh) - kernel_film_tonemap(NULL, rgba, buffer, sample, resolution, x, y); + kernel_film_tonemap(NULL, rgba, buffer, sample, resolution, x, y, offset, stride); } extern "C" __global__ void kernel_cuda_displace(uint4 *input, float3 *offset, int sx) diff --git a/intern/cycles/kernel/kernel.h b/intern/cycles/kernel/kernel.h index 700ee49c5f2..78247504b39 100644 --- a/intern/cycles/kernel/kernel.h +++ b/intern/cycles/kernel/kernel.h @@ -36,13 +36,17 @@ bool kernel_osl_use(KernelGlobals *kg); void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t size); void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t width, size_t height); -void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y); -void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y); +void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, + int sample, int x, int y, int offset, int stride); +void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, + int sample, int resolution, int x, int y, int offset, int stride); void kernel_cpu_displace(KernelGlobals *kg, uint4 *input, float3 *offset, int i); #ifdef WITH_OPTIMIZED_KERNEL -void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y); -void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y); +void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, + int sample, int x, int y, int offset, int stride); +void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, + int sample, int resolution, int x, int y, int offset, int stride); void kernel_cpu_optimized_displace(KernelGlobals *kg, uint4 *input, float3 *offset, int i); #endif diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h index 9cdc2f1f865..2dbdd076891 100644 --- a/intern/cycles/kernel/kernel_camera.h +++ b/intern/cycles/kernel/kernel_camera.h @@ -74,8 +74,8 @@ __device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float ray->dP.dx = make_float3(0.0f, 0.0f, 0.0f); ray->dP.dy = make_float3(0.0f, 0.0f, 0.0f); - ray->dD.dx = normalize(Ddiff + kernel_data.cam.dx) - normalize(Ddiff); - ray->dD.dy = normalize(Ddiff + kernel_data.cam.dy) - normalize(Ddiff); + ray->dD.dx = normalize(Ddiff + float4_to_float3(kernel_data.cam.dx)) - normalize(Ddiff); + ray->dD.dy = normalize(Ddiff + float4_to_float3(kernel_data.cam.dy)) - normalize(Ddiff); #endif #ifdef __CAMERA_CLIPPING__ @@ -107,8 +107,8 @@ __device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, floa #ifdef __RAY_DIFFERENTIALS__ /* ray differential */ - ray->dP.dx = kernel_data.cam.dx; - ray->dP.dy = kernel_data.cam.dy; + ray->dP.dx = float4_to_float3(kernel_data.cam.dx); + ray->dP.dy = float4_to_float3(kernel_data.cam.dy); ray->dD.dx = make_float3(0.0f, 0.0f, 0.0f); ray->dD.dy = make_float3(0.0f, 0.0f, 0.0f); diff --git a/intern/cycles/kernel/kernel_film.h b/intern/cycles/kernel/kernel_film.h index 4373701452e..cd8acc9647a 100644 --- a/intern/cycles/kernel/kernel_film.h +++ b/intern/cycles/kernel/kernel_film.h @@ -48,10 +48,9 @@ __device uchar4 film_float_to_byte(float4 color) return result; } -__device void kernel_film_tonemap(KernelGlobals *kg, __global uchar4 *rgba, __global float4 *buffer, int sample, int resolution, int x, int y) +__device void kernel_film_tonemap(KernelGlobals *kg, __global uchar4 *rgba, __global float4 *buffer, int sample, int resolution, int x, int y, int offset, int stride) { - int w = kernel_data.cam.width; - int index = x + y*w; + int index = offset + x + y*stride; float4 irradiance = buffer[index]; float4 float_result = film_map(kg, irradiance, sample); diff --git a/intern/cycles/kernel/kernel_optimized.cpp b/intern/cycles/kernel/kernel_optimized.cpp index 85a2b798a62..ea43e01ab58 100644 --- a/intern/cycles/kernel/kernel_optimized.cpp +++ b/intern/cycles/kernel/kernel_optimized.cpp @@ -35,16 +35,16 @@ CCL_NAMESPACE_BEGIN /* Path Tracing */ -void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y) +void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y, int offset, int stride) { - kernel_path_trace(kg, buffer, rng_state, sample, x, y); + kernel_path_trace(kg, buffer, rng_state, sample, x, y, offset, stride); } /* Tonemapping */ -void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y) +void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y, int offset, int stride) { - kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y); + kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride); } /* Displacement */ diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index c609f6f13fe..05707f31352 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -34,7 +34,7 @@ CCL_NAMESPACE_BEGIN #ifdef __MODIFY_TP__ -__device float3 path_terminate_modified_throughput(KernelGlobals *kg, __global float3 *buffer, int x, int y, int sample) +__device float3 path_terminate_modified_throughput(KernelGlobals *kg, __global float3 *buffer, int x, int y, int offset, int stride, int sample) { /* modify throughput to influence path termination probability, to avoid darker regions receiving fewer samples than lighter regions. also RGB @@ -45,7 +45,7 @@ __device float3 path_terminate_modified_throughput(KernelGlobals *kg, __global f const float minL = 0.1f; if(sample >= minsample) { - float3 L = buffer[x + y*kernel_data.cam.width]; + float3 L = buffer[offset + x + y*stride]; float3 Lmin = make_float3(minL, minL, minL); float correct = (float)(sample+1)/(float)sample; @@ -379,7 +379,7 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R return make_float4(L.x, L.y, L.z, 1.0f - Ltransparent); } -__device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __global uint *rng_state, int sample, int x, int y) +__device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __global uint *rng_state, int sample, int x, int y, int offset, int stride) { /* initialize random numbers */ RNG rng; @@ -387,7 +387,7 @@ __device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __gl float filter_u; float filter_v; - path_rng_init(kg, rng_state, sample, &rng, x, y, &filter_u, &filter_v); + path_rng_init(kg, rng_state, sample, &rng, x, y, offset, stride, &filter_u, &filter_v); /* sample camera ray */ Ray ray; @@ -399,7 +399,7 @@ __device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __gl /* integrate */ #ifdef __MODIFY_TP__ - float3 throughput = path_terminate_modified_throughput(kg, buffer, x, y, sample); + float3 throughput = path_terminate_modified_throughput(kg, buffer, x, y, offset, stride, sample); float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput)/throughput; #else float3 throughput = make_float3(1.0f, 1.0f, 1.0f); @@ -407,14 +407,14 @@ __device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __gl #endif /* accumulate result in output buffer */ - int index = x + y*kernel_data.cam.width; + int index = offset + x + y*stride; if(sample == 0) buffer[index] = L; else buffer[index] += L; - path_rng_end(kg, rng_state, rng, x, y); + path_rng_end(kg, rng_state, rng, x, y, offset, stride); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h index ba97ab3e3b6..41301ebd3dc 100644 --- a/intern/cycles/kernel/kernel_random.h +++ b/intern/cycles/kernel/kernel_random.h @@ -123,7 +123,7 @@ __device_inline float path_rng(KernelGlobals *kg, RNG *rng, int sample, int dime #endif } -__device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, RNG *rng, int x, int y, float *fx, float *fy) +__device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, RNG *rng, int x, int y, int offset, int stride, float *fx, float *fy) { #ifdef __SOBOL_FULL_SCREEN__ uint px, py; @@ -138,7 +138,7 @@ __device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state, *fx = size * (float)px * (1.0f/(float)0xFFFFFFFF) - x; *fy = size * (float)py * (1.0f/(float)0xFFFFFFFF) - y; #else - *rng = rng_state[x + y*kernel_data.cam.width]; + *rng = rng_state[offset + x + y*stride]; *rng ^= kernel_data.integrator.seed; @@ -147,7 +147,7 @@ __device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state, #endif } -__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng, int x, int y) +__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng, int x, int y, int offset, int stride) { /* nothing to do */ } @@ -163,10 +163,10 @@ __device float path_rng(KernelGlobals *kg, RNG *rng, int sample, int dimension) return (float)*rng * (1.0f/(float)0xFFFFFFFF); } -__device void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, RNG *rng, int x, int y, float *fx, float *fy) +__device void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, RNG *rng, int x, int y, int offset, int stride, float *fx, float *fy) { /* load state */ - *rng = rng_state[x + y*kernel_data.cam.width]; + *rng = rng_state[offset + x + y*stride]; *rng ^= kernel_data.integrator.seed; @@ -174,10 +174,10 @@ __device void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sam *fy = path_rng(kg, rng, sample, PRNG_FILTER_V); } -__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng, int x, int y) +__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng, int x, int y, int offset, int stride) { /* store state for next sample */ - rng_state[x + y*kernel_data.cam.width] = rng; + rng_state[offset + x + y*stride] = rng; } #endif diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index d9bd645b16d..ea73f87a8a5 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -295,29 +295,24 @@ typedef struct ShaderData { #endif } ShaderData; -/* Constrant Kernel Data */ +/* Constrant Kernel Data + * + * These structs are passed from CPU to various devices, and the struct layout + * must match exactly. Structs are padded to ensure 16 byte alignment, and we + * do not use float3 because its size may not be the same on all devices. */ typedef struct KernelCamera { /* type */ int ortho; - int pad; - - /* size */ - int width, height; + int pad1, pad2, pad3; /* matrices */ Transform cameratoworld; Transform rastertocamera; /* differentials */ - float3 dx; -#ifndef WITH_OPENCL - float pad1; -#endif - float3 dy; -#ifndef WITH_OPENCL - float pad2; -#endif + float4 dx; + float4 dy; /* depth of field */ float aperturesize; @@ -358,10 +353,6 @@ typedef struct KernelBackground { typedef struct KernelSunSky { /* sun direction in spherical and cartesian */ float theta, phi, pad3, pad4; - float3 dir; -#ifndef WITH_OPENCL - float pad; -#endif /* perez function parameters */ float zenith_Y, zenith_x, zenith_y, pad2; diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp index acdddb475d0..29141b25b59 100644 --- a/intern/cycles/render/buffers.cpp +++ b/intern/cycles/render/buffers.cpp @@ -36,8 +36,6 @@ CCL_NAMESPACE_BEGIN RenderBuffers::RenderBuffers(Device *device_) { device = device_; - width = 0; - height = 0; } RenderBuffers::~RenderBuffers() @@ -58,24 +56,23 @@ void RenderBuffers::device_free() } } -void RenderBuffers::reset(Device *device, int width_, int height_) +void RenderBuffers::reset(Device *device, BufferParams& params_) { - width = width_; - height = height_; + params = params_; /* free existing buffers */ device_free(); /* allocate buffer */ - buffer.resize(width, height); + buffer.resize(params.width, params.height); device->mem_alloc(buffer, MEM_READ_WRITE); device->mem_zero(buffer); /* allocate rng state */ - rng_state.resize(width, height); + rng_state.resize(params.width, params.height); - uint *init_state = rng_state.resize(width, height); - int x, y; + uint *init_state = rng_state.resize(params.width, params.height); + int x, y, width = params.width, height = params.height; for(x=0; x<width; x++) for(y=0; y<height; y++) @@ -92,11 +89,11 @@ float4 *RenderBuffers::copy_from_device(float exposure, int sample) device->mem_copy_from(buffer, 0, buffer.memory_size()); - float4 *out = new float4[width*height]; + float4 *out = new float4[params.width*params.height]; float4 *in = (float4*)buffer.data_pointer; float scale = 1.0f/(float)sample; - for(int i = width*height - 1; i >= 0; i--) { + for(int i = params.width*params.height - 1; i >= 0; i--) { float4 rgba = in[i]*scale; rgba.x = rgba.x*exposure; @@ -117,8 +114,6 @@ float4 *RenderBuffers::copy_from_device(float exposure, int sample) DisplayBuffer::DisplayBuffer(Device *device_) { device = device_; - width = 0; - height = 0; draw_width = 0; draw_height = 0; transparent = true; /* todo: determine from background */ @@ -137,28 +132,27 @@ void DisplayBuffer::device_free() } } -void DisplayBuffer::reset(Device *device, int width_, int height_) +void DisplayBuffer::reset(Device *device, BufferParams& params_) { draw_width = 0; draw_height = 0; - width = width_; - height = height_; + params = params_; /* free existing buffers */ device_free(); /* allocate display pixels */ - rgba.resize(width, height); + rgba.resize(params.width, params.height); device->pixels_alloc(rgba); } -void DisplayBuffer::draw_set(int width_, int height_) +void DisplayBuffer::draw_set(int width, int height) { - assert(width_ <= width && height_ <= height); + assert(width <= params.width && height <= params.height); - draw_width = width_; - draw_height = height_; + draw_width = width; + draw_height = height; } void DisplayBuffer::draw_transparency_grid() @@ -175,11 +169,11 @@ void DisplayBuffer::draw_transparency_grid() }; glColor4ub(50, 50, 50, 255); - glRectf(0, 0, width, height); + glRectf(0, 0, params.width, params.height); glEnable(GL_POLYGON_STIPPLE); glColor4ub(55, 55, 55, 255); glPolygonStipple(checker_stipple_sml); - glRectf(0, 0, width, height); + glRectf(0, 0, params.width, params.height); glDisable(GL_POLYGON_STIPPLE); } @@ -189,7 +183,7 @@ void DisplayBuffer::draw(Device *device) if(transparent) draw_transparency_grid(); - device->draw_pixels(rgba, 0, draw_width, draw_height, width, height, transparent); + device->draw_pixels(rgba, 0, draw_width, draw_height, params.width, params.height, transparent); } } diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h index d5eb8d7fa2f..66bd03c8893 100644 --- a/intern/cycles/render/buffers.h +++ b/intern/cycles/render/buffers.h @@ -30,12 +30,49 @@ CCL_NAMESPACE_BEGIN class Device; struct float4; +/* Buffer Parameters + Size of render buffer and how it fits in the full image (border render). */ + +class BufferParams { +public: + /* width/height of the physical buffer */ + int width; + int height; + + /* offset into and width/height of the full buffer */ + int full_x; + int full_y; + int full_width; + int full_height; + + BufferParams() + { + width = 0; + height = 0; + + full_x = 0; + full_y = 0; + full_width = 0; + full_height = 0; + } + + bool modified(const BufferParams& params) + { + return !(full_x == params.full_x + && full_y == params.full_y + && width == params.width + && height == params.height + && full_width == params.full_width + && full_height == params.full_height); + } +}; + /* Render Buffers */ class RenderBuffers { public: - /* buffer dimensions */ - int width, height; + /* buffer parameters */ + BufferParams params; /* float buffer */ device_vector<float4> buffer; /* random number generator state */ @@ -46,7 +83,7 @@ public: RenderBuffers(Device *device); ~RenderBuffers(); - void reset(Device *device, int width, int height); + void reset(Device *device, BufferParams& params); float4 *copy_from_device(float exposure, int sample); protected: @@ -62,8 +99,8 @@ protected: class DisplayBuffer { public: - /* buffer dimensions */ - int width, height; + /* buffer parameters */ + BufferParams params; /* dimensions for how much of the buffer is actually ready for display. with progressive render we can be using only a subset of the buffer. if these are zero, it means nothing can be drawn yet */ @@ -78,7 +115,7 @@ public: DisplayBuffer(Device *device); ~DisplayBuffer(); - void reset(Device *device, int width, int height); + void reset(Device *device, BufferParams& params); void write(Device *device, const string& filename); void draw_set(int width, int height); diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index e88c0a388bc..a83ae81844c 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -72,8 +72,9 @@ void Camera::update() if(!need_update) return; + /* ndc to raster */ Transform screentocamera; - Transform ndctoraster = transform_scale((float)width, (float)height, 1.0f); + Transform ndctoraster = transform_scale(width, height, 1.0f); /* raster to screen */ Transform screentoraster = ndctoraster * @@ -148,13 +149,9 @@ void Camera::device_update(Device *device, DeviceScene *dscene) /* type */ kcam->ortho = ortho; - /* size */ - kcam->width = width; - kcam->height = height; - /* store differentials */ - kcam->dx = dx; - kcam->dy = dy; + kcam->dx = float3_to_float4(dx); + kcam->dy = float3_to_float4(dy); /* clipping */ kcam->nearclip = nearclip; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 7d873221cd6..81d156a079d 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -273,7 +273,6 @@ static void sky_texture_precompute(KernelSunSky *ksunsky, float3 dir, float turb ksunsky->theta = theta; ksunsky->phi = phi; - ksunsky->dir = dir; float theta2 = theta*theta; float theta3 = theta*theta*theta; diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 42b4a2bb7e4..26c4dbfbb7a 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -51,8 +51,6 @@ Session::Session(const SessionParams& params_) sample = 0; delayed_reset.do_reset = false; - delayed_reset.w = 0; - delayed_reset.h = 0; delayed_reset.samples = 0; display_outdated = false; @@ -108,7 +106,7 @@ bool Session::ready_to_reset() /* GPU Session */ -void Session::reset_gpu(int w, int h, int samples) +void Session::reset_gpu(BufferParams& buffer_params, int samples) { /* block for buffer acces and reset immediately. we can't do this in the thread, because we need to allocate an OpenGL buffer, and @@ -119,7 +117,7 @@ void Session::reset_gpu(int w, int h, int samples) display_outdated = true; reset_time = time_dt(); - reset_(w, h, samples); + reset_(buffer_params, samples); gpu_need_tonemap = false; gpu_need_tonemap_cond.notify_all(); @@ -127,7 +125,7 @@ void Session::reset_gpu(int w, int h, int samples) pause_cond.notify_all(); } -bool Session::draw_gpu(int w, int h) +bool Session::draw_gpu(BufferParams& buffer_params) { /* block for buffer access */ thread_scoped_lock display_lock(display->mutex); @@ -136,7 +134,7 @@ bool Session::draw_gpu(int w, int h) if(gpu_draw_ready) { /* then verify the buffers have the expected size, so we don't draw previous results in a resized window */ - if(w == display->width && h == display->height) { + if(!buffer_params.modified(display->params)) { /* for CUDA we need to do tonemapping still, since we can only access GL buffers from the main thread */ if(gpu_need_tonemap) { @@ -261,15 +259,14 @@ void Session::run_gpu() /* CPU Session */ -void Session::reset_cpu(int w, int h, int samples) +void Session::reset_cpu(BufferParams& buffer_params, int samples) { thread_scoped_lock reset_lock(delayed_reset.mutex); display_outdated = true; reset_time = time_dt(); - delayed_reset.w = w; - delayed_reset.h = h; + delayed_reset.params = buffer_params; delayed_reset.samples = samples; delayed_reset.do_reset = true; device->task_cancel(); @@ -277,7 +274,7 @@ void Session::reset_cpu(int w, int h, int samples) pause_cond.notify_all(); } -bool Session::draw_cpu(int w, int h) +bool Session::draw_cpu(BufferParams& buffer_params) { thread_scoped_lock display_lock(display->mutex); @@ -285,7 +282,7 @@ bool Session::draw_cpu(int w, int h) if(display->draw_ready()) { /* then verify the buffers have the expected size, so we don't draw previous results in a resized window */ - if(w == display->width && h == display->height) { + if(!buffer_params.modified(display->params)) { display->draw(device); if(display_outdated && (time_dt() - reset_time) > params.text_timeout) @@ -306,7 +303,7 @@ void Session::run_cpu() thread_scoped_lock buffers_lock(buffers->mutex); thread_scoped_lock display_lock(display->mutex); - reset_(delayed_reset.w, delayed_reset.h, delayed_reset.samples); + reset_(delayed_reset.params, delayed_reset.samples); delayed_reset.do_reset = false; } @@ -389,7 +386,7 @@ void Session::run_cpu() if(delayed_reset.do_reset) { /* reset rendering if request from main thread */ delayed_reset.do_reset = false; - reset_(delayed_reset.w, delayed_reset.h, delayed_reset.samples); + reset_(delayed_reset.params, delayed_reset.samples); } else if(need_tonemap) { /* tonemap only if we do not reset, we don't we don't @@ -438,23 +435,23 @@ void Session::run() progress.set_update(); } -bool Session::draw(int w, int h) +bool Session::draw(BufferParams& buffer_params) { if(device_use_gl) - return draw_gpu(w, h); + return draw_gpu(buffer_params); else - return draw_cpu(w, h); + return draw_cpu(buffer_params); } -void Session::reset_(int w, int h, int samples) +void Session::reset_(BufferParams& buffer_params, int samples) { - if(w != buffers->width || h != buffers->height) { + if(buffer_params.modified(buffers->params)) { gpu_draw_ready = false; - buffers->reset(device, w, h); - display->reset(device, w, h); + buffers->reset(device, buffer_params); + display->reset(device, buffer_params); } - tile_manager.reset(w, h, samples); + tile_manager.reset(buffer_params, samples); start_time = time_dt(); preview_time = 0.0; @@ -462,12 +459,12 @@ void Session::reset_(int w, int h, int samples) sample = 0; } -void Session::reset(int w, int h, int samples) +void Session::reset(BufferParams& buffer_params, int samples) { if(device_use_gl) - reset_gpu(w, h, samples); + reset_gpu(buffer_params, samples); else - reset_cpu(w, h, samples); + reset_cpu(buffer_params, samples); } void Session::set_samples(int samples) @@ -514,14 +511,18 @@ void Session::update_scene() progress.set_status("Updating Scene"); - /* update camera if dimensions changed for progressive render */ + /* update camera if dimensions changed for progressive render. the camera + knows nothing about progressive or cropped rendering, it just gets the + image dimensions passed in */ Camera *cam = scene->camera; - int w = tile_manager.state.width; - int h = tile_manager.state.height; - - if(cam->width != w || cam->height != h) { - cam->width = w; - cam->height = h; + float progressive_x = tile_manager.state.width/(float)tile_manager.params.width; + float progressive_y = tile_manager.state.height/(float)tile_manager.params.height; + int width = tile_manager.params.full_width*progressive_x; + int height = tile_manager.params.full_height*progressive_y; + + if(width != cam->width || height != cam->height) { + cam->width = width; + cam->height = height; cam->tag_update(); } @@ -573,14 +574,16 @@ void Session::path_trace(Tile& tile) /* add path trace task */ DeviceTask task(DeviceTask::PATH_TRACE); - task.x = tile.x; - task.y = tile.y; + task.x = tile_manager.state.full_x + tile.x; + task.y = tile_manager.state.full_y + tile.y; task.w = tile.w; task.h = tile.h; task.buffer = buffers->buffer.device_pointer; task.rng_state = buffers->rng_state.device_pointer; task.sample = tile_manager.state.sample; task.resolution = tile_manager.state.resolution; + task.offset = -(tile_manager.state.full_x + tile_manager.state.full_y*tile_manager.state.width); + task.stride = tile_manager.state.width; device->task_add(task); } @@ -590,14 +593,16 @@ void Session::tonemap() /* add tonemap task */ DeviceTask task(DeviceTask::TONEMAP); - task.x = 0; - task.y = 0; + task.x = tile_manager.state.full_x; + task.y = tile_manager.state.full_y; task.w = tile_manager.state.width; task.h = tile_manager.state.height; task.rgba = display->rgba.device_pointer; task.buffer = buffers->buffer.device_pointer; task.sample = tile_manager.state.sample; task.resolution = tile_manager.state.resolution; + task.offset = -(tile_manager.state.full_x + tile_manager.state.full_y*tile_manager.state.width); + task.stride = tile_manager.state.width; if(task.w > 0 && task.h > 0) { device->task_add(task); diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h index ce7f420096a..89979b8c451 100644 --- a/intern/cycles/render/session.h +++ b/intern/cycles/render/session.h @@ -19,6 +19,7 @@ #ifndef __SESSION_H__ #define __SESSION_H__ +#include "buffers.h" #include "device.h" #include "tile.h" @@ -27,6 +28,7 @@ CCL_NAMESPACE_BEGIN +class BufferParams; class Device; class DeviceScene; class DisplayBuffer; @@ -106,11 +108,11 @@ public: ~Session(); void start(); - bool draw(int w, int h); + bool draw(BufferParams& params); void wait(); bool ready_to_reset(); - void reset(int w, int h, int samples); + void reset(BufferParams& params, int samples); void set_samples(int samples); void set_pause(bool pause); @@ -118,7 +120,7 @@ protected: struct DelayedReset { thread_mutex mutex; bool do_reset; - int w, h; + BufferParams params; int samples; } delayed_reset; @@ -129,15 +131,15 @@ protected: void tonemap(); void path_trace(Tile& tile); - void reset_(int w, int h, int samples); + void reset_(BufferParams& params, int samples); void run_cpu(); - bool draw_cpu(int w, int h); - void reset_cpu(int w, int h, int samples); + bool draw_cpu(BufferParams& params); + void reset_cpu(BufferParams& params, int samples); void run_gpu(); - bool draw_gpu(int w, int h); - void reset_gpu(int w, int h, int samples); + bool draw_gpu(BufferParams& params); + void reset_gpu(BufferParams& params, int samples); TileManager tile_manager; bool device_use_gl; diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp index ba437e74874..b118a7ba478 100644 --- a/intern/cycles/render/tile.cpp +++ b/intern/cycles/render/tile.cpp @@ -28,21 +28,21 @@ TileManager::TileManager(bool progressive_, int samples_, int tile_size_, int mi tile_size = tile_size_; min_size = min_size_; - reset(0, 0, 0); + BufferParams buffer_params; + reset(buffer_params, 0); } TileManager::~TileManager() { } -void TileManager::reset(int width_, int height_, int samples_) +void TileManager::reset(BufferParams& params_, int samples_) { - full_width = width_; - full_height = height_; + params = params_; start_resolution = 1; - int w = width_, h = height_; + int w = params.width, h = params.height; if(min_size != INT_MAX) { while(w*h > min_size*min_size) { @@ -55,6 +55,8 @@ void TileManager::reset(int width_, int height_, int samples_) samples = samples_; + state.full_x = 0; + state.full_y = 0; state.width = 0; state.height = 0; state.sample = -1; @@ -70,8 +72,8 @@ void TileManager::set_samples(int samples_) void TileManager::set_tiles() { int resolution = state.resolution; - int image_w = max(1, full_width/resolution); - int image_h = max(1, full_height/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 sub_w = image_w/tile_w; @@ -90,6 +92,8 @@ void TileManager::set_tiles() } } + state.full_x = params.full_x/resolution; + state.full_y = params.full_y/resolution; state.width = image_w; state.height = image_h; } diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h index 5cd16eb8afa..76863d23498 100644 --- a/intern/cycles/render/tile.h +++ b/intern/cycles/render/tile.h @@ -21,6 +21,7 @@ #include <limits.h> +#include "buffers.h" #include "util_list.h" CCL_NAMESPACE_BEGIN @@ -39,7 +40,10 @@ public: class TileManager { public: + BufferParams params; struct State { + int full_x; + int full_y; int width; int height; int sample; @@ -50,7 +54,7 @@ public: TileManager(bool progressive, int samples, int tile_size, int min_size); ~TileManager(); - void reset(int width, int height, int samples); + void reset(BufferParams& params, int samples); void set_samples(int samples); bool next(); bool done(); @@ -63,8 +67,6 @@ protected: int tile_size; int min_size; - int full_width; - int full_height; int start_resolution; }; diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index 7c56f0fbb12..0a1d8ff4555 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -536,6 +536,11 @@ __device_inline float3 float4_to_float3(const float4 a) return make_float3(a.x, a.y, a.z); } +__device_inline float4 float3_to_float4(const float3 a) +{ + return make_float4(a.x, a.y, a.z, 1.0f); +} + #ifndef __KERNEL_GPU__ __device_inline void print_float3(const char *label, const float3& a) diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h index 4bf3759dd75..07db52f6392 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -209,6 +209,13 @@ __device_inline float3 transform_get_column(const Transform *t, int column) return make_float3(t->x[column], t->y[column], t->z[column]); } +__device_inline void transform_set_column(Transform *t, int column, float3 value) +{ + t->x[column] = value.x; + t->y[column] = value.y; + t->z[column] = value.z; +} + Transform transform_inverse(const Transform& a); __device_inline bool transform_uniform_scale(const Transform& tfm, float& scale) @@ -244,6 +251,17 @@ __device_inline bool transform_negative_scale(const Transform& tfm) return (dot(cross(c0, c1), c2) < 0.0f); } +__device_inline Transform transform_clear_scale(const Transform& tfm) +{ + Transform ntfm = tfm; + + transform_set_column(&ntfm, 0, normalize(transform_get_column(&ntfm, 0))); + transform_set_column(&ntfm, 1, normalize(transform_get_column(&ntfm, 1))); + transform_set_column(&ntfm, 2, normalize(transform_get_column(&ntfm, 2))); + + return ntfm; +} + #endif CCL_NAMESPACE_END diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 01217dfd17a..fbb474cb20a 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -34,6 +34,7 @@ #endif #include <OpenGL/gl.h> +#include <OpenGL/CGLRenderers.h> /***** Multithreaded opengl code : uncomment for enabling #include <OpenGL/OpenGL.h> */ @@ -485,7 +486,14 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( // needed for 'Draw Overlap' drawing method pixelFormatAttrsWindow[i++] = NSOpenGLPFABackingStore; - pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated; + // Force software OpenGL, for debugging + if(getenv("BLENDER_SOFTWAREGL")) { + pixelFormatAttrsWindow[i++] = NSOpenGLPFARendererID; + pixelFormatAttrsWindow[i++] = kCGLRendererGenericID; + } + else + pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated; + //pixelFormatAttrsWindow[i++] = NSOpenGLPFAAllowOfflineRenderers,; // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway pixelFormatAttrsWindow[i++] = NSOpenGLPFADepthSize; @@ -521,7 +529,14 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( // needed for 'Draw Overlap' drawing method pixelFormatAttrsWindow[i++] = NSOpenGLPFABackingStore; - pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated; + // Force software OpenGL, for debugging + if(getenv("BLENDER_SOFTWAREGL")) { + pixelFormatAttrsWindow[i++] = NSOpenGLPFARendererID; + pixelFormatAttrsWindow[i++] = kCGLRendererGenericID; + } + else + pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated; + //pixelFormatAttrsWindow[i++] = NSOpenGLPFAAllowOfflineRenderers,; // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway pixelFormatAttrsWindow[i++] = NSOpenGLPFADepthSize; diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 1da5e2ca381..58941e00914 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -29,6 +29,8 @@ from bpy.props import (StringProperty, from rna_prop_ui import rna_idprop_ui_prop_get, rna_idprop_ui_prop_clear +import subprocess +import os class MESH_OT_delete_edgeloop(Operator): '''Delete an edge loop by merging the faces on each side to a single face loop''' @@ -1175,6 +1177,26 @@ class WM_OT_copy_prev_settings(Operator): return {'CANCELLED'} +class WM_OT_blenderplayer_start(bpy.types.Operator): + '''Launches the Blenderplayer with the current blendfile''' + bl_idname = "wm.blenderplayer_start" + bl_label = "Start" + + blender_bin_path = bpy.app.binary_path + blender_bin_dir = os.path.dirname(blender_bin_path) + ext = os.path.splitext(blender_bin_path)[-1] + player_path = os.path.join(blender_bin_dir, 'blenderplayer' + ext) + + def execute(self, context): + import sys + + if sys.platform == 'darwin': + self.player_path = os.path.join(self.blender_bin_dir, '../../../blenderplayer.app/Contents/MacOS/blenderplayer') + + filepath = bpy.app.tempdir + "game.blend" + bpy.ops.wm.save_as_mainfile(filepath=filepath, check_existing=False, copy=True) + subprocess.call([self.player_path, filepath]) + return {'FINISHED'} class WM_OT_keyconfig_test(Operator): "Test keyconfig for conflicts" diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py index db65b0ff669..66b8cca7866 100644 --- a/release/scripts/startup/bl_ui/properties_game.py +++ b/release/scripts/startup/bl_ui/properties_game.py @@ -244,16 +244,22 @@ class RenderButtonsPanel(): return (rd.engine in cls.COMPAT_ENGINES) -class RENDER_PT_game(RenderButtonsPanel, Panel): - bl_label = "Game" +class RENDER_PT_embedded(RenderButtonsPanel, bpy.types.Panel): + bl_label = "Embedded Player" COMPAT_ENGINES = {'BLENDER_GAME'} - def draw(self, context): layout = self.layout + rd = context.scene.render + row = layout.row() row.operator("view3d.game_start", text="Start") row.label() + row = layout.row() + row.label(text="Resolution:") + row = layout.row(align=True) + row.prop(rd, "resolution_x", slider=False, text="X") + row.prop(rd, "resolution_y", slider=False, text="Y") class RENDER_PT_game_player(RenderButtonsPanel, Panel): @@ -264,29 +270,23 @@ class RENDER_PT_game_player(RenderButtonsPanel, Panel): layout = self.layout gs = context.scene.game_settings - - layout.prop(gs, "show_fullscreen") - - split = layout.split() - - col = split.column() - col.label(text="Resolution:") - sub = col.column(align=True) - sub.prop(gs, "resolution_x", slider=False, text="X") - sub.prop(gs, "resolution_y", slider=False, text="Y") - - col = split.column() + + row = layout.row() + row.operator("wm.blenderplayer_start", text="Start") + row.prop(gs, "show_fullscreen") + + row = layout.row() + row.label(text="Resolution:") + row = layout.row(align=True) + row.prop(gs, "resolution_x", slider=False, text="X") + row.prop(gs, "resolution_y", slider=False, text="Y") + + col = layout.column() col.label(text="Quality:") - sub = col.column(align=True) - sub.prop(gs, "depth", text="Bit Depth", slider=False) - sub.prop(gs, "frequency", text="FPS", slider=False) + col = layout.column(align=True) + col.prop(gs, "depth", text="Bit Depth", slider=False) + col.prop(gs, "frequency", text="Refresh Rate", slider=False) - # framing: - col = layout.column() - col.label(text="Framing:") - col.row().prop(gs, "frame_type", expand=True) - if gs.frame_type == 'LETTERBOX': - col.prop(gs, "frame_color", text="") class RENDER_PT_game_stereo(RenderButtonsPanel, Panel): @@ -368,20 +368,24 @@ class RENDER_PT_game_shading(RenderButtonsPanel, Panel): col.prop(gs, "use_glsl_extra_textures", text="Extra Textures") -class RENDER_PT_game_performance(RenderButtonsPanel, Panel): - bl_label = "Performance" +class RENDER_PT_game_system(RenderButtonsPanel, Panel): + bl_label = "System" COMPAT_ENGINES = {'BLENDER_GAME'} def draw(self, context): layout = self.layout gs = context.scene.game_settings - col = layout.column() - row = col.row() + row = layout.row() row.prop(gs, "use_frame_rate") + row.prop(gs, "restrict_animation_updates") + + row = layout.row() row.prop(gs, "use_display_lists") - col.prop(gs, "restrict_animation_updates") + row = layout.row() + row.label("Exit Key") + row.prop(gs, "exit_key", text="", event=True) class RENDER_PT_game_display(RenderButtonsPanel, Panel): @@ -391,6 +395,9 @@ class RENDER_PT_game_display(RenderButtonsPanel, Panel): def draw(self, context): layout = self.layout + row = layout.row() + row.prop(context.scene.render, "fps", text="Animation Frame Rate", slider=False) + gs = context.scene.game_settings flow = layout.column_flow() flow.prop(gs, "show_debug_properties", text="Debug Properties") @@ -399,6 +406,12 @@ class RENDER_PT_game_display(RenderButtonsPanel, Panel): flow.prop(gs, "use_deprecation_warnings") flow.prop(gs, "show_mouse", text="Mouse Cursor") + col = layout.column() + col.label(text="Framing:") + col.row().prop(gs, "frame_type", expand=True) + if gs.frame_type == 'LETTERBOX': + col.prop(gs, "frame_color", text="") + class SceneButtonsPanel(): bl_space_type = 'PROPERTIES' @@ -463,6 +476,20 @@ class SCENE_PT_game_navmesh(SceneButtonsPanel, Panel): row.prop(rd, "sample_dist") row.prop(rd, "sample_max_error") +class RENDER_PT_game_sound(RenderButtonsPanel, Panel): + bl_label = "Sound" + COMPAT_ENGINES = {'BLENDER_GAME'} + + def draw(self, context): + layout = self.layout + + scene = context.scene + + layout.prop(scene, "audio_distance_model") + + col = layout.column(align=True) + col.prop(scene, "audio_doppler_speed", text="Speed") + col.prop(scene, "audio_doppler_factor") class WorldButtonsPanel(): bl_space_type = 'PROPERTIES' diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index f7f67527b63..b19cf0032af 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -76,7 +76,7 @@ class ParticleButtonsPanel(): class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} @classmethod def poll(cls, context): @@ -85,6 +85,10 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel): def draw(self, context): layout = self.layout + + if context.scene.render.engine == "BLENDER_GAME": + layout.label("Not available in the Game Engine") + return ob = context.object psys = context.particle_system diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index 4b4c2d2b214..6a8439ffaaa 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -51,7 +51,7 @@ class RenderButtonsPanel(): @classmethod def poll(cls, context): rd = context.scene.render - return (context.scene and rd.use_game_engine is False) and (rd.engine in cls.COMPAT_ENGINES) + return context.scene and (rd.engine in cls.COMPAT_ENGINES) class RENDER_PT_render(RenderButtonsPanel, Panel): @@ -553,7 +553,7 @@ class RENDER_PT_encoding(RenderButtonsPanel, Panel): class RENDER_PT_bake(RenderButtonsPanel, Panel): bl_label = "Bake" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index 05f4887a542..b7218e4ba47 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -29,12 +29,13 @@ class SceneButtonsPanel(): @classmethod def poll(cls, context): - return context.scene + rd = context.scene.render + return context.scene and (rd.engine in cls.COMPAT_ENGINES) class SCENE_PT_scene(SceneButtonsPanel, Panel): bl_label = "Scene" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} def draw(self, context): layout = self.layout @@ -75,7 +76,7 @@ class SCENE_PT_audio(SceneButtonsPanel, Panel): class SCENE_PT_unit(SceneButtonsPanel, Panel): bl_label = "Units" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} def draw(self, context): layout = self.layout @@ -93,6 +94,7 @@ class SCENE_PT_unit(SceneButtonsPanel, Panel): class SCENE_PT_keying_sets(SceneButtonsPanel, Panel): bl_label = "Keying Sets" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} def draw(self, context): layout = self.layout @@ -125,6 +127,7 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, Panel): class SCENE_PT_keying_set_paths(SceneButtonsPanel, Panel): bl_label = "Active Keying Set" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/space_logic.py b/release/scripts/startup/bl_ui/space_logic.py index 1ae8095fab3..1fc58475ace 100644 --- a/release/scripts/startup/bl_ui/space_logic.py +++ b/release/scripts/startup/bl_ui/space_logic.py @@ -70,7 +70,9 @@ class LOGIC_HT_header(Header): layout.template_header() if context.area.show_menus: - layout.menu("LOGIC_MT_view") + row = layout.row(align=True) + row.menu("LOGIC_MT_view") + row.menu("LOGIC_MT_logicbricks_add") class LOGIC_MT_view(Menu): diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py index c3b2e30cb12..7249e9522ff 100644 --- a/release/scripts/startup/bl_ui/space_text.py +++ b/release/scripts/startup/bl_ui/space_text.py @@ -174,9 +174,7 @@ class TEXT_MT_text(Menu): st = context.space_data text = st.text - layout.operator_context = 'EXEC_AREA' layout.operator("text.new") - layout.operator_context = 'INVOKE_AREA' layout.operator("text.open") if text: diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 84f8995b480..23073a2d8eb 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -65,6 +65,11 @@ typedef enum { * unless it's a mesh and can be exploded -> curve can also emit particles */ eModifierTypeType_DeformOrConstruct, + + /* Like eModifierTypeType_Nonconstructive, but does not affect the geometry + * of the object, rather some of its CustomData layers. + * E.g. UVProject and WeightVG modifiers. */ + eModifierTypeType_NonGeometrical, } ModifierTypeType; typedef enum { @@ -311,6 +316,7 @@ int modifier_supportsMapping(struct ModifierData *md); int modifier_couldBeCage(struct Scene *scene, struct ModifierData *md); int modifier_isCorrectableDeformed(struct ModifierData *md); int modifier_sameTopology(ModifierData *md); +int modifier_nonGeometrical(ModifierData *md); int modifier_isEnabled(struct Scene *scene, struct ModifierData *md, int required_mode); void modifier_setError(struct ModifierData *md, const char *format, ...) #ifdef __GNUC__ diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 378e5872791..6234308048b 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -305,8 +305,6 @@ void ntreeSwitchID(struct bNodeTree *ntree, struct ID *sce_from, struct ID *sc void ntreeMakeLocal(struct bNodeTree *ntree); int ntreeHasType(struct bNodeTree *ntree, int type); -void ntreeSocketUseFlags(struct bNodeTree *ntree); - void ntreeUpdateTree(struct bNodeTree *ntree); /* XXX Currently each tree update call does call to ntreeVerifyNodes too. * Some day this should be replaced by a decent depsgraph automatism! diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h index 52fa52a5899..7f321abf48e 100644 --- a/source/blender/blenkernel/BKE_texture.h +++ b/source/blender/blenkernel/BKE_texture.h @@ -67,7 +67,7 @@ void free_plugin_tex(struct PluginTex *pit); void init_colorband(struct ColorBand *coba, int rangetype); struct ColorBand *add_colorband(int rangetype); -int do_colorband(struct ColorBand *coba, float in, float out[4]); +int do_colorband(const struct ColorBand *coba, float in, float out[4]); void colorband_table_RGBA(struct ColorBand *coba, float **array, int *size); int vergcband(const void *a1, const void *a2); struct CBData *colorband_element_add(struct ColorBand *coba, float position); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 3bc2ee61e7b..d0ef517e2ae 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -642,7 +642,7 @@ enum { CALC_WP_AUTO_NORMALIZE= (1<<1) }; -void weightpaint_color(unsigned char r_col[4], ColorBand *coba, const float input) +static void weightpaint_color(unsigned char r_col[4], ColorBand *coba, const float input) { float colf[4]; @@ -669,10 +669,10 @@ static void calc_weightpaint_vert_color( if ((selected > 1) && (draw_flag & CALC_WP_MULTIPAINT)) { int was_a_nonzero= FALSE; - int i; + unsigned int i; MDeformWeight *dw= dv->dw; - for (i = dv->totweight; i > 0; i--, dw++) { + for (i = dv->totweight; i != 0; i--, dw++) { /* in multipaint, get the average if auto normalize is inactive * get the sum if it is active */ if (dw->def_nr < defbase_tot) { @@ -717,46 +717,65 @@ void vDM_ColorBand_store(ColorBand *coba) stored_cb= coba; } -static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag) +/* return an array of vertex weight colors, caller must free. + * + * note that we could save some memory and allocate RGB only but then we'd need to + * re-arrange the colors when copying to the face since MCol has odd ordering, + * so leave this as is - campbell */ +static unsigned char *calc_weightpaint_vert_array(Object *ob, int const draw_flag, ColorBand *coba) { Mesh *me = ob->data; - ColorBand *coba= stored_cb; /* warning, not a local var */ - - unsigned char *wtcol = MEM_mallocN (sizeof (unsigned char) * me->totface*4*4, "weightmap"); + unsigned char *wtcol_v = MEM_mallocN (sizeof(unsigned char) * me->totvert * 4, "weightmap_v"); if (me->dvert) { - MDeformVert *dvert= me->dvert; - MFace *mf = me->mface; + unsigned char *wc = wtcol_v; + MDeformVert *dv= me->dvert; + unsigned int i; + /* varisbles for multipaint */ const int defbase_tot = BLI_countlist(&ob->defbase); const int defbase_act = ob->actdef-1; char *dg_flags = MEM_mallocN(defbase_tot * sizeof(char), __func__); const int selected = get_selected_defgroups(ob, dg_flags, defbase_tot); /* const int unselected = defbase_tot - selected; */ /* UNUSED */ - int i; - - memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4); - for (i=0; i<me->totface; i++, mf++) { - unsigned int fidx= mf->v4 ? 3:2; - do { - calc_weightpaint_vert_color(&wtcol[(i*4 + fidx)*4], - &dvert[*(&mf->v1 + fidx)], coba, - defbase_tot, defbase_act, - dg_flags, selected, draw_flag); - } while (fidx--); + for (i = me->totvert; i != 0; i--, wc += 4, dv++) { + calc_weightpaint_vert_color(wc, dv, coba, defbase_tot, defbase_act, dg_flags, selected, draw_flag); } MEM_freeN(dg_flags); } else { - /* no weights, fill in zero */ int col_i; weightpaint_color((unsigned char *)&col_i, coba, 0.0f); - fill_vn_i((int *)wtcol, me->totface*4, col_i); + fill_vn_i((int *)wtcol_v, me->totvert, col_i); + } + + return wtcol_v; +} + +static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag) +{ + ColorBand *coba= stored_cb; /* warning, not a local var */ + + Mesh *me = ob->data; + unsigned char *wtcol_v = calc_weightpaint_vert_array(ob, draw_flag, coba); + unsigned char *wtcol_f = MEM_mallocN (sizeof(unsigned char) * me->totface*4*4, "weightmap_f"); + + MFace *mf = me->mface; + int i; + + for (i=0; i<me->totface; i++, mf++) { + unsigned int fidx= mf->v4 ? 3:2; + do { + copy_v4_v4_char((char *)&wtcol_f[(4 * i + fidx) * 4], + (char *)&wtcol_v[4 * (*(&mf->v1 + fidx))]); + } while (fidx--); } - CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData); + MEM_freeN(wtcol_v); + + CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol_f, dm->numFaceData); } /* new value for useDeform -1 (hack for the gameengine): diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index f09be8c34ad..5a389019519 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -239,7 +239,14 @@ int modifier_couldBeCage(struct Scene *scene, ModifierData *md) int modifier_sameTopology(ModifierData *md) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); - return ( mti->type == eModifierTypeType_OnlyDeform || mti->type == eModifierTypeType_Nonconstructive); + return ELEM3(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_Nonconstructive, + eModifierTypeType_NonGeometrical); +} + +int modifier_nonGeometrical(ModifierData *md) +{ + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + return (mti->type == eModifierTypeType_NonGeometrical); } void modifier_setError(ModifierData *md, const char *format, ...) diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index cc49e8465b9..ce1dd429794 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1325,32 +1325,6 @@ void nodeSetActive(bNodeTree *ntree, bNode *node) node->flag |= NODE_ACTIVE_TEXTURE; } -/* use flags are not persistent yet, groups might need different tagging, so we do it each time - when we need to get this info */ -void ntreeSocketUseFlags(bNodeTree *ntree) -{ - bNode *node; - bNodeSocket *sock; - bNodeLink *link; - - /* clear flags */ - for(node= ntree->nodes.first; node; node= node->next) { - for(sock= node->inputs.first; sock; sock= sock->next) - sock->flag &= ~SOCK_IN_USE; - for(sock= node->outputs.first; sock; sock= sock->next) - sock->flag &= ~SOCK_IN_USE; - } - - /* tag all thats in use */ - for(link= ntree->links.first; link; link= link->next) { - - if(link->fromsock) // FIXME, see below - link->fromsock->flag |= SOCK_IN_USE; - if(link->tosock) // FIXME This can be NULL, when dragging a new link in the UI, should probably copy the node tree for preview render - campbell - link->tosock->flag |= SOCK_IN_USE; - } -} - /* ************** dependency stuff *********** */ /* node is guaranteed to be not checked before */ @@ -1425,16 +1399,27 @@ static void ntree_update_link_pointers(bNodeTree *ntree) /* first clear data */ for(node= ntree->nodes.first; node; node= node->next) { - for(sock= node->inputs.first; sock; sock= sock->next) + for(sock= node->inputs.first; sock; sock= sock->next) { sock->link= NULL; + sock->flag &= ~SOCK_IN_USE; + } + for(sock= node->outputs.first; sock; sock= sock->next) { + sock->flag &= ~SOCK_IN_USE; + } + } + for(sock= ntree->inputs.first; sock; sock= sock->next) { + sock->flag &= ~SOCK_IN_USE; } - /* clear socket links */ - for(sock= ntree->outputs.first; sock; sock= sock->next) + for(sock= ntree->outputs.first; sock; sock= sock->next) { sock->link= NULL; + sock->flag &= ~SOCK_IN_USE; + } for(link= ntree->links.first; link; link= link->next) { - if (link->tosock) - link->tosock->link= link; + link->tosock->link= link; + + link->fromsock->flag |= SOCK_IN_USE; + link->tosock->flag |= SOCK_IN_USE; } } diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 93404dc25fb..7051376a1f4 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -349,9 +349,9 @@ ColorBand *add_colorband(int rangetype) /* ------------------------------------------------------------------------- */ -int do_colorband(ColorBand *coba, float in, float out[4]) +int do_colorband(const ColorBand *coba, float in, float out[4]) { - CBData *cbd1, *cbd2, *cbd0, *cbd3; + const CBData *cbd1, *cbd2, *cbd0, *cbd3; float fac, mfac, t[4]; int a; diff --git a/source/blender/blenlib/BLI_dynstr.h b/source/blender/blenlib/BLI_dynstr.h index e27a315a023..32c4e012d1d 100644 --- a/source/blender/blenlib/BLI_dynstr.h +++ b/source/blender/blenlib/BLI_dynstr.h @@ -100,6 +100,17 @@ int BLI_dynstr_get_len (DynStr *ds); */ char* BLI_dynstr_get_cstring (DynStr *ds); +/** + * Get a DynStr's contents as a c-string. + * <i> The str argument must be allocated to be at + * least the size of BLI_dynstr_get_len(ds) + 1. </i> + * + * @param ds The DynStr of interest. + * @param str The string to fill. + * @return The contents of @a ds as a c-string. + */ +void BLI_dynstr_get_cstring_ex (DynStr *ds, char *str); + /** * Free the DynStr * diff --git a/source/blender/blenlib/intern/BLI_dynstr.c b/source/blender/blenlib/intern/BLI_dynstr.c index 349bc3492e7..ad52de180aa 100644 --- a/source/blender/blenlib/intern/BLI_dynstr.c +++ b/source/blender/blenlib/intern/BLI_dynstr.c @@ -226,11 +226,11 @@ int BLI_dynstr_get_len(DynStr *ds) return ds->curlen; } -char *BLI_dynstr_get_cstring(DynStr *ds) +void BLI_dynstr_get_cstring_ex(DynStr *ds, char *rets) { - char *s, *rets= MEM_mallocN(ds->curlen+1, "dynstr_cstring"); + char *s; DynStrElem *dse; - + for (s= rets, dse= ds->elems; dse; dse= dse->next) { int slen= strlen(dse->str); @@ -239,7 +239,12 @@ char *BLI_dynstr_get_cstring(DynStr *ds) s+= slen; } rets[ds->curlen]= '\0'; - +} + +char *BLI_dynstr_get_cstring(DynStr *ds) +{ + char *rets= MEM_mallocN(ds->curlen+1, "dynstr_cstring"); + BLI_dynstr_get_cstring_ex(ds, rets); return rets; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ab362fba143..8c96e4fa377 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7459,6 +7459,30 @@ void do_versions_image_settings_2_60(Scene *sce) } +/* socket use flags were only temporary before */ +static void do_versions_nodetree_socket_use_flags_2_62(bNodeTree *ntree) +{ + bNode *node; + bNodeSocket *sock; + bNodeLink *link; + + for (node=ntree->nodes.first; node; node=node->next) { + for (sock=node->inputs.first; sock; sock=sock->next) + sock->flag &= ~SOCK_IN_USE; + for (sock=node->outputs.first; sock; sock=sock->next) + sock->flag &= ~SOCK_IN_USE; + } + for (sock=ntree->inputs.first; sock; sock=sock->next) + sock->flag &= ~SOCK_IN_USE; + for (sock=ntree->outputs.first; sock; sock=sock->next) + sock->flag &= ~SOCK_IN_USE; + + for (link=ntree->links.first; link; link=link->next) { + link->fromsock->flag |= SOCK_IN_USE; + link->tosock->flag |= SOCK_IN_USE; + } +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -12688,40 +12712,82 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* put compatibility code here until next subversion bump */ { - MovieClip *clip; - Object *ob; + { + /* update use flags for node sockets (was only temporary before) */ + Scene *sce; + Material *mat; + Tex *tex; + Lamp *lamp; + World *world; + bNodeTree *ntree; - for (clip= main->movieclip.first; clip; clip= clip->id.next) { - MovieTracking *tracking= &clip->tracking; - MovieTrackingObject *tracking_object= tracking->objects.first; + for (sce=main->scene.first; sce; sce=sce->id.next) + if (sce->nodetree) + do_versions_nodetree_socket_use_flags_2_62(sce->nodetree); - if(!tracking->settings.object_distance) - tracking->settings.object_distance= 1.0f; + for (mat=main->mat.first; mat; mat=mat->id.next) + if (mat->nodetree) + do_versions_nodetree_socket_use_flags_2_62(mat->nodetree); + + for (tex=main->tex.first; tex; tex=tex->id.next) + if (tex->nodetree) + do_versions_nodetree_socket_use_flags_2_62(tex->nodetree); - if(tracking->objects.first == NULL) - BKE_tracking_new_object(tracking, "Camera"); + for (lamp=main->lamp.first; lamp; lamp=lamp->id.next) + if (lamp->nodetree) + do_versions_nodetree_socket_use_flags_2_62(lamp->nodetree); - while(tracking_object) { - if(!tracking_object->scale) - tracking_object->scale= 1.0f; + for (world=main->world.first; world; world=world->id.next) + if (world->nodetree) + do_versions_nodetree_socket_use_flags_2_62(world->nodetree); - tracking_object= tracking_object->next; + for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) + do_versions_nodetree_socket_use_flags_2_62(ntree); + } + { + /* Initialize BGE exit key to esc key */ + Scene *scene; + for(scene= main->scene.first; scene; scene= scene->id.next) { + if (!scene->gm.exitkey) + scene->gm.exitkey = 218; // Blender key code for ESC } } + { + MovieClip *clip; + Object *ob; - for (ob= main->object.first; ob; ob= ob->id.next) { - bConstraint *con; - for (con= ob->constraints.first; con; con=con->next) { - bConstraintTypeInfo *cti= constraint_get_typeinfo(con); + for (clip= main->movieclip.first; clip; clip= clip->id.next) { + MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *tracking_object= tracking->objects.first; + + if(!tracking->settings.object_distance) + tracking->settings.object_distance= 1.0f; + + if(tracking->objects.first == NULL) + BKE_tracking_new_object(tracking, "Camera"); + + while(tracking_object) { + if(!tracking_object->scale) + tracking_object->scale= 1.0f; + + tracking_object= tracking_object->next; + } + } + + for (ob= main->object.first; ob; ob= ob->id.next) { + bConstraint *con; + for (con= ob->constraints.first; con; con=con->next) { + bConstraintTypeInfo *cti= constraint_get_typeinfo(con); - if(!cti) - continue; + if(!cti) + continue; - if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) { - bObjectSolverConstraint *data= (bObjectSolverConstraint *)con->data; + if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) { + bObjectSolverConstraint *data= (bObjectSolverConstraint *)con->data; - if(data->invmat[3][3]==0.0f) - unit_m4(data->invmat); + if(data->invmat[3][3]==0.0f) + unit_m4(data->invmat); + } } } } diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index f75f2921e51..3a69db013c0 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -243,6 +243,19 @@ int ED_mesh_color_add(struct bContext *C, struct Scene *scene, struct Object *ob int ED_mesh_color_remove(struct bContext *C, struct Object *ob, struct Mesh *me); int ED_mesh_color_remove_named(struct bContext *C, struct Object *ob, struct Mesh *me, const char *name); + +/* mirrtopo */ +typedef struct MirrTopoStore_t { + intptr_t *index_lookup; + int prev_vert_tot; + int prev_edge_tot; + int prev_ob_mode; +} MirrTopoStore_t; + +int ED_mesh_mirrtopo_recalc_check(struct Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store); +void ED_mesh_mirrtopo_init(struct Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store); +void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store); + #ifdef __cplusplus } #endif diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index ea45337ddb3..9853c9c049b 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -845,7 +845,7 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob, Modif uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT); uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply"), 0, "apply_as", MODIFIER_APPLY_DATA); - if (modifier_sameTopology(md)) + if (modifier_sameTopology(md) && !modifier_nonGeometrical(md)) uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply as Shape"), 0, "apply_as", MODIFIER_APPLY_SHAPE); } @@ -853,7 +853,7 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob, Modif uiBlockSetButLock(block, ob && ob->id.lib, ERROR_LIBDATA_MESSAGE); if (!ELEM5(md->type, eModifierType_Fluidsim, eModifierType_Softbody, eModifierType_ParticleSystem, eModifierType_Cloth, eModifierType_Smoke)) - uiItemO(row, TIP_("Copy"), ICON_NONE, "OBJECT_OT_modifier_copy"); + uiItemO(row, IFACE_("Copy"), ICON_NONE, "OBJECT_OT_modifier_copy"); } /* result is the layout block inside the box, that we return so that modifier settings can be drawn */ diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 02d20e64bc3..95c71488d26 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -815,3 +815,229 @@ int do_paintface_box_select(ViewContext *vc, rcti *rect, int select, int extend) return OPERATOR_FINISHED; } + + +/* ********************* MESH VERTEX MIRR TOPO LOOKUP *************** */ +/* note, this is not the best place for the function to be but moved + * here to for the purpose of syncing with bmesh */ + +typedef int MirrTopoHash_t; + +typedef struct MirrTopoPair_t { + MirrTopoHash_t hash; + int v_index; +} MirrTopoPair_t; + +static int MirrTopo_long_sort(const void *l1, const void *l2) +{ + if ((MirrTopoHash_t)(intptr_t)l1 > (MirrTopoHash_t)(intptr_t)l2 ) return 1; + else if ((MirrTopoHash_t)(intptr_t)l1 < (MirrTopoHash_t)(intptr_t)l2 ) return -1; + return 0; +} + +static int MirrTopo_item_sort(const void *v1, const void *v2) +{ + if (((MirrTopoPair_t *)v1)->hash > ((MirrTopoPair_t *)v2)->hash ) return 1; + else if (((MirrTopoPair_t *)v1)->hash < ((MirrTopoPair_t *)v2)->hash ) return -1; + return 0; +} + +int ED_mesh_mirrtopo_recalc_check(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store) +{ + int totvert; + int totedge; + + if (me->edit_mesh) { + totvert= me->edit_mesh->totvert; + totedge= me->edit_mesh->totedge; + } + else { + totvert= me->totvert; + totedge= me->totedge; + } + + if( (mesh_topo_store->index_lookup==NULL) || + (mesh_topo_store->prev_ob_mode != ob_mode) || + (totvert != mesh_topo_store->prev_vert_tot) || + (totedge != mesh_topo_store->prev_edge_tot)) + { + return TRUE; + } + else { + return FALSE; + } + +} + +void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store) +{ + MEdge *medge; + EditMesh *em= me->edit_mesh; + void **eve_tmp_back= NULL; /* some of the callers are using eve->tmp so restore after */ + + /* editmode*/ + EditEdge *eed; + + int a, last; + int totvert, totedge; + int totUnique= -1, totUniqueOld= -1; + + MirrTopoHash_t *MirrTopoHash = NULL; + MirrTopoHash_t *MirrTopoHash_Prev = NULL; + MirrTopoPair_t *MirrTopoPairs; + + /* reallocate if needed */ + ED_mesh_mirrtopo_free(mesh_topo_store); + + mesh_topo_store->prev_ob_mode= ob_mode; + + if(em) { + EditVert *eve; + totvert= 0; + eve_tmp_back= MEM_callocN( em->totvert * sizeof(void *), "TopoMirr" ); + for(eve= em->verts.first; eve; eve= eve->next) { + eve_tmp_back[totvert]= eve->tmp.p; + eve->tmp.l = totvert++; + } + } + else { + totvert = me->totvert; + } + + MirrTopoHash = MEM_callocN( totvert * sizeof(MirrTopoHash_t), "TopoMirr" ); + + /* Initialize the vert-edge-user counts used to detect unique topology */ + if(em) { + totedge= 0; + + for(eed=em->edges.first; eed; eed= eed->next, totedge++) { + MirrTopoHash[eed->v1->tmp.l]++; + MirrTopoHash[eed->v2->tmp.l]++; + } + } else { + totedge= me->totedge; + + for(a=0, medge=me->medge; a < me->totedge; a++, medge++) { + MirrTopoHash[medge->v1]++; + MirrTopoHash[medge->v2]++; + } + } + + MirrTopoHash_Prev = MEM_dupallocN( MirrTopoHash ); + + totUniqueOld = -1; + while(1) { + /* use the number of edges per vert to give verts unique topology IDs */ + + if(em) { + for(eed=em->edges.first; eed; eed= eed->next) { + MirrTopoHash[eed->v1->tmp.l] += MirrTopoHash_Prev[eed->v2->tmp.l]; + MirrTopoHash[eed->v2->tmp.l] += MirrTopoHash_Prev[eed->v1->tmp.l]; + } + } else { + for(a=0, medge=me->medge; a<me->totedge; a++, medge++) { + /* This can make really big numbers, wrapping around here is fine */ + MirrTopoHash[medge->v1] += MirrTopoHash_Prev[medge->v2]; + MirrTopoHash[medge->v2] += MirrTopoHash_Prev[medge->v1]; + } + } + memcpy(MirrTopoHash_Prev, MirrTopoHash, sizeof(MirrTopoHash_t) * totvert); + + /* sort so we can count unique values */ + qsort(MirrTopoHash_Prev, totvert, sizeof(MirrTopoHash_t), MirrTopo_long_sort); + + totUnique = 1; /* account for skiping the first value */ + for(a=1; a<totvert; a++) { + if (MirrTopoHash_Prev[a-1] != MirrTopoHash_Prev[a]) { + totUnique++; + } + } + + if (totUnique <= totUniqueOld) { + /* Finish searching for unique valus when 1 loop dosnt give a + * higher number of unique values compared to the previous loop */ + break; + } else { + totUniqueOld = totUnique; + } + /* Copy the hash calculated this iter, so we can use them next time */ + memcpy(MirrTopoHash_Prev, MirrTopoHash, sizeof(MirrTopoHash_t) * totvert); + } + + /* restore eve->tmp.* */ + if(eve_tmp_back) { + EditVert *eve; + totvert= 0; + for(eve= em->verts.first; eve; eve= eve->next) { + eve->tmp.p= eve_tmp_back[totvert++]; + } + + MEM_freeN(eve_tmp_back); + eve_tmp_back= NULL; + } + + + /* Hash/Index pairs are needed for sorting to find index pairs */ + MirrTopoPairs= MEM_callocN( sizeof(MirrTopoPair_t) * totvert, "MirrTopoPairs"); + + /* since we are looping through verts, initialize these values here too */ + mesh_topo_store->index_lookup = MEM_mallocN( totvert * sizeof(long), "mesh_topo_lookup" ); + + if(em) { + EM_init_index_arrays(em,1,0,0); + } + + + for(a=0; a<totvert; a++) { + MirrTopoPairs[a].hash= MirrTopoHash[a]; + MirrTopoPairs[a].v_index = a; + + /* initialize lookup */ + mesh_topo_store->index_lookup[a] = -1; + } + + qsort(MirrTopoPairs, totvert, sizeof(MirrTopoPair_t), MirrTopo_item_sort); + + /* Since the loop starts at 2, we must define the last index where the hash's differ */ + last = ((totvert >= 2) && (MirrTopoPairs[0].hash == MirrTopoPairs[1].hash)) ? 0 : 1; + + /* Get the pairs out of the sorted hashes, note, totvert+1 means we can use the previous 2, + * but you cant ever access the last 'a' index of MirrTopoPairs */ + for(a=2; a <= totvert; a++) { + /* printf("I %d %ld %d\n", (a-last), MirrTopoPairs[a ].hash, MirrTopoPairs[a ].vIndex ); */ + if ((a==totvert) || (MirrTopoPairs[a-1].hash != MirrTopoPairs[a].hash)) { + if (a-last==2) { + if(em) { + mesh_topo_store->index_lookup[MirrTopoPairs[a-1].v_index] = (intptr_t)EM_get_vert_for_index(MirrTopoPairs[a-2].v_index); + mesh_topo_store->index_lookup[MirrTopoPairs[a-2].v_index] = (intptr_t)EM_get_vert_for_index(MirrTopoPairs[a-1].v_index); + } else { + mesh_topo_store->index_lookup[MirrTopoPairs[a-1].v_index] = MirrTopoPairs[a-2].v_index; + mesh_topo_store->index_lookup[MirrTopoPairs[a-2].v_index] = MirrTopoPairs[a-1].v_index; + } + } + last= a; + } + } + if(em) { + EM_free_index_arrays(); + } + + MEM_freeN( MirrTopoPairs ); + MirrTopoPairs = NULL; + + MEM_freeN( MirrTopoHash ); + MEM_freeN( MirrTopoHash_Prev ); + + mesh_topo_store->prev_vert_tot = totvert; + mesh_topo_store->prev_edge_tot = totedge; +} + +void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store) +{ + if (mesh_topo_store->index_lookup) { + MEM_freeN(mesh_topo_store->index_lookup); + } + mesh_topo_store->index_lookup = NULL; + mesh_topo_store->prev_vert_tot = -1; + mesh_topo_store->prev_edge_tot = -1; +} diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index dd82f055f14..77daf21affa 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -765,7 +765,7 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode) if(mode=='u') { /* use table */ if(MeshOctree.table==NULL) mesh_octree_table(ob, em, NULL, 's'); - + if(MeshOctree.table) { Mesh *me= ob->data; bt= MeshOctree.table + mesh_octree_get_base_offs(co, MeshOctree.offs, MeshOctree.div); @@ -848,34 +848,7 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode) return 0; } - -/* ********************* MESH VERTEX MIRR TOPO LOOKUP *************** */ - -typedef int MirrTopoHash_t; - -typedef struct MirrTopoPair_t { - MirrTopoHash_t hash; - int vIndex; -} MirrTopoPair_t; - -static int MirrTopo_long_sort(const void *l1, const void *l2) -{ - if ((MirrTopoHash_t)(intptr_t)l1 > (MirrTopoHash_t)(intptr_t)l2 ) return 1; - else if ((MirrTopoHash_t)(intptr_t)l1 < (MirrTopoHash_t)(intptr_t)l2 ) return -1; - return 0; -} - -static int MirrTopo_item_sort(const void *v1, const void *v2) -{ - if (((MirrTopoPair_t *)v1)->hash > ((MirrTopoPair_t *)v2)->hash ) return 1; - else if (((MirrTopoPair_t *)v1)->hash < ((MirrTopoPair_t *)v2)->hash ) return -1; - return 0; -} - -static intptr_t *mesh_topo_lookup = NULL; -static int mesh_topo_lookup_vert_tot = -1; -static int mesh_topo_lookup_edge_tot = -1; -static int mesh_topo_lookup_mode = -1; +MirrTopoStore_t mesh_topo_store= {NULL, -1. -1, -1}; /* mode is 's' start, or 'e' end, or 'u' use */ /* if end, ob can be NULL */ @@ -883,188 +856,15 @@ static int mesh_topo_lookup_mode = -1; int mesh_mirrtopo_table(Object *ob, char mode) { if(mode=='u') { /* use table */ - Mesh *me= ob->data; - if( (mesh_topo_lookup==NULL) || - (mesh_topo_lookup_mode != ob->mode) || - (me->edit_mesh && (me->edit_mesh->totvert != mesh_topo_lookup_vert_tot)) || - (me->edit_mesh && (me->edit_mesh->totedge != mesh_topo_lookup_edge_tot)) || - (me->edit_mesh==NULL && me->totvert != mesh_topo_lookup_vert_tot) || - (me->edit_mesh==NULL && me->totedge != mesh_topo_lookup_edge_tot) - ) { + if (ED_mesh_mirrtopo_recalc_check(ob->data, ob->mode, &mesh_topo_store)) { mesh_mirrtopo_table(ob, 's'); } - } else if(mode=='s') { /* start table */ - Mesh *me= ob->data; - MEdge *medge; - EditMesh *em= me->edit_mesh; - void **eve_tmp_back= NULL; /* some of the callers are using eve->tmp so restore after */ - - - /* editmode*/ - EditEdge *eed; - - int a, last; - int totvert, totedge; - int totUnique= -1, totUniqueOld= -1; - - MirrTopoHash_t *MirrTopoHash = NULL; - MirrTopoHash_t *MirrTopoHash_Prev = NULL; - MirrTopoPair_t *MirrTopoPairs; - mesh_topo_lookup_mode= ob->mode; - - /* reallocate if needed */ - if (mesh_topo_lookup) { - MEM_freeN(mesh_topo_lookup); - mesh_topo_lookup = NULL; - } - - if(em) { - EditVert *eve; - totvert= 0; - eve_tmp_back= MEM_callocN( em->totvert * sizeof(void *), "TopoMirr" ); - for(eve= em->verts.first; eve; eve= eve->next) { - eve_tmp_back[totvert]= eve->tmp.p; - eve->tmp.l = totvert++; - } - } - else { - totvert = me->totvert; - } - - MirrTopoHash = MEM_callocN( totvert * sizeof(MirrTopoHash_t), "TopoMirr" ); - - /* Initialize the vert-edge-user counts used to detect unique topology */ - if(em) { - totedge= 0; - - for(eed=em->edges.first; eed; eed= eed->next, totedge++) { - MirrTopoHash[eed->v1->tmp.l]++; - MirrTopoHash[eed->v2->tmp.l]++; - } - } else { - totedge= me->totedge; - - for(a=0, medge=me->medge; a < me->totedge; a++, medge++) { - MirrTopoHash[medge->v1]++; - MirrTopoHash[medge->v2]++; - } - } - - MirrTopoHash_Prev = MEM_dupallocN( MirrTopoHash ); - - totUniqueOld = -1; - while(1) { - /* use the number of edges per vert to give verts unique topology IDs */ - - if(em) { - for(eed=em->edges.first; eed; eed= eed->next) { - MirrTopoHash[eed->v1->tmp.l] += MirrTopoHash_Prev[eed->v2->tmp.l]; - MirrTopoHash[eed->v2->tmp.l] += MirrTopoHash_Prev[eed->v1->tmp.l]; - } - } else { - for(a=0, medge=me->medge; a<me->totedge; a++, medge++) { - /* This can make really big numbers, wrapping around here is fine */ - MirrTopoHash[medge->v1] += MirrTopoHash_Prev[medge->v2]; - MirrTopoHash[medge->v2] += MirrTopoHash_Prev[medge->v1]; - } - } - memcpy(MirrTopoHash_Prev, MirrTopoHash, sizeof(MirrTopoHash_t) * totvert); - - /* sort so we can count unique values */ - qsort(MirrTopoHash_Prev, totvert, sizeof(MirrTopoHash_t), MirrTopo_long_sort); - - totUnique = 1; /* account for skiping the first value */ - for(a=1; a<totvert; a++) { - if (MirrTopoHash_Prev[a-1] != MirrTopoHash_Prev[a]) { - totUnique++; - } - } - - if (totUnique <= totUniqueOld) { - /* Finish searching for unique valus when 1 loop dosnt give a - * higher number of unique values compared to the previous loop */ - break; - } else { - totUniqueOld = totUnique; - } - /* Copy the hash calculated this iter, so we can use them next time */ - memcpy(MirrTopoHash_Prev, MirrTopoHash, sizeof(MirrTopoHash_t) * totvert); - } - - /* restore eve->tmp.* */ - if(eve_tmp_back) { - EditVert *eve; - totvert= 0; - for(eve= em->verts.first; eve; eve= eve->next) { - eve->tmp.p= eve_tmp_back[totvert++]; - } - - MEM_freeN(eve_tmp_back); - eve_tmp_back= NULL; - } - - - /* Hash/Index pairs are needed for sorting to find index pairs */ - MirrTopoPairs= MEM_callocN( sizeof(MirrTopoPair_t) * totvert, "MirrTopoPairs"); - - /* since we are looping through verts, initialize these values here too */ - mesh_topo_lookup = MEM_mallocN( totvert * sizeof(long), "mesh_topo_lookup" ); - - if(em) { - EM_init_index_arrays(em,1,0,0); - } - - - for(a=0; a<totvert; a++) { - MirrTopoPairs[a].hash= MirrTopoHash[a]; - MirrTopoPairs[a].vIndex = a; - - /* initialize lookup */ - mesh_topo_lookup[a] = -1; - } - - qsort(MirrTopoPairs, totvert, sizeof(MirrTopoPair_t), MirrTopo_item_sort); - - /* Since the loop starts at 2, we must define the last index where the hash's differ */ - last = ((totvert >= 2) && (MirrTopoPairs[0].hash == MirrTopoPairs[1].hash)) ? 0 : 1; - - /* Get the pairs out of the sorted hashes, note, totvert+1 means we can use the previous 2, - * but you cant ever access the last 'a' index of MirrTopoPairs */ - for(a=2; a < totvert+1; a++) { - /* printf("I %d %ld %d\n", (a-last), MirrTopoPairs[a ].hash, MirrTopoPairs[a ].vIndex ); */ - if ((a==totvert) || (MirrTopoPairs[a-1].hash != MirrTopoPairs[a].hash)) { - if (a-last==2) { - if(em) { - mesh_topo_lookup[MirrTopoPairs[a-1].vIndex] = (intptr_t)EM_get_vert_for_index(MirrTopoPairs[a-2].vIndex); - mesh_topo_lookup[MirrTopoPairs[a-2].vIndex] = (intptr_t)EM_get_vert_for_index(MirrTopoPairs[a-1].vIndex); - } else { - mesh_topo_lookup[MirrTopoPairs[a-1].vIndex] = MirrTopoPairs[a-2].vIndex; - mesh_topo_lookup[MirrTopoPairs[a-2].vIndex] = MirrTopoPairs[a-1].vIndex; - } - } - last= a; - } - } - if(em) { - EM_free_index_arrays(); - } - - MEM_freeN( MirrTopoPairs ); - MirrTopoPairs = NULL; - - MEM_freeN( MirrTopoHash ); - MEM_freeN( MirrTopoHash_Prev ); - - mesh_topo_lookup_vert_tot = totvert; - mesh_topo_lookup_edge_tot = totedge; - - } else if(mode=='e') { /* end table */ - if (mesh_topo_lookup) { - MEM_freeN(mesh_topo_lookup); - } - mesh_topo_lookup = NULL; - mesh_topo_lookup_vert_tot= -1; - mesh_topo_lookup_edge_tot= -1; + } + else if(mode=='s') { /* start table */ + ED_mesh_mirrtopo_init(ob->data, ob->mode, &mesh_topo_store); + } + else if(mode=='e') { /* end table */ + ED_mesh_mirrtopo_free(&mesh_topo_store); } return 0; } @@ -1088,7 +888,7 @@ static int mesh_get_x_mirror_vert_topo(Object *ob, int index) if (mesh_mirrtopo_table(ob, 'u')==-1) return -1; - return mesh_topo_lookup[index]; + return mesh_topo_store.index_lookup[index]; } int mesh_get_x_mirror_vert(Object *ob, int index) @@ -1136,7 +936,7 @@ static EditVert *editmesh_get_x_mirror_vert_topo(Object *ob, struct EditMesh *em } } - poinval= mesh_topo_lookup[ index ]; + poinval= mesh_topo_store.index_lookup[index]; if(poinval != -1) return (EditVert *)(poinval); diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 240fb8017f2..913e5893a77 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -452,7 +452,7 @@ static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, M Key *key=me->key; KeyBlock *kb; - if(!modifier_sameTopology(md)) { + if(!modifier_sameTopology(md) || mti->type == eModifierTypeType_NonGeometrical) { BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to Shapes"); return 0; } @@ -500,7 +500,7 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, Mesh *me = ob->data; MultiresModifierData *mmd= find_multires_modifier_before(scene, md); - if( me->key) { + if(me->key && mti->type != eModifierTypeType_NonGeometrical) { BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to Mesh with Shape Keys"); return 0; } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 007a8f7e4d7..1c34df5393a 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1293,6 +1293,7 @@ static void area_split_exit(bContext *C, wmOperator *op) op->customdata = NULL; } + WM_cursor_restore(CTX_wm_window(C)); WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); /* this makes sure aligned edges will result in aligned grabbing */ @@ -1491,6 +1492,37 @@ static int area_split_modal(bContext *C, wmOperator *op, wmEvent *event) } } break; + + case MIDDLEMOUSE: + case TABKEY: + if (sd->previewmode==0){ + } + else{ + dir = RNA_enum_get(op->ptr, "direction"); + + if(event->val==KM_PRESS){ + if (sd->sarea){ + sd->sarea->flag &= ~(AREA_FLAG_DRAWSPLIT_H|AREA_FLAG_DRAWSPLIT_V); + ED_area_tag_redraw(sd->sarea); + + if (dir=='v'){ + RNA_enum_set(op->ptr, "direction", 'h'); + sd->sarea->flag |= AREA_FLAG_DRAWSPLIT_H; + + WM_cursor_set(CTX_wm_window(C),CURSOR_X_MOVE); + } + else{ + RNA_enum_set(op->ptr, "direction", 'v'); + sd->sarea->flag |= AREA_FLAG_DRAWSPLIT_V; + + WM_cursor_set(CTX_wm_window(C),CURSOR_Y_MOVE); + } + } + } + } + + break; + case RIGHTMOUSE: /* cancel operation */ case ESCKEY: return area_split_cancel(C, op); diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 2d0ad349be8..eb20465a2ab 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -605,9 +605,13 @@ void ED_keymap_paint(wmKeyConfig *keyconf) ed_keymap_paint_brush_size(keymap, "tool_settings.weight_paint.brush.size"); ed_keymap_paint_brush_radial_control(keymap, "weight_paint", 0); - kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* mask toggle */ + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* face mask toggle */ RNA_string_set(kmi->ptr, "data_path", "weight_paint_object.data.use_paint_mask"); + /* note, conflicts with vertex paint, but this is more useful */ + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", VKEY, KM_PRESS, 0, 0); /* vert mask toggle */ + RNA_string_set(kmi->ptr, "data_path", "weight_paint_object.data.use_paint_mask_vertex"); + WM_keymap_verify_item(keymap, "PAINT_OT_weight_from_bones", WKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c index 15e5719be37..1b5f2417384 100644 --- a/source/blender/editors/space_node/node_buttons.c +++ b/source/blender/editors/space_node/node_buttons.c @@ -115,6 +115,9 @@ static void active_node_panel(const bContext *C, Panel *pa) uiItemS(layout); uiItemR(layout, &ptr, "name", 0, NULL, ICON_NODE); uiItemS(layout); + + uiItemO(layout, NULL, 0, "NODE_OT_hide_socket_toggle"); + uiItemS(layout); /* draw this node's settings */ if (node->typeinfo && node->typeinfo->uifuncbut) diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 08e073494bb..7b692f55965 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -351,10 +351,10 @@ static void node_update_hidden(bNode *node) /* calculate minimal radius */ for(nsock= node->inputs.first; nsock; nsock= nsock->next) - if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) + if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (nsock->flag & SOCK_IN_USE)) totin++; for(nsock= node->outputs.first; nsock; nsock= nsock->next) - if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) + if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (nsock->flag & SOCK_IN_USE)) totout++; tot= MAX2(totin, totout); @@ -371,7 +371,7 @@ static void node_update_hidden(bNode *node) rad=drad= (float)M_PI/(1.0f + (float)totout); for(nsock= node->outputs.first; nsock; nsock= nsock->next) { - if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { + if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (nsock->flag & SOCK_IN_USE)) { nsock->locx= node->totr.xmax - hiddenrad + (float)sin(rad)*hiddenrad; nsock->locy= node->totr.ymin + hiddenrad + (float)cos(rad)*hiddenrad; rad+= drad; @@ -382,7 +382,7 @@ static void node_update_hidden(bNode *node) rad=drad= - (float)M_PI/(1.0f + (float)totin); for(nsock= node->inputs.first; nsock; nsock= nsock->next) { - if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { + if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (nsock->flag & SOCK_IN_USE)) { nsock->locx= node->totr.xmin + hiddenrad + (float)sin(rad)*hiddenrad; nsock->locy= node->totr.ymin + hiddenrad + (float)cos(rad)*hiddenrad; rad+= drad; @@ -854,12 +854,12 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b /* sockets */ for(sock= node->inputs.first; sock; sock= sock->next) { - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) + if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (sock->flag & SOCK_IN_USE)) node_socket_circle_draw(snode->nodetree, sock, socket_size); } for(sock= node->outputs.first; sock; sock= sock->next) { - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) + if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (sock->flag & SOCK_IN_USE)) node_socket_circle_draw(snode->nodetree, sock, socket_size); } diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 16ee32d10a2..566659e0391 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -195,7 +195,6 @@ void TEXT_OT_new(wmOperatorType *ot) ot->description= "Create a new text data block"; /* api callbacks */ - ot->invoke= WM_operator_confirm; ot->exec= text_new_exec; ot->poll= text_new_poll; diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 6dd362b827f..e0b1741b0d0 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -70,6 +70,25 @@ #include "view3d_intern.h" // own include +/* user data structures for derived mesh callbacks */ +typedef struct drawMeshFaceSelect_userData { + Mesh *me; + EdgeHash *eh; +} drawMeshFaceSelect_userData; + +typedef struct drawEMTFMapped_userData { + EditMesh *em; + short has_mcol; + short has_mtface; + MFace *mf; + MTFace *tf; +} drawEMTFMapped_userData; + +typedef struct drawTFace_userData { + MFace *mf; + MTFace *tf; +} drawTFace_userData; + /**************************** Face Select Mode *******************************/ /* Flags for marked edges */ @@ -121,7 +140,7 @@ static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me) static int draw_mesh_face_select__setHiddenOpts(void *userData, int index) { - struct { Mesh *me; EdgeHash *eh; } *data = userData; + drawMeshFaceSelect_userData *data = userData; Mesh *me= data->me; MEdge *med = &me->medge[index]; uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2); @@ -138,7 +157,7 @@ static int draw_mesh_face_select__setHiddenOpts(void *userData, int index) static int draw_mesh_face_select__setSelectOpts(void *userData, int index) { - struct { Mesh *me; EdgeHash *eh; } *data = userData; + drawMeshFaceSelect_userData *data = userData; MEdge *med = &data->me->medge[index]; uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2); @@ -159,7 +178,7 @@ static int draw_mesh_face_select__drawFaceOptsInv(void *userData, int index) static void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm) { - struct { Mesh *me; EdgeHash *eh; } data; + drawMeshFaceSelect_userData data; data.me = me; data.eh = get_tface_mesh_marked_edge_info(me); @@ -513,7 +532,7 @@ static int draw_tface_mapped__set_draw(void *userData, int index) static int draw_em_tf_mapped__set_draw(void *userData, int index) { - struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data = userData; + drawEMTFMapped_userData *data = userData; EditMesh *em = data->em; EditFace *efa= EM_get_face_for_index(index); MTFace *tface; @@ -631,7 +650,7 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl) static int compareDrawOptions(void *userData, int cur_index, int next_index) { - struct { MFace *mf; MTFace *tf; } *data = userData; + drawTFace_userData *data = userData; if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr) return 0; @@ -644,7 +663,7 @@ static int compareDrawOptions(void *userData, int cur_index, int next_index) static int compareDrawOptionsEm(void *userData, int cur_index, int next_index) { - struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data= userData; + drawEMTFMapped_userData *data= userData; if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr) return 0; @@ -669,7 +688,7 @@ void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec glColor4f(1.0f,1.0f,1.0f,1.0f); if(ob->mode & OB_MODE_EDIT) { - struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} data; + drawEMTFMapped_userData data; data.em= me->edit_mesh; data.has_mcol= CustomData_has_layer(&me->edit_mesh->fdata, CD_MCOL); @@ -693,7 +712,7 @@ void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL); } else { - struct { MFace *mf; MTFace *tf; } userData; + drawTFace_userData userData; if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL)) add_tface_color_layer(dm); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index e3e551d67ee..7827569bd30 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -118,6 +118,48 @@ typedef enum eWireDrawMode { OBDRAW_WIRE_ON_DEPTH= 2 } eWireDrawMode; +/* user data structures for derived mesh callbacks */ +typedef struct foreachScreenVert_userData { + void (*func)(void *userData, EditVert *eve, int x, int y, int index); + void *userData; + ViewContext vc; + eV3DClipTest clipVerts; +} foreachScreenVert_userData; + +typedef struct foreachScreenEdge_userData { + void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); + void *userData; + ViewContext vc; + eV3DClipTest clipVerts; +} foreachScreenEdge_userData; + +typedef struct foreachScreenFace_userData { + void (*func)(void *userData, EditFace *efa, int x, int y, int index); + void *userData; + ViewContext vc; +} foreachScreenFace_userData; + +typedef struct drawDMVerts_userData { + int sel; + EditVert *eve_act; +} drawDMVerts_userData; + +typedef struct drawDMEdgesSel_userData { + unsigned char *baseCol, *selCol, *actCol; + EditEdge *eed_act; +} drawDMEdgesSel_userData; + +typedef struct drawDMFacesSel_userData { + unsigned char *cols[3]; + EditFace *efa_act; + int *orig_index; +} drawDMFacesSel_userData; + +typedef struct bbsObmodeMeshVerts_userData { + void *offset; + MVert *mvert; +} bbsObmodeMeshVerts_userData; + static void draw_bounding_volume(Scene *scene, Object *ob, char type); static void drawcube_size(float size); @@ -1944,9 +1986,7 @@ static void drawlattice(Scene *scene, View3D *v3d, Object *ob) * use the object matrix in the useual way */ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) { - struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); - void *userData; ViewContext vc; eV3DClipTest clipVerts; } *data = userData; - + foreachScreenVert_userData *data = userData; EditVert *eve = EM_get_vert_for_index(index); if (eve->h==0) { @@ -1968,9 +2008,7 @@ void mesh_foreachScreenVert( void (*func)(void *userData, EditVert *eve, int x, int y, int index), void *userData, eV3DClipTest clipVerts) { - struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); - void *userData; ViewContext vc; eV3DClipTest clipVerts; } data; - + foreachScreenVert_userData data; DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); data.vc= *vc; @@ -2024,8 +2062,7 @@ static int is_co_in_region(ARegion *ar, const short co[2]) } static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co) { - struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); - void *userData; ViewContext vc; eV3DClipTest clipVerts; } *data = userData; + foreachScreenEdge_userData *data = userData; EditEdge *eed = EM_get_edge_for_index(index); short s[2][2]; @@ -2056,8 +2093,7 @@ void mesh_foreachScreenEdge( void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, eV3DClipTest clipVerts) { - struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); - void *userData; ViewContext vc; eV3DClipTest clipVerts; } data; + foreachScreenEdge_userData data; DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); data.vc= *vc; @@ -2077,7 +2113,7 @@ void mesh_foreachScreenEdge( static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *cent, float *UNUSED(no)) { - struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ViewContext vc; } *data = userData; + foreachScreenFace_userData *data = userData; EditFace *efa = EM_get_face_for_index(index); short s[2]; @@ -2095,7 +2131,7 @@ void mesh_foreachScreenFace( void (*func)(void *userData, EditFace *efa, int x, int y, int index), void *userData) { - struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ViewContext vc; } data; + foreachScreenFace_userData data; DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); data.vc= *vc; @@ -2240,7 +2276,7 @@ static void draw_dm_vert_normals(Scene *scene, DerivedMesh *dm) /* Draw verts with color set based on selection */ static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) { - struct { int sel; EditVert *eve_act; } * data = userData; + drawDMVerts_userData * data = userData; EditVert *eve = EM_get_vert_for_index(index); if (eve->h==0 && (eve->f&SELECT)==data->sel) { @@ -2267,7 +2303,7 @@ static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float * static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act) { - struct { int sel; EditVert *eve_act; } data; + drawDMVerts_userData data; data.sel = sel; data.eve_act = eve_act; @@ -2281,7 +2317,7 @@ static int draw_dm_edges_sel__setDrawOptions(void *userData, int index) { EditEdge *eed = EM_get_edge_for_index(index); //unsigned char **cols = userData, *col; - struct { unsigned char *baseCol, *selCol, *actCol; EditEdge *eed_act; } * data = userData; + drawDMEdgesSel_userData * data = userData; unsigned char *col; if (eed->h==0) { @@ -2305,7 +2341,7 @@ static int draw_dm_edges_sel__setDrawOptions(void *userData, int index) } static void draw_dm_edges_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditEdge *eed_act) { - struct { unsigned char *baseCol, *selCol, *actCol; EditEdge *eed_act; } data; + drawDMEdgesSel_userData data; data.baseCol = baseCol; data.selCol = selCol; @@ -2379,7 +2415,7 @@ static void draw_dm_edges_sharp(DerivedMesh *dm) * return 2 for the active face so it renders with stipple enabled */ static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNUSED(drawSmooth_r)) { - struct { unsigned char *cols[3]; EditFace *efa_act; int *orig_index; } * data = userData; + drawDMFacesSel_userData * data = userData; EditFace *efa = EM_get_face_for_index(index); unsigned char *col; @@ -2399,7 +2435,7 @@ static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNU static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int next_index) { - struct { unsigned char *cols[3]; EditFace *efa_act; int *orig_index; } *data = userData; + drawDMFacesSel_userData *data = userData; EditFace *efa; EditFace *next_efa; unsigned char *col, *next_col; @@ -2428,7 +2464,7 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int /* also draws the active face */ static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditFace *efa_act) { - struct { unsigned char *cols[3]; EditFace *efa_act; int *orig_index; } data; + drawDMFacesSel_userData data; data.cols[0] = baseCol; data.cols[1] = selCol; data.cols[2] = actCol; @@ -6879,7 +6915,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) { - struct {void* offset; MVert *mvert;} *data = userData; + bbsObmodeMeshVerts_userData *data = userData; MVert *mv = &data->mvert[index]; int offset = (intptr_t) data->offset; @@ -6891,7 +6927,7 @@ static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, float *co, static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset) { - struct {void* offset; struct MVert *mvert;} data; + bbsObmodeMeshVerts_userData data; Mesh *me = ob->data; MVert *mvert = me->mvert; data.mvert = mvert; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 1b849754db8..345e78d70c9 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -576,7 +576,7 @@ typedef struct GameData { short mode, matmode; short occlusionRes; /* resolution of occlusion Z buffer in pixel */ short physicsEngine; - short pad[2]; + short exitkey, pad; short ticrate, maxlogicstep, physubstep, maxphystep; short obstacleSimulation, pad1; float levelHeight; diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h index 1e8a4574120..149393b6723 100644 --- a/source/blender/makesdna/DNA_world_types.h +++ b/source/blender/makesdna/DNA_world_types.h @@ -181,6 +181,7 @@ typedef struct World { #define TEXCO_ANGMAP 64 #define TEXCO_H_SPHEREMAP 256 #define TEXCO_H_TUBEMAP 1024 +#define TEXCO_EQUIRECTMAP 2048 /* mapto */ #define WOMAP_BLEND 1 diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index a682c329444..9638bba3e80 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1213,6 +1213,13 @@ static void rna_GameSettings_auto_start_set(PointerRNA *UNUSED(ptr), int value) G.fileflags &= ~G_FILE_AUTOPLAY; } +static void rna_GameSettings_exit_key_set(PointerRNA *ptr, int value) +{ + GameData *gm = (GameData*)ptr->data; + + if(ISKEYBOARD(value)) + gm->exitkey=value; +} static TimeMarker *rna_TimeLine_add(Scene *scene, const char name[]) { @@ -2103,6 +2110,13 @@ static void rna_def_scene_game_data(BlenderRNA *brna) RNA_def_property_range(prop, 8, 32); RNA_def_property_ui_text(prop, "Bits", "Display bit depth of full screen display"); RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "exit_key", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "exitkey"); + RNA_def_property_enum_items(prop, event_type_items); + RNA_def_property_enum_funcs(prop, NULL, "rna_GameSettings_exit_key_set", NULL); + RNA_def_property_ui_text(prop, "Exit Key", "Sets the key that exits the Game Engine"); + RNA_def_property_update(prop, NC_SCENE, NULL); // Do we need it here ? (since we already have it in World prop= RNA_def_property(srna, "frequency", PROP_INT, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index 840498249ea..087716adbe3 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -143,6 +143,7 @@ static void rna_def_world_mtex(BlenderRNA *brna) {TEXCO_GLOB, "GLOBAL", 0, "Global", "Use global coordinates for the texture coordinates (interior mist)"}, {TEXCO_ANGMAP, "ANGMAP", 0, "AngMap", "Use 360 degree angular coordinates, e.g. for spherical light probes"}, {TEXCO_H_SPHEREMAP, "SPHERE", 0, "Sphere", "For 360 degree panorama sky, spherical mapped, only top half"}, + {TEXCO_EQUIRECTMAP, "EQUIRECT", 0, "Equirectangular", "For 360 degree panorama sky, equirectangular mapping"}, {TEXCO_H_TUBEMAP, "TUBE", 0, "Tube", "For 360 degree panorama sky, cylindrical mapped, only top half"}, {TEXCO_OBJECT, "OBJECT", 0, "Object", "Use linked object's coordinates for texture coordinates"}, {0, NULL, 0, NULL, NULL}}; diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index 3146d1c9d5d..38c2073b6a5 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -290,7 +290,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, project_from_camera(tface->uv[0], coords[mf->v1], projectors[0].uci); project_from_camera(tface->uv[1], coords[mf->v2], projectors[0].uci); project_from_camera(tface->uv[2], coords[mf->v3], projectors[0].uci); - if(mf->v3) + if(mf->v4) project_from_camera(tface->uv[3], coords[mf->v4], projectors[0].uci); } else { @@ -343,7 +343,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, project_from_camera(tface->uv[0], coords[mf->v1], best_projector->uci); project_from_camera(tface->uv[1], coords[mf->v2], best_projector->uci); project_from_camera(tface->uv[2], coords[mf->v3], best_projector->uci); - if(mf->v3) + if(mf->v4) project_from_camera(tface->uv[3], coords[mf->v4], best_projector->uci); } else { @@ -407,7 +407,7 @@ ModifierTypeInfo modifierType_UVProject = { /* name */ "UVProject", /* structName */ "UVProjectModifierData", /* structSize */ sizeof(UVProjectModifierData), - /* type */ eModifierTypeType_Nonconstructive, + /* type */ eModifierTypeType_NonGeometrical, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index 24d80fe847c..bdd7ab7486b 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -177,10 +177,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md; - DerivedMesh *dm = derivedData, *ret = NULL; -#if 0 - Mesh *ob_m = NULL; -#endif + DerivedMesh *dm = derivedData; MDeformVert *dvert = NULL; MDeformWeight **dw = NULL; float *org_w; /* Array original weights. */ @@ -188,7 +185,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der int numVerts; int defgrp_idx; int i; - char rel_ret = 0; /* Boolean, whether we have to release ret dm or not, when not using it! */ /* Flags. */ int do_add = (wmd->edit_flags & MOD_WVG_EDIT_ADD2VG) != 0; int do_rem = (wmd->edit_flags & MOD_WVG_EDIT_REMFVG) != 0; @@ -207,49 +203,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der if (defgrp_idx < 0) return dm; - /* XXX All this to avoid copying dm when not needed... However, it nearly doubles compute - * time! See scene 5 of the WeighVG test file... - */ -#if 0 - /* Get actual dverts (ie vertex group data). */ - dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); - /* If no dverts, return unmodified data... */ - if (dvert == NULL) - return dm; - - /* Get org mesh, only to test whether affected cdata layer has already been copied - * somewhere up in the modifiers stack. - */ - ob_m = get_mesh(ob); - if (ob_m == NULL) - return dm; - - /* Create a copy of our dmesh, only if our affected cdata layer is the same as org mesh. */ - if (dvert == CustomData_get_layer(&ob_m->vdata, CD_MDEFORMVERT)) { - /* XXX Seems to create problems with weightpaint mode??? - * I'm missing something here, I guess... - */ -// DM_set_only_copy(dm, CD_MASK_MDEFORMVERT); /* Only copy defgroup layer. */ - ret = CDDM_copy(dm); - dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT); - if (dvert == NULL) { - ret->release(ret); - return dm; - } - rel_ret = 1; - } - else - ret = dm; -#else - ret = CDDM_copy(dm); - rel_ret = 1; - dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT); - if (dvert == NULL) { - if (rel_ret) - ret->release(ret); - return dm; - } -#endif + dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts); /* Get org weights, assuming 0.0 for vertices not in given vgroup. */ org_w = MEM_mallocN(sizeof(float) * numVerts, "WeightVGEdit Modifier, org_w"); @@ -271,7 +225,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der } /* Do masking. */ - weightvg_do_mask(numVerts, NULL, org_w, new_w, ob, ret, wmd->mask_constant, + weightvg_do_mask(numVerts, NULL, org_w, new_w, ob, dm, wmd->mask_constant, wmd->mask_defgrp_name, wmd->mask_texture, wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); @@ -285,7 +239,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der MEM_freeN(dw); /* Return the vgroup-modified mesh. */ - return ret; + return dm; } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, @@ -300,7 +254,7 @@ ModifierTypeInfo modifierType_WeightVGEdit = { /* name */ "VertexWeightEdit", /* structName */ "WeightVGEditModifierData", /* structSize */ sizeof(WeightVGEditModifierData), - /* type */ eModifierTypeType_Nonconstructive, + /* type */ eModifierTypeType_NonGeometrical, /* flags */ eModifierTypeFlag_AcceptsMesh /* |eModifierTypeFlag_SupportsMapping*/ |eModifierTypeFlag_SupportsEditmode, diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index 221deeef1a6..17316d891da 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -219,10 +219,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { WeightVGMixModifierData *wmd = (WeightVGMixModifierData*) md; - DerivedMesh *dm = derivedData, *ret = NULL; -#if 0 - Mesh *ob_m = NULL; -#endif + DerivedMesh *dm = derivedData; MDeformVert *dvert = NULL; MDeformWeight **dw1, **tdw1, **dw2, **tdw2; int numVerts; @@ -232,7 +229,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der int *tidx, *indices = NULL; int numIdx = 0; int i; - char rel_ret = 0; /* Boolean, whether we have to release ret dm or not, when not using it! */ /* Get number of verts. */ numVerts = dm->getNumVerts(dm); @@ -254,49 +250,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der return dm; } - /* XXX All this to avoid copying dm when not needed... However, it nearly doubles compute - * time! See scene 5 of the WeighVG test file... - */ -#if 0 - /* Get actual dverts (ie vertex group data). */ - dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); - /* If no dverts, return unmodified data... */ - if (dvert == NULL) - return dm; - - /* Get org mesh, only to test whether affected cdata layer has already been copied - * somewhere up in the modifiers stack. - */ - ob_m = get_mesh(ob); - if (ob_m == NULL) - return dm; - - /* Create a copy of our dmesh, only if our affected cdata layer is the same as org mesh. */ - if (dvert == CustomData_get_layer(&ob_m->vdata, CD_MDEFORMVERT)) { - /* XXX Seems to create problems with weightpaint mode??? - * I'm missing something here, I guess... - */ -// DM_set_only_copy(dm, CD_MASK_MDEFORMVERT); /* Only copy defgroup layer. */ - ret = CDDM_copy(dm); - dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT); - if (dvert == NULL) { - ret->release(ret); - return dm; - } - rel_ret = 1; - } - else - ret = dm; -#else - ret = CDDM_copy(dm); - rel_ret = 1; - dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT); - if (dvert == NULL) { - if (rel_ret) - ret->release(ret); - return dm; - } -#endif + dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts); /* Find out which vertices to work on. */ tidx = MEM_mallocN(sizeof(int) * numVerts, "WeightVGMix Modifier, tidx"); @@ -364,8 +318,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der MEM_freeN(tdw1); MEM_freeN(tdw2); MEM_freeN(tidx); - if (rel_ret) - ret->release(ret); return dm; } if (numIdx != -1) { @@ -400,7 +352,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der } /* Do masking. */ - weightvg_do_mask(numIdx, indices, org_w, new_w, ob, ret, wmd->mask_constant, + weightvg_do_mask(numIdx, indices, org_w, new_w, ob, dm, wmd->mask_constant, wmd->mask_defgrp_name, wmd->mask_texture, wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); @@ -419,7 +371,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der MEM_freeN(indices); /* Return the vgroup-modified mesh. */ - return ret; + return dm; } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, @@ -434,7 +386,7 @@ ModifierTypeInfo modifierType_WeightVGMix = { /* name */ "VertexWeightMix", /* structName */ "WeightVGMixModifierData", /* structSize */ sizeof(WeightVGMixModifierData), - /* type */ eModifierTypeType_Nonconstructive, + /* type */ eModifierTypeType_NonGeometrical, /* flags */ eModifierTypeFlag_AcceptsMesh /* |eModifierTypeFlag_SupportsMapping*/ |eModifierTypeFlag_SupportsEditmode, diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index af180b8a688..f67fd907d02 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -28,11 +28,17 @@ * \ingroup modifiers */ +#define DO_PROFILE 0 + #include "BLI_editVert.h" #include "BLI_math.h" #include "BLI_string.h" #include "BLI_utildefines.h" +#if DO_PROFILE + #include "PIL_time.h" +#endif + #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" @@ -334,10 +340,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData*) md; - DerivedMesh *dm = derivedData, *ret = NULL; -#if 0 - Mesh *ob_m = NULL; -#endif + DerivedMesh *dm = derivedData; MDeformVert *dvert = NULL; MDeformWeight **dw, **tdw; int numVerts; @@ -350,7 +353,10 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der int *tidx, *indices = NULL; int numIdx = 0; int i; - char rel_ret = 0; /* Boolean, whether we have to release ret dm or not, when not using it! */ + +#if DO_PROFILE + TIMEIT_START(perf) +#endif /* Get number of verts. */ numVerts = dm->getNumVerts(dm); @@ -371,49 +377,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der if (defgrp_idx < 0) return dm; - /* XXX All this to avoid copying dm when not needed... However, it nearly doubles compute - * time! See scene 5 of the WeighVG test file... - */ -#if 0 - /* Get actual dverts (ie vertex group data). */ - dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); - /* If no dverts, return unmodified data... */ - if (dvert == NULL) - return dm; - - /* Get org mesh, only to test whether affected cdata layer has already been copied - * somewhere up in the modifiers stack. - */ - ob_m = get_mesh(ob); - if (ob_m == NULL) - return dm; - - /* Create a copy of our dmesh, only if our affected cdata layer is the same as org mesh. */ - if (dvert == CustomData_get_layer(&ob_m->vdata, CD_MDEFORMVERT)) { - /* XXX Seems to create problems with weightpaint mode??? - * I'm missing something here, I guess... - */ -// DM_set_only_copy(dm, CD_MASK_MDEFORMVERT); /* Only copy defgroup layer. */ - ret = CDDM_copy(dm); - dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT); - if (dvert == NULL) { - ret->release(ret); - return dm; - } - rel_ret = 1; - } - else - ret = dm; -#else - ret = CDDM_copy(dm); - rel_ret = 1; - dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT); - if (dvert == NULL) { - if (rel_ret) - ret->release(ret); - return dm; - } -#endif + dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts); /* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight. */ @@ -433,8 +397,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der MEM_freeN(tidx); MEM_freeN(tw); MEM_freeN(tdw); - if (rel_ret) - ret->release(ret); return dm; } indices = MEM_mallocN(sizeof(int) * numIdx, "WeightVGProximity Modifier, indices"); @@ -455,7 +417,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der */ float (*tv_cos)[3] = MEM_mallocN(sizeof(float[3]) * numVerts, "WeightVGProximity Modifier, tv_cos"); v_cos = MEM_mallocN(sizeof(float[3]) * numIdx, "WeightVGProximity Modifier, v_cos"); - ret->getVertCos(ret, tv_cos); + dm->getVertCos(dm, tv_cos); for (i = 0; i < numIdx; i++) copy_v3_v3(v_cos[i], tv_cos[indices[i]]); MEM_freeN(tv_cos); @@ -524,7 +486,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der do_map(new_w, numIdx, wmd->min_dist, wmd->max_dist, wmd->falloff_type); /* Do masking. */ - weightvg_do_mask(numIdx, indices, org_w, new_w, ob, ret, wmd->mask_constant, + weightvg_do_mask(numIdx, indices, org_w, new_w, ob, dm, wmd->mask_constant, wmd->mask_defgrp_name, wmd->mask_texture, wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); @@ -538,8 +500,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der MEM_freeN(indices); MEM_freeN(v_cos); +#if DO_PROFILE + TIMEIT_END(perf) +#endif + /* Return the vgroup-modified mesh. */ - return ret; + return dm; } static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, @@ -554,7 +520,7 @@ ModifierTypeInfo modifierType_WeightVGProximity = { /* name */ "VertexWeightProximity", /* structName */ "WeightVGProximityModifierData", /* structSize */ sizeof(WeightVGProximityModifierData), - /* type */ eModifierTypeType_Nonconstructive, + /* type */ eModifierTypeType_NonGeometrical, /* flags */ eModifierTypeFlag_AcceptsMesh /* |eModifierTypeFlag_SupportsMapping*/ |eModifierTypeFlag_SupportsEditmode, diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c index 87585c35e6a..8b8afc3d846 100644 --- a/source/blender/nodes/shader/node_shader_util.c +++ b/source/blender/nodes/shader/node_shader_util.c @@ -134,8 +134,6 @@ void ntreeShaderGetTexcoMode(bNodeTree *ntree, int r_mode, short *texco, int *mo bNodeSocket *sock; int a; - ntreeSocketUseFlags(ntree); - for(node= ntree->nodes.first; node; node= node->next) { if(node->type==SH_NODE_TEXTURE) { if((r_mode & R_OSA) && node->id) { diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 69a5fb39b67..ded0f2f768c 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -642,7 +642,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) if (len==16) { if (is_thick) { ret= Matrix_CreatePyObject(NULL, 4, 4, Py_NEW, NULL); - RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->contigPtr); + RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix); } else { PyObject *mat_cb= Matrix_CreatePyObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, FALSE); @@ -653,7 +653,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) else if (len==9) { if (is_thick) { ret= Matrix_CreatePyObject(NULL, 3, 3, Py_NEW, NULL); - RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->contigPtr); + RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix); } else { PyObject *mat_cb= Matrix_CreatePyObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, FALSE); diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c index 5587028d812..1dfd7c574dd 100644 --- a/source/blender/python/mathutils/mathutils.c +++ b/source/blender/python/mathutils/mathutils.c @@ -35,6 +35,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_dynstr.h" PyDoc_STRVAR(M_Mathutils_doc, "This module provides access to matrices, eulers, quaternions and vectors." @@ -211,7 +212,7 @@ int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) { return -1; } - else if (((MatrixObject *)value)->col_size < 3 || ((MatrixObject *)value)->row_size < 3) { + else if (((MatrixObject *)value)->num_row < 3 || ((MatrixObject *)value)->num_col < 3) { PyErr_Format(PyExc_ValueError, "%.200s: matrix must have minimum 3x3 dimensions", error_prefix); @@ -267,6 +268,18 @@ int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps) return 1; } +/* dynstr as python string utility funcions, frees 'ds'! */ +PyObject *mathutils_dynstr_to_py(struct DynStr *ds) +{ + const int ds_len = BLI_dynstr_get_len(ds); /* space for \0 */ + char *ds_buf = PyMem_Malloc(ds_len + 1); + PyObject *ret; + BLI_dynstr_get_cstring_ex(ds, ds_buf); + BLI_dynstr_free(ds); + ret = PyUnicode_FromStringAndSize(ds_buf, ds_len); + PyMem_Free(ds_buf); + return ret; +} /* Mathutils Callbacks */ diff --git a/source/blender/python/mathutils/mathutils.h b/source/blender/python/mathutils/mathutils.h index cd3548b9b82..2454e953949 100644 --- a/source/blender/python/mathutils/mathutils.h +++ b/source/blender/python/mathutils/mathutils.h @@ -37,6 +37,8 @@ /* Can cast different mathutils types to this, use for generic funcs */ +struct DynStr; + extern char BaseMathObject_Wrapped_doc[]; extern char BaseMathObject_Owner_doc[]; @@ -120,4 +122,7 @@ int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error int column_vector_multiplication(float rvec[4], VectorObject *vec, MatrixObject *mat); +/* dynstr as python string utility funcions */ +PyObject *mathutils_dynstr_to_py(struct DynStr *ds); + #endif /* MATHUTILS_H */ diff --git a/source/blender/python/mathutils/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c index e46dda7560f..e0a0deb9a0e 100644 --- a/source/blender/python/mathutils/mathutils_Color.c +++ b/source/blender/python/mathutils/mathutils_Color.c @@ -32,6 +32,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_dynstr.h" #define COLOR_SIZE 3 @@ -125,6 +126,21 @@ static PyObject *Color_repr(ColorObject * self) return ret; } +static PyObject *Color_str(ColorObject * self) +{ + DynStr *ds; + + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + ds= BLI_dynstr_new(); + + BLI_dynstr_appendf(ds, "<Color (r=%.4f, g=%.4f, b=%.4f)>", + self->col[0], self->col[1], self->col[2]); + + return mathutils_dynstr_to_py(ds); /* frees ds */ +} + //------------------------tp_richcmpr //returns -1 execption, 0 false, 1 true static PyObject* Color_richcmpr(PyObject *a, PyObject *b, int op) @@ -789,7 +805,7 @@ PyTypeObject color_Type = { &Color_AsMapping, //tp_as_mapping NULL, //tp_hash NULL, //tp_call - NULL, //tp_str + (reprfunc) Color_str, //tp_str NULL, //tp_getattro NULL, //tp_setattro NULL, //tp_as_buffer diff --git a/source/blender/python/mathutils/mathutils_Euler.c b/source/blender/python/mathutils/mathutils_Euler.c index f44c0b82a2d..443e77c3798 100644 --- a/source/blender/python/mathutils/mathutils_Euler.c +++ b/source/blender/python/mathutils/mathutils_Euler.c @@ -36,6 +36,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_dynstr.h" #define EULER_SIZE 3 @@ -317,6 +318,21 @@ static PyObject *Euler_repr(EulerObject * self) return ret; } +static PyObject *Euler_str(EulerObject * self) +{ + DynStr *ds; + + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + ds= BLI_dynstr_new(); + + BLI_dynstr_appendf(ds, "<Euler (x=%.4f, y=%.4f, z=%.4f), order='%s'>", + self->eul[0], self->eul[1], self->eul[2], euler_order_str(self)); + + return mathutils_dynstr_to_py(ds); /* frees ds */ +} + static PyObject* Euler_richcmpr(PyObject *a, PyObject *b, int op) { PyObject *res; @@ -635,7 +651,7 @@ PyTypeObject euler_Type = { &Euler_AsMapping, //tp_as_mapping NULL, //tp_hash NULL, //tp_call - NULL, //tp_str + (reprfunc) Euler_str, //tp_str NULL, //tp_getattro NULL, //tp_setattro NULL, //tp_as_buffer diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index 44799bb7943..59aad37f746 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -35,6 +35,8 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_string.h" +#include "BLI_dynstr.h" static PyObject *Matrix_copy(MatrixObject *self); static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *value); @@ -49,56 +51,56 @@ static int mathutils_matrix_vector_check(BaseMathObject *bmo) return BaseMath_ReadCallback(self); } -static int mathutils_matrix_vector_get(BaseMathObject *bmo, int subtype) +static int mathutils_matrix_vector_get(BaseMathObject *bmo, int col) { MatrixObject *self= (MatrixObject *)bmo->cb_user; - int index; + int row; if (BaseMath_ReadCallback(self) == -1) return -1; - for (index=0; index < self->col_size; index++) { - bmo->data[index] = MATRIX_ITEM(self, subtype, index); + for (row=0; row < self->num_row; row++) { + bmo->data[row] = MATRIX_ITEM(self, row, col); } return 0; } -static int mathutils_matrix_vector_set(BaseMathObject *bmo, int subtype) +static int mathutils_matrix_vector_set(BaseMathObject *bmo, int col) { MatrixObject *self= (MatrixObject *)bmo->cb_user; - int index; + int row; if (BaseMath_ReadCallback(self) == -1) return -1; - for (index=0; index < self->col_size; index++) { - MATRIX_ITEM(self, subtype, index) = bmo->data[index]; + for (row=0; row < self->num_row; row++) { + MATRIX_ITEM(self, row, col) = bmo->data[row]; } (void)BaseMath_WriteCallback(self); return 0; } -static int mathutils_matrix_vector_get_index(BaseMathObject *bmo, int subtype, int index) +static int mathutils_matrix_vector_get_index(BaseMathObject *bmo, int col, int row) { MatrixObject *self= (MatrixObject *)bmo->cb_user; if (BaseMath_ReadCallback(self) == -1) return -1; - bmo->data[index]= MATRIX_ITEM(self, subtype, index); + bmo->data[row]= MATRIX_ITEM(self, row, col); return 0; } -static int mathutils_matrix_vector_set_index(BaseMathObject *bmo, int subtype, int index) +static int mathutils_matrix_vector_set_index(BaseMathObject *bmo, int col, int row) { MatrixObject *self= (MatrixObject *)bmo->cb_user; if (BaseMath_ReadCallback(self) == -1) return -1; - MATRIX_ITEM(self, subtype, index) = bmo->data[index]; + MATRIX_ITEM(self, row, col) = bmo->data[row]; (void)BaseMath_WriteCallback(self); return 0; @@ -133,16 +135,16 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *arg= PyTuple_GET_ITEM(args, 0); /* -1 is an error, size checks will accunt for this */ - const unsigned short row_size= PySequence_Size(arg); + const unsigned short num_col= PySequence_Size(arg); - if (row_size >= 2 && row_size <= 4) { + if (num_col >= 2 && num_col <= 4) { PyObject *item= PySequence_GetItem(arg, 0); - const unsigned short col_size= PySequence_Size(item); + const unsigned short num_row= PySequence_Size(item); Py_XDECREF(item); - if (col_size >= 2 && col_size <= 4) { + if (num_row >= 2 && num_row <= 4) { /* sane row & col size, new matrix and assign as slice */ - PyObject *matrix= Matrix_CreatePyObject(NULL, row_size, col_size, Py_NEW, type); + PyObject *matrix= Matrix_CreatePyObject(NULL, num_col, num_row, Py_NEW, type); if (Matrix_ass_slice((MatrixObject *)matrix, 0, INT_MAX, arg) == 0) { return matrix; } @@ -622,25 +624,25 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args) void matrix_as_3x3(float mat[3][3], MatrixObject *self) { - copy_v3_v3(mat[0], MATRIX_ROW_PTR(self, 0)); - copy_v3_v3(mat[1], MATRIX_ROW_PTR(self, 1)); - copy_v3_v3(mat[2], MATRIX_ROW_PTR(self, 2)); + copy_v3_v3(mat[0], MATRIX_COL_PTR(self, 0)); + copy_v3_v3(mat[1], MATRIX_COL_PTR(self, 1)); + copy_v3_v3(mat[2], MATRIX_COL_PTR(self, 2)); } /* assumes rowsize == colsize is checked and the read callback has run */ static float matrix_determinant_internal(MatrixObject *self) { - if (self->row_size == 2) { + if (self->num_col == 2) { return determinant_m2(MATRIX_ITEM(self, 0, 0), MATRIX_ITEM(self, 0, 1), MATRIX_ITEM(self, 1, 0), MATRIX_ITEM(self, 1, 1)); } - else if (self->row_size == 3) { + else if (self->num_col == 3) { return determinant_m3(MATRIX_ITEM(self, 0, 0), MATRIX_ITEM(self, 0, 1), MATRIX_ITEM(self, 0, 2), MATRIX_ITEM(self, 1, 0), MATRIX_ITEM(self, 1, 1), MATRIX_ITEM(self, 1, 2), MATRIX_ITEM(self, 2, 0), MATRIX_ITEM(self, 2, 1), MATRIX_ITEM(self, 2, 2)); } else { - return determinant_m4((float (*)[4])self->contigPtr); + return determinant_m4((float (*)[4])self->matrix); } } @@ -662,17 +664,17 @@ static PyObject *Matrix_to_quaternion(MatrixObject *self) return NULL; /*must be 3-4 cols, 3-4 rows, square matrix*/ - if ((self->col_size < 3) || (self->row_size < 3) || (self->col_size != self->row_size)) { + if ((self->num_row < 3) || (self->num_col < 3) || (self->num_row != self->num_col)) { PyErr_SetString(PyExc_ValueError, "Matrix.to_quat(): " "inappropriate matrix size - expects 3x3 or 4x4 matrix"); return NULL; } - if (self->col_size == 3) { - mat3_to_quat(quat, (float (*)[3])self->contigPtr); + if (self->num_row == 3) { + mat3_to_quat(quat, (float (*)[3])self->matrix); } else { - mat4_to_quat(quat, (float (*)[4])self->contigPtr); + mat4_to_quat(quat, (float (*)[4])self->matrix); } return Quaternion_CreatePyObject(quat, Py_NEW, NULL); @@ -719,11 +721,11 @@ static PyObject *Matrix_to_euler(MatrixObject *self, PyObject *args) } /*must be 3-4 cols, 3-4 rows, square matrix*/ - if (self->col_size ==3 && self->row_size ==3) { - mat= (float (*)[3])self->contigPtr; + if (self->num_row ==3 && self->num_col ==3) { + mat= (float (*)[3])self->matrix; } - else if (self->col_size ==4 && self->row_size ==4) { - copy_m3_m4(tmat, (float (*)[4])self->contigPtr); + else if (self->num_row ==4 && self->num_col ==4) { + copy_m3_m4(tmat, (float (*)[4])self->matrix); mat= tmat; } else { @@ -774,8 +776,8 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self) return NULL; } - self->contigPtr = PyMem_Realloc(self->contigPtr, (sizeof(float) * 16)); - if (self->contigPtr == NULL) { + self->matrix = PyMem_Realloc(self->matrix, (sizeof(float) * 16)); + if (self->matrix == NULL) { PyErr_SetString(PyExc_MemoryError, "Matrix.resize_4x4(): " "problem allocating pointer space"); @@ -783,31 +785,31 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self) } /*move data to new spot in array + clean*/ - for (blank_rows = (4 - self->row_size); blank_rows > 0; blank_rows--) { + for (blank_rows = (4 - self->num_col); blank_rows > 0; blank_rows--) { for (x = 0; x < 4; x++) { - index = (4 * (self->row_size + (blank_rows - 1))) + x; + index = (4 * (self->num_col + (blank_rows - 1))) + x; if (index == 10 || index == 15) { - self->contigPtr[index] = 1.0f; + self->matrix[index] = 1.0f; } else { - self->contigPtr[index] = 0.0f; + self->matrix[index] = 0.0f; } } } - for (x = 1; x <= self->row_size; x++) { - first_row_elem = (self->col_size * (self->row_size - x)); - curr_pos = (first_row_elem + (self->col_size -1)); - new_pos = (4 * (self->row_size - x)) + (curr_pos - first_row_elem); - for (blank_columns = (4 - self->col_size); blank_columns > 0; blank_columns--) { - self->contigPtr[new_pos + blank_columns] = 0.0f; + for (x = 1; x <= self->num_col; x++) { + first_row_elem = (self->num_row * (self->num_col - x)); + curr_pos = (first_row_elem + (self->num_row -1)); + new_pos = (4 * (self->num_col - x)) + (curr_pos - first_row_elem); + for (blank_columns = (4 - self->num_row); blank_columns > 0; blank_columns--) { + self->matrix[new_pos + blank_columns] = 0.0f; } for ( ; curr_pos >= first_row_elem; curr_pos--) { - self->contigPtr[new_pos] = self->contigPtr[curr_pos]; + self->matrix[new_pos] = self->matrix[curr_pos]; new_pos--; } } - self->row_size = 4; - self->col_size = 4; + self->num_col = 4; + self->num_row = 4; Py_RETURN_NONE; } @@ -825,12 +827,12 @@ static PyObject *Matrix_to_4x4(MatrixObject *self) if (BaseMath_ReadCallback(self) == -1) return NULL; - if (self->col_size==4 && self->row_size==4) { - return Matrix_CreatePyObject(self->contigPtr, 4, 4, Py_NEW, Py_TYPE(self)); + if (self->num_row==4 && self->num_col==4) { + return Matrix_CreatePyObject(self->matrix, 4, 4, Py_NEW, Py_TYPE(self)); } - else if (self->col_size==3 && self->row_size==3) { + else if (self->num_row==3 && self->num_col==3) { float mat[4][4]; - copy_m4_m3(mat, (float (*)[3])self->contigPtr); + copy_m4_m3(mat, (float (*)[3])self->matrix); return Matrix_CreatePyObject((float *)mat, 4, 4, Py_NEW, Py_TYPE(self)); } /* TODO, 2x2 matrix */ @@ -856,7 +858,7 @@ static PyObject *Matrix_to_3x3(MatrixObject *self) if (BaseMath_ReadCallback(self) == -1) return NULL; - if ((self->col_size < 3) || (self->row_size < 3)) { + if ((self->num_row < 3) || (self->num_col < 3)) { PyErr_SetString(PyExc_TypeError, "Matrix.to_3x3(): inappropriate matrix size"); return NULL; @@ -880,14 +882,14 @@ static PyObject *Matrix_to_translation(MatrixObject *self) if (BaseMath_ReadCallback(self) == -1) return NULL; - if ((self->col_size < 3) || self->row_size < 4) { + if ((self->num_row < 3) || self->num_col < 4) { PyErr_SetString(PyExc_TypeError, "Matrix.to_translation(): " "inappropriate matrix size"); return NULL; } - return Vector_CreatePyObject(MATRIX_ROW_PTR(self, 3), 3, Py_NEW, NULL); + return Vector_CreatePyObject(MATRIX_COL_PTR(self, 3), 3, Py_NEW, NULL); } PyDoc_STRVAR(Matrix_to_scale_doc, @@ -910,7 +912,7 @@ static PyObject *Matrix_to_scale(MatrixObject *self) return NULL; /*must be 3-4 cols, 3-4 rows, square matrix*/ - if ((self->col_size < 3) || (self->row_size < 3)) { + if ((self->num_row < 3) || (self->num_col < 3)) { PyErr_SetString(PyExc_TypeError, "Matrix.to_scale(): " "inappropriate matrix size, 3x3 minimum size"); @@ -948,7 +950,7 @@ static PyObject *Matrix_invert(MatrixObject *self) if (BaseMath_ReadCallback(self) == -1) return NULL; - if (self->row_size != self->col_size) { + if (self->num_col != self->num_row) { PyErr_SetString(PyExc_TypeError, "Matrix.invert(ed): " "only square matrices are supported"); @@ -960,26 +962,26 @@ static PyObject *Matrix_invert(MatrixObject *self) if (det != 0) { /*calculate the classical adjoint*/ - if (self->row_size == 2) { + if (self->num_col == 2) { mat[0] = MATRIX_ITEM(self, 1, 1); mat[1] = -MATRIX_ITEM(self, 0, 1); mat[2] = -MATRIX_ITEM(self, 1, 0); mat[3] = MATRIX_ITEM(self, 0, 0); } - else if (self->row_size == 3) { - adjoint_m3_m3((float (*)[3]) mat,(float (*)[3])self->contigPtr); + else if (self->num_col == 3) { + adjoint_m3_m3((float (*)[3]) mat,(float (*)[3])self->matrix); } - else if (self->row_size == 4) { - adjoint_m4_m4((float (*)[4]) mat, (float (*)[4])self->contigPtr); + else if (self->num_col == 4) { + adjoint_m4_m4((float (*)[4]) mat, (float (*)[4])self->matrix); } /*divide by determinate*/ - for (x = 0; x < (self->row_size * self->col_size); x++) { + for (x = 0; x < (self->num_col * self->num_row); x++) { mat[x] /= det; } /*set values*/ - for (x = 0; x < self->row_size; x++) { - for (y = 0; y < self->col_size; y++) { - MATRIX_ITEM(self, x, y) = mat[z]; + for (x = 0; x < self->num_col; x++) { + for (y = 0; y < self->num_row; y++) { + MATRIX_ITEM(self, y, x) = mat[z]; z++; } } @@ -1032,7 +1034,7 @@ static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value) if (mathutils_any_to_rotmat(other_rmat, value, "matrix.rotate(value)") == -1) return NULL; - if (self->col_size != 3 || self->row_size != 3) { + if (self->num_row != 3 || self->num_col != 3) { PyErr_SetString(PyExc_TypeError, "Matrix.rotate(): " "must have 3x3 dimensions"); @@ -1042,7 +1044,7 @@ static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value) matrix_as_3x3(self_rmat, self); mul_m3_m3m3(rmat, other_rmat, self_rmat); - copy_m3_m3((float (*)[3])(self->contigPtr), rmat); + copy_m3_m3((float (*)[3])(self->matrix), rmat); (void)BaseMath_WriteCallback(self); Py_RETURN_NONE; @@ -1065,7 +1067,7 @@ static PyObject *Matrix_decompose(MatrixObject *self) float quat[4]; float size[3]; - if (self->col_size != 4 || self->row_size != 4) { + if (self->num_row != 4 || self->num_col != 4) { PyErr_SetString(PyExc_TypeError, "Matrix.decompose(): " "inappropriate matrix size - expects 4x4 matrix"); @@ -1075,7 +1077,7 @@ static PyObject *Matrix_decompose(MatrixObject *self) if (BaseMath_ReadCallback(self) == -1) return NULL; - mat4_to_loc_rot_size(loc, rot, size, (float (*)[4])self->contigPtr); + mat4_to_loc_rot_size(loc, rot, size, (float (*)[4])self->matrix); mat3_to_quat(quat, rot); ret= PyTuple_New(3); @@ -1108,7 +1110,7 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O!f:lerp", &matrix_Type, &mat2, &fac)) return NULL; - if (self->row_size != mat2->row_size || self->col_size != mat2->col_size) { + if (self->num_col != mat2->num_col || self->num_row != mat2->num_row) { PyErr_SetString(PyExc_ValueError, "Matrix.lerp(): " "expects both matrix objects of the same dimensions"); @@ -1119,11 +1121,11 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args) return NULL; /* TODO, different sized matrix */ - if (self->row_size==4 && self->col_size==4) { - blend_m4_m4m4((float (*)[4])mat, (float (*)[4])self->contigPtr, (float (*)[4])mat2->contigPtr, fac); + if (self->num_col==4 && self->num_row==4) { + blend_m4_m4m4((float (*)[4])mat, (float (*)[4])self->matrix, (float (*)[4])mat2->matrix, fac); } - else if (self->row_size==3 && self->col_size==3) { - blend_m3_m3m3((float (*)[3])mat, (float (*)[3])self->contigPtr, (float (*)[3])mat2->contigPtr, fac); + else if (self->num_col==3 && self->num_row==3) { + blend_m3_m3m3((float (*)[3])mat, (float (*)[3])self->matrix, (float (*)[3])mat2->matrix, fac); } else { PyErr_SetString(PyExc_ValueError, @@ -1132,7 +1134,7 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args) return NULL; } - return Matrix_CreatePyObject(mat, self->row_size, self->col_size, Py_NEW, Py_TYPE(self)); + return Matrix_CreatePyObject(mat, self->num_col, self->num_row, Py_NEW, Py_TYPE(self)); } /*---------------------------matrix.determinant() ----------------*/ @@ -1151,7 +1153,7 @@ static PyObject *Matrix_determinant(MatrixObject *self) if (BaseMath_ReadCallback(self) == -1) return NULL; - if (self->row_size != self->col_size) { + if (self->num_col != self->num_row) { PyErr_SetString(PyExc_TypeError, "Matrix.determinant(): " "only square matrices are supported"); @@ -1173,23 +1175,23 @@ static PyObject *Matrix_transpose(MatrixObject *self) if (BaseMath_ReadCallback(self) == -1) return NULL; - if (self->row_size != self->col_size) { + if (self->num_col != self->num_row) { PyErr_SetString(PyExc_TypeError, "Matrix.transpose(d): " "only square matrices are supported"); return NULL; } - if (self->row_size == 2) { + if (self->num_col == 2) { const float t = MATRIX_ITEM(self, 1, 0); MATRIX_ITEM(self, 1, 0) = MATRIX_ITEM(self, 0, 1); MATRIX_ITEM(self, 0, 1) = t; } - else if (self->row_size == 3) { - transpose_m3((float (*)[3])self->contigPtr); + else if (self->num_col == 3) { + transpose_m3((float (*)[3])self->matrix); } else { - transpose_m4((float (*)[4])self->contigPtr); + transpose_m4((float (*)[4])self->matrix); } (void)BaseMath_WriteCallback(self); @@ -1220,7 +1222,7 @@ PyDoc_STRVAR(Matrix_zero_doc, ); static PyObject *Matrix_zero(MatrixObject *self) { - fill_vn_fl(self->contigPtr, self->row_size * self->col_size, 0.0f); + fill_vn_fl(self->matrix, self->num_col * self->num_row, 0.0f); if (BaseMath_WriteCallback(self) == -1) return NULL; @@ -1243,24 +1245,24 @@ static PyObject *Matrix_identity(MatrixObject *self) if (BaseMath_ReadCallback(self) == -1) return NULL; - if (self->row_size != self->col_size) { + if (self->num_col != self->num_row) { PyErr_SetString(PyExc_TypeError, "Matrix.identity(): " "only square matrices are supported"); return NULL; } - if (self->row_size == 2) { + if (self->num_col == 2) { MATRIX_ITEM(self, 0, 0) = 1.0f; MATRIX_ITEM(self, 0, 1) = 0.0f; MATRIX_ITEM(self, 1, 0) = 0.0f; MATRIX_ITEM(self, 1, 1) = 1.0f; } - else if (self->row_size == 3) { - unit_m3((float (*)[3])self->contigPtr); + else if (self->num_col == 3) { + unit_m3((float (*)[3])self->matrix); } else { - unit_m4((float (*)[4])self->contigPtr); + unit_m4((float (*)[4])self->matrix); } if (BaseMath_WriteCallback(self) == -1) @@ -1283,26 +1285,26 @@ static PyObject *Matrix_copy(MatrixObject *self) if (BaseMath_ReadCallback(self) == -1) return NULL; - return Matrix_CreatePyObject((float (*))self->contigPtr, self->row_size, self->col_size, Py_NEW, Py_TYPE(self)); + return Matrix_CreatePyObject((float (*))self->matrix, self->num_col, self->num_row, Py_NEW, Py_TYPE(self)); } /*----------------------------print object (internal)-------------*/ /*print the object to screen*/ static PyObject *Matrix_repr(MatrixObject *self) { - int x, y; + int col, row; PyObject *rows[MATRIX_MAX_DIM]= {NULL}; if (BaseMath_ReadCallback(self) == -1) return NULL; - for (x = 0; x < self->row_size; x++) { - rows[x]= PyTuple_New(self->col_size); - for (y = 0; y < self->col_size; y++) { - PyTuple_SET_ITEM(rows[x], y, PyFloat_FromDouble(MATRIX_ITEM(self, x, y))); + for (col = 0; col < self->num_col; col++) { + rows[col]= PyTuple_New(self->num_row); + for (row = 0; row < self->num_row; row++) { + PyTuple_SET_ITEM(rows[col], row, PyFloat_FromDouble(MATRIX_ITEM(self, row, col))); } } - switch (self->row_size) { + switch (self->num_col) { case 2: return PyUnicode_FromFormat("Matrix((%R,\n" " %R))", rows[0], rows[1]); @@ -1320,6 +1322,42 @@ static PyObject *Matrix_repr(MatrixObject *self) return NULL; } +static PyObject* Matrix_str(MatrixObject *self) +{ + DynStr *ds; + + int maxsize[MATRIX_MAX_DIM]; + int row, col; + + char dummy_buf[1]; + + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + ds= BLI_dynstr_new(); + + /* First determine the maximum width for each column */ + for (col = 0; col < self->num_col; col++) { + maxsize[col]= 0; + for (row = 0; row < self->num_row; row++) { + int size= BLI_snprintf(dummy_buf, sizeof(dummy_buf), "%.4f", MATRIX_ITEM(self, row, col)); + maxsize[col]= MAX2(maxsize[col], size); + } + } + + /* Now write the unicode string to be printed */ + BLI_dynstr_appendf(ds, "<Matrix %dx%d (", self->num_row, self->num_col); + for (row = 0; row < self->num_row; row++) { + for (col = 0; col < self->num_col; col++) { + BLI_dynstr_appendf(ds, col ? ", %*.4f" : "%*.4f", maxsize[col], MATRIX_ITEM(self, row, col)); + } + BLI_dynstr_append(ds, row + 1 != self->num_row ? ")\n " : ")"); + } + BLI_dynstr_append(ds, ">"); + + return mathutils_dynstr_to_py(ds); /* frees ds */ +} + static PyObject* Matrix_richcmpr(PyObject *a, PyObject *b, int op) { PyObject *res; @@ -1332,9 +1370,9 @@ static PyObject* Matrix_richcmpr(PyObject *a, PyObject *b, int op) if (BaseMath_ReadCallback(matA) == -1 || BaseMath_ReadCallback(matB) == -1) return NULL; - ok= ( (matA->col_size == matB->col_size) && - (matA->row_size == matB->row_size) && - EXPP_VectorsAreEqual(matA->contigPtr, matB->contigPtr, (matA->row_size * matA->col_size), 1) + ok= ( (matA->num_row == matB->num_row) && + (matA->num_col == matB->num_col) && + EXPP_VectorsAreEqual(matA->matrix, matB->matrix, (matA->num_col * matA->num_row), 1) ) ? 0 : -1; } @@ -1364,7 +1402,7 @@ static PyObject* Matrix_richcmpr(PyObject *a, PyObject *b, int op) sequence length*/ static int Matrix_len(MatrixObject *self) { - return (self->row_size); + return (self->num_col); } /*----------------------------object[]--------------------------- sequence accessor (get) @@ -1374,13 +1412,13 @@ static PyObject *Matrix_item(MatrixObject *self, int i) if (BaseMath_ReadCallback(self) == -1) return NULL; - if (i < 0 || i >= self->row_size) { + if (i < 0 || i >= self->num_col) { PyErr_SetString(PyExc_IndexError, "matrix[attribute]: " "array index out of range"); return NULL; } - return Vector_CreatePyObject_cb((PyObject *)self, self->col_size, mathutils_matrix_vector_cb_index, i); + return Vector_CreatePyObject_cb((PyObject *)self, self->num_row, mathutils_matrix_vector_cb_index, i); } /*----------------------------object[]------------------------- sequence accessor (set) */ @@ -1391,17 +1429,17 @@ static int Matrix_ass_item(MatrixObject *self, int i, PyObject *value) if (BaseMath_ReadCallback(self) == -1) return -1; - if (i >= self->row_size || i < 0) { + if (i >= self->num_col || i < 0) { PyErr_SetString(PyExc_IndexError, "matrix[attribute] = x: bad column"); return -1; } - if (mathutils_array_parse(vec, self->col_size, self->col_size, value, "matrix[i] = value assignment") < 0) { + if (mathutils_array_parse(vec, self->num_row, self->num_row, value, "matrix[i] = value assignment") < 0) { return -1; } - memcpy(MATRIX_ROW_PTR(self, i), vec, self->col_size * sizeof(float)); + memcpy(MATRIX_COL_PTR(self, i), vec, self->num_row * sizeof(float)); (void)BaseMath_WriteCallback(self); return 0; @@ -1418,14 +1456,14 @@ static PyObject *Matrix_slice(MatrixObject *self, int begin, int end) if (BaseMath_ReadCallback(self) == -1) return NULL; - CLAMP(begin, 0, self->row_size); - CLAMP(end, 0, self->row_size); + CLAMP(begin, 0, self->num_col); + CLAMP(end, 0, self->num_col); begin= MIN2(begin, end); tuple= PyTuple_New(end - begin); for (count= begin; count < end; count++) { PyTuple_SET_ITEM(tuple, count - begin, - Vector_CreatePyObject_cb((PyObject *)self, self->col_size, mathutils_matrix_vector_cb_index, count)); + Vector_CreatePyObject_cb((PyObject *)self, self->num_row, mathutils_matrix_vector_cb_index, count)); } @@ -1440,8 +1478,8 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va if (BaseMath_ReadCallback(self) == -1) return -1; - CLAMP(begin, 0, self->row_size); - CLAMP(end, 0, self->row_size); + CLAMP(begin, 0, self->num_col); + CLAMP(end, 0, self->num_col); begin = MIN2(begin, end); /* non list/tuple cases */ @@ -1467,7 +1505,7 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va /*parse each sub sequence*/ PyObject *item= PySequence_Fast_GET_ITEM(value_fast, i); - if (mathutils_array_parse(&mat[i * self->col_size], self->col_size, self->col_size, item, + if (mathutils_array_parse(&mat[i * self->num_row], self->num_row, self->num_row, item, "matrix[begin:end] = value assignment") < 0) { return -1; @@ -1477,7 +1515,7 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va Py_DECREF(value_fast); /*parsed well - now set in matrix*/ - memcpy(self->contigPtr + (begin * self->col_size), mat, sizeof(float) * (size * self->col_size)); + memcpy(self->matrix + (begin * self->num_row), mat, sizeof(float) * (size * self->num_row)); (void)BaseMath_WriteCallback(self); return 0; @@ -1504,16 +1542,16 @@ static PyObject *Matrix_add(PyObject *m1, PyObject *m2) if (BaseMath_ReadCallback(mat1) == -1 || BaseMath_ReadCallback(mat2) == -1) return NULL; - if (mat1->row_size != mat2->row_size || mat1->col_size != mat2->col_size) { + if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) { PyErr_SetString(PyExc_TypeError, "Matrix addition: " "matrices must have the same dimensions for this operation"); return NULL; } - add_vn_vnvn(mat, mat1->contigPtr, mat2->contigPtr, mat1->row_size * mat1->col_size); + add_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row); - return Matrix_CreatePyObject(mat, mat1->row_size, mat1->col_size, Py_NEW, Py_TYPE(mat1)); + return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_NEW, Py_TYPE(mat1)); } /*------------------------obj - obj------------------------------ subtraction*/ @@ -1537,24 +1575,24 @@ static PyObject *Matrix_sub(PyObject *m1, PyObject *m2) if (BaseMath_ReadCallback(mat1) == -1 || BaseMath_ReadCallback(mat2) == -1) return NULL; - if (mat1->row_size != mat2->row_size || mat1->col_size != mat2->col_size) { + if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) { PyErr_SetString(PyExc_TypeError, "Matrix addition: " "matrices must have the same dimensions for this operation"); return NULL; } - sub_vn_vnvn(mat, mat1->contigPtr, mat2->contigPtr, mat1->row_size * mat1->col_size); + sub_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row); - return Matrix_CreatePyObject(mat, mat1->row_size, mat1->col_size, Py_NEW, Py_TYPE(mat1)); + return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_NEW, Py_TYPE(mat1)); } /*------------------------obj * obj------------------------------ mulplication*/ static PyObject *matrix_mul_float(MatrixObject *mat, const float scalar) { float tmat[16]; - mul_vn_vn_fl(tmat, mat->contigPtr, mat->row_size * mat->col_size, scalar); - return Matrix_CreatePyObject(tmat, mat->row_size, mat->col_size, Py_NEW, Py_TYPE(mat)); + mul_vn_vn_fl(tmat, mat->matrix, mat->num_col * mat->num_row, scalar); + return Matrix_CreatePyObject(tmat, mat->num_col, mat->num_row, Py_NEW, Py_TYPE(mat)); } static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) @@ -1581,19 +1619,19 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; double dot = 0.0f; - int x, y, z; + int col, row, item; - for (x = 0; x < mat2->row_size; x++) { - for (y = 0; y < mat1->col_size; y++) { - for (z = 0; z < mat1->row_size; z++) { - dot += MATRIX_ITEM(mat1, z, y) * MATRIX_ITEM(mat2, x, z); + for (col = 0; col < mat2->num_col; col++) { + for (row = 0; row < mat1->num_row; row++) { + for (item = 0; item < mat1->num_col; item++) { + dot += MATRIX_ITEM(mat1, row, item) * MATRIX_ITEM(mat2, item, col); } - mat[((x * mat1->col_size) + y)] = (float)dot; + mat[((col * mat1->num_row) + row)] = (float)dot; dot = 0.0f; } } - return Matrix_CreatePyObject(mat, mat2->row_size, mat1->col_size, Py_NEW, Py_TYPE(mat1)); + return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_NEW, Py_TYPE(mat1)); } else if (mat2) { /*FLOAT/INT * MATRIX */ @@ -1660,13 +1698,13 @@ static PyObject *Matrix_subscript(MatrixObject* self, PyObject* item) if (i == -1 && PyErr_Occurred()) return NULL; if (i < 0) - i += self->row_size; + i += self->num_col; return Matrix_item(self, i); } else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx((void *)item, self->row_size, &start, &stop, &step, &slicelength) < 0) + if (PySlice_GetIndicesEx((void *)item, self->num_col, &start, &stop, &step, &slicelength) < 0) return NULL; if (slicelength <= 0) { @@ -1696,13 +1734,13 @@ static int Matrix_ass_subscript(MatrixObject* self, PyObject* item, PyObject* va if (i == -1 && PyErr_Occurred()) return -1; if (i < 0) - i += self->row_size; + i += self->num_col; return Matrix_ass_item(self, i, value); } else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx((void *)item, self->row_size, &start, &stop, &step, &slicelength) < 0) + if (PySlice_GetIndicesEx((void *)item, self->num_col, &start, &stop, &step, &slicelength) < 0) return -1; if (step == 1) @@ -1767,12 +1805,12 @@ static PyNumberMethods Matrix_NumMethods = { static PyObject *Matrix_getRowSize(MatrixObject *self, void *UNUSED(closure)) { - return PyLong_FromLong((long) self->row_size); + return PyLong_FromLong((long) self->num_col); } static PyObject *Matrix_getColSize(MatrixObject *self, void *UNUSED(closure)) { - return PyLong_FromLong((long) self->col_size); + return PyLong_FromLong((long) self->num_row); } static PyObject *Matrix_median_scale_get(MatrixObject *self, void *UNUSED(closure)) @@ -1783,7 +1821,7 @@ static PyObject *Matrix_median_scale_get(MatrixObject *self, void *UNUSED(closur return NULL; /*must be 3-4 cols, 3-4 rows, square matrix*/ - if ((self->col_size < 3) || (self->row_size < 3)) { + if ((self->num_row < 3) || (self->num_col < 3)) { PyErr_SetString(PyExc_AttributeError, "Matrix.median_scale: " "inappropriate matrix size, 3x3 minimum"); @@ -1801,10 +1839,10 @@ static PyObject *Matrix_is_negative_get(MatrixObject *self, void *UNUSED(closure return NULL; /*must be 3-4 cols, 3-4 rows, square matrix*/ - if (self->col_size == 4 && self->row_size == 4) - return PyBool_FromLong(is_negative_m4((float (*)[4])self->contigPtr)); - else if (self->col_size == 3 && self->row_size == 3) - return PyBool_FromLong(is_negative_m3((float (*)[3])self->contigPtr)); + if (self->num_row == 4 && self->num_col == 4) + return PyBool_FromLong(is_negative_m4((float (*)[4])self->matrix)); + else if (self->num_row == 3 && self->num_col == 3) + return PyBool_FromLong(is_negative_m3((float (*)[3])self->matrix)); else { PyErr_SetString(PyExc_AttributeError, "Matrix.is_negative: " @@ -1819,10 +1857,10 @@ static PyObject *Matrix_is_orthogonal_get(MatrixObject *self, void *UNUSED(closu return NULL; /*must be 3-4 cols, 3-4 rows, square matrix*/ - if (self->col_size == 4 && self->row_size == 4) - return PyBool_FromLong(is_orthogonal_m4((float (*)[4])self->contigPtr)); - else if (self->col_size == 3 && self->row_size == 3) - return PyBool_FromLong(is_orthogonal_m3((float (*)[3])self->contigPtr)); + if (self->num_row == 4 && self->num_col == 4) + return PyBool_FromLong(is_orthogonal_m4((float (*)[4])self->matrix)); + else if (self->num_row == 3 && self->num_col == 3) + return PyBool_FromLong(is_orthogonal_m3((float (*)[3])self->matrix)); else { PyErr_SetString(PyExc_AttributeError, "Matrix.is_orthogonal: " @@ -1906,7 +1944,7 @@ PyTypeObject matrix_Type = { &Matrix_AsMapping, /*tp_as_mapping*/ NULL, /*tp_hash*/ NULL, /*tp_call*/ - NULL, /*tp_str*/ + (reprfunc) Matrix_str, /*tp_str*/ NULL, /*tp_getattro*/ NULL, /*tp_setattro*/ NULL, /*tp_as_buffer*/ @@ -1944,37 +1982,37 @@ PyTypeObject matrix_Type = { * pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON * (i.e. it must be created here with PyMEM_malloc()) */ PyObject *Matrix_CreatePyObject(float *mat, - const unsigned short row_size, const unsigned short col_size, + const unsigned short num_col, const unsigned short num_row, int type, PyTypeObject *base_type) { MatrixObject *self; /* matrix objects can be any 2-4row x 2-4col matrix */ - if (row_size < 2 || row_size > 4 || col_size < 2 || col_size > 4) { + if (num_col < 2 || num_col > 4 || num_row < 2 || num_row > 4) { PyErr_SetString(PyExc_RuntimeError, "Matrix(): " "row and column sizes must be between 2 and 4"); return NULL; } - self= base_type ? (MatrixObject *)base_type->tp_alloc(base_type, 0) : - (MatrixObject *)PyObject_GC_New(MatrixObject, &matrix_Type); + self= base_type ? (MatrixObject *)base_type->tp_alloc(base_type, 0) : + (MatrixObject *)PyObject_GC_New(MatrixObject, &matrix_Type); if (self) { - self->row_size = row_size; - self->col_size = col_size; + self->num_col = num_col; + self->num_row = num_row; /* init callbacks as NULL */ self->cb_user= NULL; self->cb_type= self->cb_subtype= 0; if (type == Py_WRAP) { - self->contigPtr = mat; + self->matrix = mat; self->wrapped = Py_WRAP; } else if (type == Py_NEW) { - self->contigPtr = PyMem_Malloc(row_size * col_size * sizeof(float)); - if (self->contigPtr == NULL) { /*allocation failure*/ + self->matrix = PyMem_Malloc(num_col * num_row * sizeof(float)); + if (self->matrix == NULL) { /*allocation failure*/ PyErr_SetString(PyExc_MemoryError, "Matrix(): " "problem allocating pointer space"); @@ -1982,16 +2020,16 @@ PyObject *Matrix_CreatePyObject(float *mat, } if (mat) { /*if a float array passed*/ - memcpy(self->contigPtr, mat, row_size * col_size * sizeof(float)); + memcpy(self->matrix, mat, num_col * num_row * sizeof(float)); } - else if (row_size == col_size) { + else if (num_col == num_row) { /* or if no arguments are passed return identity matrix for square matrices */ PyObject *ret_dummy= Matrix_identity(self); Py_DECREF(ret_dummy); } else { /* otherwise zero everything */ - memset(self->contigPtr, 0, row_size * col_size * sizeof(float)); + memset(self->matrix, 0, num_col * num_row * sizeof(float)); } self->wrapped = Py_NEW; } diff --git a/source/blender/python/mathutils/mathutils_Matrix.h b/source/blender/python/mathutils/mathutils_Matrix.h index 95768febca0..91a276b648e 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.h +++ b/source/blender/python/mathutils/mathutils_Matrix.h @@ -41,22 +41,22 @@ extern PyTypeObject matrix_Type; /* matrix[row][col] == MATRIX_ITEM_INDEX(matrix, row, col) */ #ifdef DEBUG -# define MATRIX_ITEM_ASSERT(_mat, _row, _col) (BLI_assert(_row < (_mat)->row_size && _col < (_mat)->col_size)) +# define MATRIX_ITEM_ASSERT(_mat, _row, _col) (BLI_assert(_row < (_mat)->num_row && _col < (_mat)->num_col)) #else # define MATRIX_ITEM_ASSERT(_mat, _row, _col) (void)0 #endif -#define MATRIX_ITEM_INDEX(_mat, _row, _col) (MATRIX_ITEM_ASSERT(_mat, _row, _col),(((_mat)->col_size * (_row)) + (_col))) -#define MATRIX_ITEM_PTR( _mat, _row, _col) ((_mat)->contigPtr + MATRIX_ITEM_INDEX(_mat, _row, _col)) -#define MATRIX_ITEM( _mat, _row, _col) ((_mat)->contigPtr [MATRIX_ITEM_INDEX(_mat, _row, _col)]) +#define MATRIX_ITEM_INDEX(_mat, _row, _col) (MATRIX_ITEM_ASSERT(_mat, _row, _col),(((_mat)->num_row * (_col)) + (_row))) +#define MATRIX_ITEM_PTR( _mat, _row, _col) ((_mat)->matrix + MATRIX_ITEM_INDEX(_mat, _row, _col)) +#define MATRIX_ITEM( _mat, _row, _col) ((_mat)->matrix [MATRIX_ITEM_INDEX(_mat, _row, _col)]) -#define MATRIX_ROW_INDEX(_mat, _row) (MATRIX_ITEM_INDEX(_mat, _row, 0)) -#define MATRIX_ROW_PTR( _mat, _row) ((_mat)->contigPtr + MATRIX_ROW_INDEX(_mat, _row)) +#define MATRIX_COL_INDEX(_mat, _col) (MATRIX_ITEM_INDEX(_mat, 0, _col)) +#define MATRIX_COL_PTR( _mat, _col) ((_mat)->matrix + MATRIX_COL_INDEX(_mat, _col)) typedef struct { - BASE_MATH_MEMBERS(contigPtr); - unsigned short row_size; - unsigned short col_size; + BASE_MATH_MEMBERS(matrix); + unsigned short num_col; + unsigned short num_row; } MatrixObject; /* struct data contains a pointer to the actual data that the @@ -66,9 +66,9 @@ typedef struct { /* prototypes */ PyObject *Matrix_CreatePyObject(float *mat, - const unsigned short row_size, const unsigned short col_size, + const unsigned short num_col, const unsigned short num_row, int type, PyTypeObject *base_type); -PyObject *Matrix_CreatePyObject_cb(PyObject *user, int row_size, int col_size, int cb_type, int cb_subtype); +PyObject *Matrix_CreatePyObject_cb(PyObject *user, int num_col, int num_row, int cb_type, int cb_subtype); extern int mathutils_matrix_vector_cb_index; extern struct Mathutils_Callback mathutils_matrix_vector_cb; diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c index 7ab9b7b0713..7c339807ee9 100644 --- a/source/blender/python/mathutils/mathutils_Quaternion.c +++ b/source/blender/python/mathutils/mathutils_Quaternion.c @@ -35,6 +35,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_dynstr.h" #define QUAT_SIZE 4 @@ -493,6 +494,21 @@ static PyObject *Quaternion_repr(QuaternionObject *self) return ret; } +static PyObject *Quaternion_str(QuaternionObject *self) +{ + DynStr *ds; + + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + ds= BLI_dynstr_new(); + + BLI_dynstr_appendf(ds, "<Quaternion (w=%.4f, x=%.4f, y=%.4f, z=%.4f)>", + self->quat[0], self->quat[1], self->quat[2], self->quat[3]); + + return mathutils_dynstr_to_py(ds); /* frees ds */ +} + static PyObject* Quaternion_richcmpr(PyObject *a, PyObject *b, int op) { PyObject *res; @@ -1167,7 +1183,7 @@ PyTypeObject quaternion_Type = { &Quaternion_AsMapping, //tp_as_mapping NULL, //tp_hash NULL, //tp_call - NULL, //tp_str + (reprfunc) Quaternion_str, //tp_str NULL, //tp_getattro NULL, //tp_setattro NULL, //tp_as_buffer diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c index aedf60e7191..bd121b6177f 100644 --- a/source/blender/python/mathutils/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -35,6 +35,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_dynstr.h" #define MAX_DIMENSIONS 4 @@ -1171,6 +1172,29 @@ static PyObject *Vector_repr(VectorObject *self) return ret; } +static PyObject *Vector_str(VectorObject *self) +{ + int i; + + DynStr *ds; + + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + ds= BLI_dynstr_new(); + + BLI_dynstr_append(ds, "<Vector ("); + + for (i = 0; i < self->size; i++) { + BLI_dynstr_appendf(ds, i ? ", %.4f" : "%.4f", self->vec[i]); + } + + BLI_dynstr_append(ds, ")>"); + + return mathutils_dynstr_to_py(ds); /* frees ds */ +} + + /* Sequence Protocol */ /* sequence length len(vector) */ static int Vector_len(VectorObject *self) @@ -1462,14 +1486,14 @@ static PyObject *Vector_isub(PyObject *v1, PyObject *v2) * note: vector/matrix multiplication IS NOT COMMUTATIVE!!!! * note: assume read callbacks have been done first. */ -int column_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject* vec, MatrixObject * mat) +int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject* vec, MatrixObject * mat) { float vec_cpy[MAX_DIMENSIONS]; double dot = 0.0f; - int x, y, z = 0; + int row, col, z = 0; - if (mat->row_size != vec->size) { - if (mat->row_size == 4 && vec->size == 3) { + if (mat->num_col != vec->size) { + if (mat->num_col == 4 && vec->size == 3) { vec_cpy[3] = 1.0f; } else { @@ -1483,13 +1507,13 @@ int column_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject* vec, memcpy(vec_cpy, vec->vec, vec->size * sizeof(float)); - rvec[3] = 1.0f; + r_vec[3] = 1.0f; - for (x = 0; x < mat->col_size; x++) { - for (y = 0; y < mat->row_size; y++) { - dot += (double)(MATRIX_ITEM(mat, y, x) * vec_cpy[y]); + for (row = 0; row < mat->num_row; row++) { + for (col = 0; col < mat->num_col; col++) { + dot += (double)(MATRIX_ITEM(mat, row, col) * vec_cpy[col]); } - rvec[z++] = (float)dot; + r_vec[z++] = (float)dot; dot = 0.0f; } @@ -2589,8 +2613,8 @@ static int row_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject *v double dot = 0.0f; int x, y, z= 0, vec_size= vec->size; - if (mat->col_size != vec_size) { - if (mat->col_size == 4 && vec_size != 3) { + if (mat->num_row != vec_size) { + if (mat->num_row == 4 && vec_size != 3) { PyErr_SetString(PyExc_ValueError, "vector * matrix: matrix column size " "and the vector size must be the same"); @@ -2608,9 +2632,9 @@ static int row_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject *v rvec[3] = 1.0f; //muliplication - for (x = 0; x < mat->row_size; x++) { - for (y = 0; y < mat->col_size; y++) { - dot += MATRIX_ITEM(mat, x, y) * vec_cpy[y]; + for (x = 0; x < mat->num_col; x++) { + for (y = 0; y < mat->num_row; y++) { + dot += MATRIX_ITEM(mat, y, x) * vec_cpy[y]; } rvec[z++] = (float)dot; dot = 0.0f; @@ -2715,7 +2739,7 @@ PyTypeObject vector_Type = { NULL, /* hashfunc tp_hash; */ NULL, /* ternaryfunc tp_call; */ - NULL, /* reprfunc tp_str; */ + (reprfunc)Vector_str, /* reprfunc tp_str; */ NULL, /* getattrofunc tp_getattro; */ NULL, /* setattrofunc tp_setattro; */ diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 2b44bad82ab..dc2de5fb450 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -190,6 +190,11 @@ void RE_engine_end_result(RenderEngine *engine, RenderResult *result) if(!result) return; + + result->tilerect.xmin += re->disprect.xmin; + result->tilerect.xmax += re->disprect.xmin; + result->tilerect.ymin += re->disprect.ymin; + result->tilerect.ymax += re->disprect.ymin; /* merge. on break, don't merge in result for preview renders, looks nicer */ if(!(re->test_break(re->tbh) && (re->r.scemode & R_PREVIEWBUTS))) diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 883684c3483..f9992050052 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -3083,6 +3083,12 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h continue; } break; + case TEXCO_EQUIRECTMAP: + tempvec[0]= atan2f(lo[0], lo[2]) / (float)M_PI; + tempvec[1]= 1.0f - 2.0f*saacos(lo[1]) / (float)M_PI; + tempvec[2]= 0.0f; + co= tempvec; + break; case TEXCO_OBJECT: if(mtex->object) { copy_v3_v3(tempvec, lo); diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 79a7f5bd910..6851b783463 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -491,7 +491,6 @@ elseif(WIN32) else() install( FILES - ${LIBDIR}/png/lib/libpng.dll ${LIBDIR}/zlib/lib/zlib.dll DESTINATION ${TARGETDIR} ) diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 360a082b03b..445f2b8f0ba 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -241,6 +241,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c ketsjiengine->SetUseFixedTime(usefixed); ketsjiengine->SetTimingDisplay(frameRate, profile, properties); ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS); + KX_KetsjiEngine::SetExitKey(ConvertKeyCode(startscene->gm.exitkey)); //set the global settings (carried over if restart/load new files) ketsjiengine->SetGlobalSettings(&gs); diff --git a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h index 1c91f498d32..93bf133635d 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h @@ -41,6 +41,7 @@ #include "wm_event_types.h" #include "WM_types.h" #include "SCA_IInputDevice.h" +#include "BL_BlenderDataConversion.h" #ifdef WITH_CXX_GUARDEDALLOC #include "MEM_guardedalloc.h" @@ -51,172 +52,9 @@ */ class BL_BlenderInputDevice : public SCA_IInputDevice { - // this map is Blender specific: a conversion between blender and ketsji enums - std::map<int,KX_EnumInputs> m_reverseKeyTranslateTable; public: BL_BlenderInputDevice() { - - /* The reverse table. In order to not confuse ourselves, we */ - /* immediately convert all events that come in to KX codes. */ - m_reverseKeyTranslateTable[LEFTMOUSE ] = KX_LEFTMOUSE; - m_reverseKeyTranslateTable[MIDDLEMOUSE ] = KX_MIDDLEMOUSE; - m_reverseKeyTranslateTable[RIGHTMOUSE ] = KX_RIGHTMOUSE; - m_reverseKeyTranslateTable[WHEELUPMOUSE ] = KX_WHEELUPMOUSE; - m_reverseKeyTranslateTable[WHEELDOWNMOUSE ] = KX_WHEELDOWNMOUSE; - m_reverseKeyTranslateTable[MOUSEX ] = KX_MOUSEX; - m_reverseKeyTranslateTable[MOUSEY ] = KX_MOUSEY; - - // TIMERS - - m_reverseKeyTranslateTable[TIMER0 ] = KX_TIMER0; - m_reverseKeyTranslateTable[TIMER1 ] = KX_TIMER1; - m_reverseKeyTranslateTable[TIMER2 ] = KX_TIMER2; - - // SYSTEM -#if 0 - /* **** XXX **** */ - m_reverseKeyTranslateTable[KEYBD ] = KX_KEYBD; - m_reverseKeyTranslateTable[RAWKEYBD ] = KX_RAWKEYBD; - m_reverseKeyTranslateTable[REDRAW ] = KX_REDRAW; - m_reverseKeyTranslateTable[INPUTCHANGE ] = KX_INPUTCHANGE; - m_reverseKeyTranslateTable[QFULL ] = KX_QFULL; - m_reverseKeyTranslateTable[WINFREEZE ] = KX_WINFREEZE; - m_reverseKeyTranslateTable[WINTHAW ] = KX_WINTHAW; - m_reverseKeyTranslateTable[WINCLOSE ] = KX_WINCLOSE; - m_reverseKeyTranslateTable[WINQUIT ] = KX_WINQUIT; - m_reverseKeyTranslateTable[Q_FIRSTTIME ] = KX_Q_FIRSTTIME; - /* **** XXX **** */ -#endif - // standard keyboard - - m_reverseKeyTranslateTable[AKEY ] = KX_AKEY; - m_reverseKeyTranslateTable[BKEY ] = KX_BKEY; - m_reverseKeyTranslateTable[CKEY ] = KX_CKEY; - m_reverseKeyTranslateTable[DKEY ] = KX_DKEY; - m_reverseKeyTranslateTable[EKEY ] = KX_EKEY; - m_reverseKeyTranslateTable[FKEY ] = KX_FKEY; - m_reverseKeyTranslateTable[GKEY ] = KX_GKEY; - //XXX clean up -#ifdef WIN32 -#define HKEY 'h' -#endif - m_reverseKeyTranslateTable[HKEY ] = KX_HKEY; - //XXX clean up -#ifdef WIN32 -#undef HKEY -#endif - m_reverseKeyTranslateTable[IKEY ] = KX_IKEY; - m_reverseKeyTranslateTable[JKEY ] = KX_JKEY; - m_reverseKeyTranslateTable[KKEY ] = KX_KKEY; - m_reverseKeyTranslateTable[LKEY ] = KX_LKEY; - m_reverseKeyTranslateTable[MKEY ] = KX_MKEY; - m_reverseKeyTranslateTable[NKEY ] = KX_NKEY; - m_reverseKeyTranslateTable[OKEY ] = KX_OKEY; - m_reverseKeyTranslateTable[PKEY ] = KX_PKEY; - m_reverseKeyTranslateTable[QKEY ] = KX_QKEY; - m_reverseKeyTranslateTable[RKEY ] = KX_RKEY; - m_reverseKeyTranslateTable[SKEY ] = KX_SKEY; - m_reverseKeyTranslateTable[TKEY ] = KX_TKEY; - m_reverseKeyTranslateTable[UKEY ] = KX_UKEY; - m_reverseKeyTranslateTable[VKEY ] = KX_VKEY; - m_reverseKeyTranslateTable[WKEY ] = KX_WKEY; - m_reverseKeyTranslateTable[XKEY ] = KX_XKEY; - m_reverseKeyTranslateTable[YKEY ] = KX_YKEY; - m_reverseKeyTranslateTable[ZKEY ] = KX_ZKEY; - - m_reverseKeyTranslateTable[ZEROKEY ] = KX_ZEROKEY; - m_reverseKeyTranslateTable[ONEKEY ] = KX_ONEKEY; - m_reverseKeyTranslateTable[TWOKEY ] = KX_TWOKEY; - m_reverseKeyTranslateTable[THREEKEY ] = KX_THREEKEY; - m_reverseKeyTranslateTable[FOURKEY ] = KX_FOURKEY; - m_reverseKeyTranslateTable[FIVEKEY ] = KX_FIVEKEY; - m_reverseKeyTranslateTable[SIXKEY ] = KX_SIXKEY; - m_reverseKeyTranslateTable[SEVENKEY ] = KX_SEVENKEY; - m_reverseKeyTranslateTable[EIGHTKEY ] = KX_EIGHTKEY; - m_reverseKeyTranslateTable[NINEKEY ] = KX_NINEKEY; - - m_reverseKeyTranslateTable[CAPSLOCKKEY ] = KX_CAPSLOCKKEY; - - m_reverseKeyTranslateTable[LEFTCTRLKEY ] = KX_LEFTCTRLKEY; - m_reverseKeyTranslateTable[LEFTALTKEY ] = KX_LEFTALTKEY; - m_reverseKeyTranslateTable[RIGHTALTKEY ] = KX_RIGHTALTKEY; - m_reverseKeyTranslateTable[RIGHTCTRLKEY ] = KX_RIGHTCTRLKEY; - m_reverseKeyTranslateTable[RIGHTSHIFTKEY ] = KX_RIGHTSHIFTKEY; - m_reverseKeyTranslateTable[LEFTSHIFTKEY ] = KX_LEFTSHIFTKEY; - - m_reverseKeyTranslateTable[ESCKEY ] = KX_ESCKEY; - m_reverseKeyTranslateTable[TABKEY ] = KX_TABKEY; - m_reverseKeyTranslateTable[RETKEY ] = KX_RETKEY; - m_reverseKeyTranslateTable[SPACEKEY ] = KX_SPACEKEY; - m_reverseKeyTranslateTable[LINEFEEDKEY ] = KX_LINEFEEDKEY; - m_reverseKeyTranslateTable[BACKSPACEKEY ] = KX_BACKSPACEKEY; - m_reverseKeyTranslateTable[DELKEY ] = KX_DELKEY; - m_reverseKeyTranslateTable[SEMICOLONKEY ] = KX_SEMICOLONKEY; - m_reverseKeyTranslateTable[PERIODKEY ] = KX_PERIODKEY; - m_reverseKeyTranslateTable[COMMAKEY ] = KX_COMMAKEY; - m_reverseKeyTranslateTable[QUOTEKEY ] = KX_QUOTEKEY; - m_reverseKeyTranslateTable[ACCENTGRAVEKEY ] = KX_ACCENTGRAVEKEY; - m_reverseKeyTranslateTable[MINUSKEY ] = KX_MINUSKEY; - m_reverseKeyTranslateTable[SLASHKEY ] = KX_SLASHKEY; - m_reverseKeyTranslateTable[BACKSLASHKEY ] = KX_BACKSLASHKEY; - m_reverseKeyTranslateTable[EQUALKEY ] = KX_EQUALKEY; - m_reverseKeyTranslateTable[LEFTBRACKETKEY ] = KX_LEFTBRACKETKEY; - m_reverseKeyTranslateTable[RIGHTBRACKETKEY ] = KX_RIGHTBRACKETKEY; - - m_reverseKeyTranslateTable[LEFTARROWKEY ] = KX_LEFTARROWKEY; - m_reverseKeyTranslateTable[DOWNARROWKEY ] = KX_DOWNARROWKEY; - m_reverseKeyTranslateTable[RIGHTARROWKEY ] = KX_RIGHTARROWKEY; - m_reverseKeyTranslateTable[UPARROWKEY ] = KX_UPARROWKEY; - - m_reverseKeyTranslateTable[PAD2 ] = KX_PAD2; - m_reverseKeyTranslateTable[PAD4 ] = KX_PAD4; - m_reverseKeyTranslateTable[PAD6 ] = KX_PAD6; - m_reverseKeyTranslateTable[PAD8 ] = KX_PAD8; - - m_reverseKeyTranslateTable[PAD1 ] = KX_PAD1; - m_reverseKeyTranslateTable[PAD3 ] = KX_PAD3; - m_reverseKeyTranslateTable[PAD5 ] = KX_PAD5; - m_reverseKeyTranslateTable[PAD7 ] = KX_PAD7; - m_reverseKeyTranslateTable[PAD9 ] = KX_PAD9; - - m_reverseKeyTranslateTable[PADPERIOD ] = KX_PADPERIOD; - m_reverseKeyTranslateTable[PADSLASHKEY ] = KX_PADSLASHKEY; - m_reverseKeyTranslateTable[PADASTERKEY ] = KX_PADASTERKEY; - - - m_reverseKeyTranslateTable[PAD0 ] = KX_PAD0; - m_reverseKeyTranslateTable[PADMINUS ] = KX_PADMINUS; - m_reverseKeyTranslateTable[PADENTER ] = KX_PADENTER; - m_reverseKeyTranslateTable[PADPLUSKEY ] = KX_PADPLUSKEY; - - - m_reverseKeyTranslateTable[F1KEY ] = KX_F1KEY; - m_reverseKeyTranslateTable[F2KEY ] = KX_F2KEY; - m_reverseKeyTranslateTable[F3KEY ] = KX_F3KEY; - m_reverseKeyTranslateTable[F4KEY ] = KX_F4KEY; - m_reverseKeyTranslateTable[F5KEY ] = KX_F5KEY; - m_reverseKeyTranslateTable[F6KEY ] = KX_F6KEY; - m_reverseKeyTranslateTable[F7KEY ] = KX_F7KEY; - m_reverseKeyTranslateTable[F8KEY ] = KX_F8KEY; - m_reverseKeyTranslateTable[F9KEY ] = KX_F9KEY; - m_reverseKeyTranslateTable[F10KEY ] = KX_F10KEY; - m_reverseKeyTranslateTable[F11KEY ] = KX_F11KEY; - m_reverseKeyTranslateTable[F12KEY ] = KX_F12KEY; - m_reverseKeyTranslateTable[F13KEY ] = KX_F13KEY; - m_reverseKeyTranslateTable[F14KEY ] = KX_F14KEY; - m_reverseKeyTranslateTable[F15KEY ] = KX_F15KEY; - m_reverseKeyTranslateTable[F16KEY ] = KX_F16KEY; - m_reverseKeyTranslateTable[F17KEY ] = KX_F17KEY; - m_reverseKeyTranslateTable[F18KEY ] = KX_F18KEY; - m_reverseKeyTranslateTable[F19KEY ] = KX_F19KEY; - - m_reverseKeyTranslateTable[PAUSEKEY ] = KX_PAUSEKEY; - m_reverseKeyTranslateTable[INSERTKEY ] = KX_INSERTKEY; - m_reverseKeyTranslateTable[HOMEKEY ] = KX_HOMEKEY; - m_reverseKeyTranslateTable[PAGEUPKEY ] = KX_PAGEUPKEY; - m_reverseKeyTranslateTable[PAGEDOWNKEY ] = KX_PAGEDOWNKEY; - m_reverseKeyTranslateTable[ENDKEY ] = KX_ENDKEY; } virtual ~BL_BlenderInputDevice() @@ -225,7 +63,7 @@ public: } KX_EnumInputs ToNative(unsigned short incode) { - return m_reverseKeyTranslateTable[incode]; + return ConvertKeyCode(incode); } virtual bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)=0; diff --git a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp index a6712c531fb..54c60096812 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp @@ -36,6 +36,7 @@ #endif #include "KX_BlenderKeyboardDevice.h" +#include "KX_KetsjiEngine.h" KX_BlenderKeyboardDevice::KX_BlenderKeyboardDevice() : m_hookesc(false) @@ -106,7 +107,7 @@ bool KX_BlenderKeyboardDevice::ConvertBlenderEvent(unsigned short incode,short v if (val == KM_PRESS) { - if (kxevent == KX_ESCKEY && val != 0 && !m_hookesc) + if (kxevent == KX_KetsjiEngine::GetExitKey() && val != 0 && !m_hookesc) result = true; if (kxevent == KX_PAUSEKEY && val && (IsPressed(KX_LEFTCTRLKEY) || IsPressed(KX_RIGHTCTRLKEY))) result = true; diff --git a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h index 63a01db2fe0..3039e69efcd 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h @@ -50,6 +50,8 @@ public: virtual bool ConvertBlenderEvent(unsigned short incode,short val); virtual void NextFrame(); virtual void HookEscape(); +private: + short m_exit_key; #ifdef WITH_CXX_GUARDEDALLOC diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 57611d65e14..ff4b9ba9c96 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -197,6 +197,180 @@ extern "C" { static bool default_light_mode = 0; +static std::map<int, SCA_IInputDevice::KX_EnumInputs> create_translate_table() +{ + std::map<int, SCA_IInputDevice::KX_EnumInputs> m; + + /* The reverse table. In order to not confuse ourselves, we */ + /* immediately convert all events that come in to KX codes. */ + m[LEFTMOUSE ] = SCA_IInputDevice::KX_LEFTMOUSE; + m[MIDDLEMOUSE ] = SCA_IInputDevice::KX_MIDDLEMOUSE; + m[RIGHTMOUSE ] = SCA_IInputDevice::KX_RIGHTMOUSE; + m[WHEELUPMOUSE ] = SCA_IInputDevice::KX_WHEELUPMOUSE; + m[WHEELDOWNMOUSE ] = SCA_IInputDevice::KX_WHEELDOWNMOUSE; + m[MOUSEX ] = SCA_IInputDevice::KX_MOUSEX; + m[MOUSEY ] = SCA_IInputDevice::KX_MOUSEY; + + // TIMERS + + m[TIMER0 ] = SCA_IInputDevice::KX_TIMER0; + m[TIMER1 ] = SCA_IInputDevice::KX_TIMER1; + m[TIMER2 ] = SCA_IInputDevice::KX_TIMER2; + + // SYSTEM + +#if 0 + /* **** XXX **** */ + m[KEYBD ] = SCA_IInputDevice::KX_KEYBD; + m[RAWKEYBD ] = SCA_IInputDevice::KX_RAWKEYBD; + m[REDRAW ] = SCA_IInputDevice::KX_REDRAW; + m[INPUTCHANGE ] = SCA_IInputDevice::KX_INPUTCHANGE; + m[QFULL ] = SCA_IInputDevice::KX_QFULL; + m[WINFREEZE ] = SCA_IInputDevice::KX_WINFREEZE; + m[WINTHAW ] = SCA_IInputDevice::KX_WINTHAW; + m[WINCLOSE ] = SCA_IInputDevice::KX_WINCLOSE; + m[WINQUIT ] = SCA_IInputDevice::KX_WINQUIT; + m[Q_FIRSTTIME ] = SCA_IInputDevice::KX_Q_FIRSTTIME; + /* **** XXX **** */ +#endif + + // standard keyboard + + m[AKEY ] = SCA_IInputDevice::KX_AKEY; + m[BKEY ] = SCA_IInputDevice::KX_BKEY; + m[CKEY ] = SCA_IInputDevice::KX_CKEY; + m[DKEY ] = SCA_IInputDevice::KX_DKEY; + m[EKEY ] = SCA_IInputDevice::KX_EKEY; + m[FKEY ] = SCA_IInputDevice::KX_FKEY; + m[GKEY ] = SCA_IInputDevice::KX_GKEY; + +//XXX clean up +#ifdef WIN32 +#define HKEY 'h' +#endif + m[HKEY ] = SCA_IInputDevice::KX_HKEY; +//XXX clean up +#ifdef WIN32 +#undef HKEY +#endif + + m[IKEY ] = SCA_IInputDevice::KX_IKEY; + m[JKEY ] = SCA_IInputDevice::KX_JKEY; + m[KKEY ] = SCA_IInputDevice::KX_KKEY; + m[LKEY ] = SCA_IInputDevice::KX_LKEY; + m[MKEY ] = SCA_IInputDevice::KX_MKEY; + m[NKEY ] = SCA_IInputDevice::KX_NKEY; + m[OKEY ] = SCA_IInputDevice::KX_OKEY; + m[PKEY ] = SCA_IInputDevice::KX_PKEY; + m[QKEY ] = SCA_IInputDevice::KX_QKEY; + m[RKEY ] = SCA_IInputDevice::KX_RKEY; + m[SKEY ] = SCA_IInputDevice::KX_SKEY; + m[TKEY ] = SCA_IInputDevice::KX_TKEY; + m[UKEY ] = SCA_IInputDevice::KX_UKEY; + m[VKEY ] = SCA_IInputDevice::KX_VKEY; + m[WKEY ] = SCA_IInputDevice::KX_WKEY; + m[XKEY ] = SCA_IInputDevice::KX_XKEY; + m[YKEY ] = SCA_IInputDevice::KX_YKEY; + m[ZKEY ] = SCA_IInputDevice::KX_ZKEY; + + m[ZEROKEY ] = SCA_IInputDevice::KX_ZEROKEY; + m[ONEKEY ] = SCA_IInputDevice::KX_ONEKEY; + m[TWOKEY ] = SCA_IInputDevice::KX_TWOKEY; + m[THREEKEY ] = SCA_IInputDevice::KX_THREEKEY; + m[FOURKEY ] = SCA_IInputDevice::KX_FOURKEY; + m[FIVEKEY ] = SCA_IInputDevice::KX_FIVEKEY; + m[SIXKEY ] = SCA_IInputDevice::KX_SIXKEY; + m[SEVENKEY ] = SCA_IInputDevice::KX_SEVENKEY; + m[EIGHTKEY ] = SCA_IInputDevice::KX_EIGHTKEY; + m[NINEKEY ] = SCA_IInputDevice::KX_NINEKEY; + + m[CAPSLOCKKEY ] = SCA_IInputDevice::KX_CAPSLOCKKEY; + + m[LEFTCTRLKEY ] = SCA_IInputDevice::KX_LEFTCTRLKEY; + m[LEFTALTKEY ] = SCA_IInputDevice::KX_LEFTALTKEY; + m[RIGHTALTKEY ] = SCA_IInputDevice::KX_RIGHTALTKEY; + m[RIGHTCTRLKEY ] = SCA_IInputDevice::KX_RIGHTCTRLKEY; + m[RIGHTSHIFTKEY ] = SCA_IInputDevice::KX_RIGHTSHIFTKEY; + m[LEFTSHIFTKEY ] = SCA_IInputDevice::KX_LEFTSHIFTKEY; + + m[ESCKEY ] = SCA_IInputDevice::KX_ESCKEY; + m[TABKEY ] = SCA_IInputDevice::KX_TABKEY; + m[RETKEY ] = SCA_IInputDevice::KX_RETKEY; + m[SPACEKEY ] = SCA_IInputDevice::KX_SPACEKEY; + m[LINEFEEDKEY ] = SCA_IInputDevice::KX_LINEFEEDKEY; + m[BACKSPACEKEY ] = SCA_IInputDevice::KX_BACKSPACEKEY; + m[DELKEY ] = SCA_IInputDevice::KX_DELKEY; + m[SEMICOLONKEY ] = SCA_IInputDevice::KX_SEMICOLONKEY; + m[PERIODKEY ] = SCA_IInputDevice::KX_PERIODKEY; + m[COMMAKEY ] = SCA_IInputDevice::KX_COMMAKEY; + m[QUOTEKEY ] = SCA_IInputDevice::KX_QUOTEKEY; + m[ACCENTGRAVEKEY ] = SCA_IInputDevice::KX_ACCENTGRAVEKEY; + m[MINUSKEY ] = SCA_IInputDevice::KX_MINUSKEY; + m[SLASHKEY ] = SCA_IInputDevice::KX_SLASHKEY; + m[BACKSLASHKEY ] = SCA_IInputDevice::KX_BACKSLASHKEY; + m[EQUALKEY ] = SCA_IInputDevice::KX_EQUALKEY; + m[LEFTBRACKETKEY ] = SCA_IInputDevice::KX_LEFTBRACKETKEY; + m[RIGHTBRACKETKEY ] = SCA_IInputDevice::KX_RIGHTBRACKETKEY; + + m[LEFTARROWKEY ] = SCA_IInputDevice::KX_LEFTARROWKEY; + m[DOWNARROWKEY ] = SCA_IInputDevice::KX_DOWNARROWKEY; + m[RIGHTARROWKEY ] = SCA_IInputDevice::KX_RIGHTARROWKEY; + m[UPARROWKEY ] = SCA_IInputDevice::KX_UPARROWKEY; + + m[PAD2 ] = SCA_IInputDevice::KX_PAD2; + m[PAD4 ] = SCA_IInputDevice::KX_PAD4; + m[PAD6 ] = SCA_IInputDevice::KX_PAD6; + m[PAD8 ] = SCA_IInputDevice::KX_PAD8; + + m[PAD1 ] = SCA_IInputDevice::KX_PAD1; + m[PAD3 ] = SCA_IInputDevice::KX_PAD3; + m[PAD5 ] = SCA_IInputDevice::KX_PAD5; + m[PAD7 ] = SCA_IInputDevice::KX_PAD7; + m[PAD9 ] = SCA_IInputDevice::KX_PAD9; + + m[PADPERIOD ] = SCA_IInputDevice::KX_PADPERIOD; + m[PADSLASHKEY ] = SCA_IInputDevice::KX_PADSLASHKEY; + m[PADASTERKEY ] = SCA_IInputDevice::KX_PADASTERKEY; + + m[PAD0 ] = SCA_IInputDevice::KX_PAD0; + m[PADMINUS ] = SCA_IInputDevice::KX_PADMINUS; + m[PADENTER ] = SCA_IInputDevice::KX_PADENTER; + m[PADPLUSKEY ] = SCA_IInputDevice::KX_PADPLUSKEY; + + + m[F1KEY ] = SCA_IInputDevice::KX_F1KEY; + m[F2KEY ] = SCA_IInputDevice::KX_F2KEY; + m[F3KEY ] = SCA_IInputDevice::KX_F3KEY; + m[F4KEY ] = SCA_IInputDevice::KX_F4KEY; + m[F5KEY ] = SCA_IInputDevice::KX_F5KEY; + m[F6KEY ] = SCA_IInputDevice::KX_F6KEY; + m[F7KEY ] = SCA_IInputDevice::KX_F7KEY; + m[F8KEY ] = SCA_IInputDevice::KX_F8KEY; + m[F9KEY ] = SCA_IInputDevice::KX_F9KEY; + m[F10KEY ] = SCA_IInputDevice::KX_F10KEY; + m[F11KEY ] = SCA_IInputDevice::KX_F11KEY; + m[F12KEY ] = SCA_IInputDevice::KX_F12KEY; + m[F13KEY ] = SCA_IInputDevice::KX_F13KEY; + m[F14KEY ] = SCA_IInputDevice::KX_F14KEY; + m[F15KEY ] = SCA_IInputDevice::KX_F15KEY; + m[F16KEY ] = SCA_IInputDevice::KX_F16KEY; + m[F17KEY ] = SCA_IInputDevice::KX_F17KEY; + m[F18KEY ] = SCA_IInputDevice::KX_F18KEY; + m[F19KEY ] = SCA_IInputDevice::KX_F19KEY; + + + m[PAUSEKEY ] = SCA_IInputDevice::KX_PAUSEKEY; + m[INSERTKEY ] = SCA_IInputDevice::KX_INSERTKEY; + m[HOMEKEY ] = SCA_IInputDevice::KX_HOMEKEY; + m[PAGEUPKEY ] = SCA_IInputDevice::KX_PAGEUPKEY; + m[PAGEDOWNKEY ] = SCA_IInputDevice::KX_PAGEDOWNKEY; + m[ENDKEY ] = SCA_IInputDevice::KX_ENDKEY; + + return m; +} + +static std::map<int, SCA_IInputDevice::KX_EnumInputs> gReverseKeyTranslateTable = create_translate_table(); + static unsigned int KX_rgbaint2uint_new(unsigned int icol) { union @@ -2854,3 +3028,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, RAS_BucketManager *bucketmanager = kxscene->GetBucketManager(); bucketmanager->OptimizeBuckets(distance); } + +SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code) +{ + return gReverseKeyTranslateTable[key_code]; +}
\ No newline at end of file diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.h b/source/gameengine/Converter/BL_BlenderDataConversion.h index 2ae7fee1798..6da3ac90aef 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.h +++ b/source/gameengine/Converter/BL_BlenderDataConversion.h @@ -36,6 +36,7 @@ #include "STR_String.h" #include "KX_Python.h" #include "KX_PhysicsEngineEnums.h" +#include "SCA_IInputDevice.h" class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class KX_Scene* scene, class KX_BlenderSceneConverter *converter); @@ -49,5 +50,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, bool alwaysUseExpandFraming ); +SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code); + #endif // __BLENDER_CONVERT diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp index b7aee8ec924..9391d12a3ce 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.cpp +++ b/source/gameengine/Converter/KX_ConvertSensors.cpp @@ -86,10 +86,7 @@ probably misplaced */ #include "KX_KetsjiEngine.h" #include "KX_BlenderSceneConverter.h" - -// this map is Blender specific: a conversion between blender and ketsji enums -std::map<int,SCA_IInputDevice::KX_EnumInputs> gReverseKeyTranslateTable; - +#include "BL_BlenderDataConversion.h" void BL_ConvertSensors(struct Object* blenderobject, class KX_GameObject* gameobj, @@ -102,177 +99,6 @@ void BL_ConvertSensors(struct Object* blenderobject, KX_BlenderSceneConverter* converter ) { - static bool reverseTableConverted = false; - - if (!reverseTableConverted) - { - reverseTableConverted = true; - - /* The reverse table. In order to not confuse ourselves, we */ - /* immediately convert all events that come in to KX codes. */ - gReverseKeyTranslateTable[LEFTMOUSE ] = SCA_IInputDevice::KX_LEFTMOUSE; - gReverseKeyTranslateTable[MIDDLEMOUSE ] = SCA_IInputDevice::KX_MIDDLEMOUSE; - gReverseKeyTranslateTable[RIGHTMOUSE ] = SCA_IInputDevice::KX_RIGHTMOUSE; - gReverseKeyTranslateTable[WHEELUPMOUSE ] = SCA_IInputDevice::KX_WHEELUPMOUSE; - gReverseKeyTranslateTable[WHEELDOWNMOUSE ] = SCA_IInputDevice::KX_WHEELDOWNMOUSE; - gReverseKeyTranslateTable[MOUSEX ] = SCA_IInputDevice::KX_MOUSEX; - gReverseKeyTranslateTable[MOUSEY ] = SCA_IInputDevice::KX_MOUSEY; - - // TIMERS - - gReverseKeyTranslateTable[TIMER0 ] = SCA_IInputDevice::KX_TIMER0; - gReverseKeyTranslateTable[TIMER1 ] = SCA_IInputDevice::KX_TIMER1; - gReverseKeyTranslateTable[TIMER2 ] = SCA_IInputDevice::KX_TIMER2; - - // SYSTEM - -#if 0 - /* **** XXX **** */ - gReverseKeyTranslateTable[KEYBD ] = SCA_IInputDevice::KX_KEYBD; - gReverseKeyTranslateTable[RAWKEYBD ] = SCA_IInputDevice::KX_RAWKEYBD; - gReverseKeyTranslateTable[REDRAW ] = SCA_IInputDevice::KX_REDRAW; - gReverseKeyTranslateTable[INPUTCHANGE ] = SCA_IInputDevice::KX_INPUTCHANGE; - gReverseKeyTranslateTable[QFULL ] = SCA_IInputDevice::KX_QFULL; - gReverseKeyTranslateTable[WINFREEZE ] = SCA_IInputDevice::KX_WINFREEZE; - gReverseKeyTranslateTable[WINTHAW ] = SCA_IInputDevice::KX_WINTHAW; - gReverseKeyTranslateTable[WINCLOSE ] = SCA_IInputDevice::KX_WINCLOSE; - gReverseKeyTranslateTable[WINQUIT ] = SCA_IInputDevice::KX_WINQUIT; - gReverseKeyTranslateTable[Q_FIRSTTIME ] = SCA_IInputDevice::KX_Q_FIRSTTIME; - /* **** XXX **** */ -#endif - - // standard keyboard - - gReverseKeyTranslateTable[AKEY ] = SCA_IInputDevice::KX_AKEY; - gReverseKeyTranslateTable[BKEY ] = SCA_IInputDevice::KX_BKEY; - gReverseKeyTranslateTable[CKEY ] = SCA_IInputDevice::KX_CKEY; - gReverseKeyTranslateTable[DKEY ] = SCA_IInputDevice::KX_DKEY; - gReverseKeyTranslateTable[EKEY ] = SCA_IInputDevice::KX_EKEY; - gReverseKeyTranslateTable[FKEY ] = SCA_IInputDevice::KX_FKEY; - gReverseKeyTranslateTable[GKEY ] = SCA_IInputDevice::KX_GKEY; - -//XXX clean up -#ifdef WIN32 -#define HKEY 'h' -#endif - gReverseKeyTranslateTable[HKEY ] = SCA_IInputDevice::KX_HKEY; -//XXX clean up -#ifdef WIN32 -#undef HKEY -#endif - - gReverseKeyTranslateTable[IKEY ] = SCA_IInputDevice::KX_IKEY; - gReverseKeyTranslateTable[JKEY ] = SCA_IInputDevice::KX_JKEY; - gReverseKeyTranslateTable[KKEY ] = SCA_IInputDevice::KX_KKEY; - gReverseKeyTranslateTable[LKEY ] = SCA_IInputDevice::KX_LKEY; - gReverseKeyTranslateTable[MKEY ] = SCA_IInputDevice::KX_MKEY; - gReverseKeyTranslateTable[NKEY ] = SCA_IInputDevice::KX_NKEY; - gReverseKeyTranslateTable[OKEY ] = SCA_IInputDevice::KX_OKEY; - gReverseKeyTranslateTable[PKEY ] = SCA_IInputDevice::KX_PKEY; - gReverseKeyTranslateTable[QKEY ] = SCA_IInputDevice::KX_QKEY; - gReverseKeyTranslateTable[RKEY ] = SCA_IInputDevice::KX_RKEY; - gReverseKeyTranslateTable[SKEY ] = SCA_IInputDevice::KX_SKEY; - gReverseKeyTranslateTable[TKEY ] = SCA_IInputDevice::KX_TKEY; - gReverseKeyTranslateTable[UKEY ] = SCA_IInputDevice::KX_UKEY; - gReverseKeyTranslateTable[VKEY ] = SCA_IInputDevice::KX_VKEY; - gReverseKeyTranslateTable[WKEY ] = SCA_IInputDevice::KX_WKEY; - gReverseKeyTranslateTable[XKEY ] = SCA_IInputDevice::KX_XKEY; - gReverseKeyTranslateTable[YKEY ] = SCA_IInputDevice::KX_YKEY; - gReverseKeyTranslateTable[ZKEY ] = SCA_IInputDevice::KX_ZKEY; - - gReverseKeyTranslateTable[ZEROKEY ] = SCA_IInputDevice::KX_ZEROKEY; - gReverseKeyTranslateTable[ONEKEY ] = SCA_IInputDevice::KX_ONEKEY; - gReverseKeyTranslateTable[TWOKEY ] = SCA_IInputDevice::KX_TWOKEY; - gReverseKeyTranslateTable[THREEKEY ] = SCA_IInputDevice::KX_THREEKEY; - gReverseKeyTranslateTable[FOURKEY ] = SCA_IInputDevice::KX_FOURKEY; - gReverseKeyTranslateTable[FIVEKEY ] = SCA_IInputDevice::KX_FIVEKEY; - gReverseKeyTranslateTable[SIXKEY ] = SCA_IInputDevice::KX_SIXKEY; - gReverseKeyTranslateTable[SEVENKEY ] = SCA_IInputDevice::KX_SEVENKEY; - gReverseKeyTranslateTable[EIGHTKEY ] = SCA_IInputDevice::KX_EIGHTKEY; - gReverseKeyTranslateTable[NINEKEY ] = SCA_IInputDevice::KX_NINEKEY; - - gReverseKeyTranslateTable[CAPSLOCKKEY ] = SCA_IInputDevice::KX_CAPSLOCKKEY; - - gReverseKeyTranslateTable[LEFTCTRLKEY ] = SCA_IInputDevice::KX_LEFTCTRLKEY; - gReverseKeyTranslateTable[LEFTALTKEY ] = SCA_IInputDevice::KX_LEFTALTKEY; - gReverseKeyTranslateTable[RIGHTALTKEY ] = SCA_IInputDevice::KX_RIGHTALTKEY; - gReverseKeyTranslateTable[RIGHTCTRLKEY ] = SCA_IInputDevice::KX_RIGHTCTRLKEY; - gReverseKeyTranslateTable[RIGHTSHIFTKEY ] = SCA_IInputDevice::KX_RIGHTSHIFTKEY; - gReverseKeyTranslateTable[LEFTSHIFTKEY ] = SCA_IInputDevice::KX_LEFTSHIFTKEY; - - gReverseKeyTranslateTable[ESCKEY ] = SCA_IInputDevice::KX_ESCKEY; - gReverseKeyTranslateTable[TABKEY ] = SCA_IInputDevice::KX_TABKEY; - gReverseKeyTranslateTable[RETKEY ] = SCA_IInputDevice::KX_RETKEY; - gReverseKeyTranslateTable[SPACEKEY ] = SCA_IInputDevice::KX_SPACEKEY; - gReverseKeyTranslateTable[LINEFEEDKEY ] = SCA_IInputDevice::KX_LINEFEEDKEY; - gReverseKeyTranslateTable[BACKSPACEKEY ] = SCA_IInputDevice::KX_BACKSPACEKEY; - gReverseKeyTranslateTable[DELKEY ] = SCA_IInputDevice::KX_DELKEY; - gReverseKeyTranslateTable[SEMICOLONKEY ] = SCA_IInputDevice::KX_SEMICOLONKEY; - gReverseKeyTranslateTable[PERIODKEY ] = SCA_IInputDevice::KX_PERIODKEY; - gReverseKeyTranslateTable[COMMAKEY ] = SCA_IInputDevice::KX_COMMAKEY; - gReverseKeyTranslateTable[QUOTEKEY ] = SCA_IInputDevice::KX_QUOTEKEY; - gReverseKeyTranslateTable[ACCENTGRAVEKEY ] = SCA_IInputDevice::KX_ACCENTGRAVEKEY; - gReverseKeyTranslateTable[MINUSKEY ] = SCA_IInputDevice::KX_MINUSKEY; - gReverseKeyTranslateTable[SLASHKEY ] = SCA_IInputDevice::KX_SLASHKEY; - gReverseKeyTranslateTable[BACKSLASHKEY ] = SCA_IInputDevice::KX_BACKSLASHKEY; - gReverseKeyTranslateTable[EQUALKEY ] = SCA_IInputDevice::KX_EQUALKEY; - gReverseKeyTranslateTable[LEFTBRACKETKEY ] = SCA_IInputDevice::KX_LEFTBRACKETKEY; - gReverseKeyTranslateTable[RIGHTBRACKETKEY ] = SCA_IInputDevice::KX_RIGHTBRACKETKEY; - - gReverseKeyTranslateTable[LEFTARROWKEY ] = SCA_IInputDevice::KX_LEFTARROWKEY; - gReverseKeyTranslateTable[DOWNARROWKEY ] = SCA_IInputDevice::KX_DOWNARROWKEY; - gReverseKeyTranslateTable[RIGHTARROWKEY ] = SCA_IInputDevice::KX_RIGHTARROWKEY; - gReverseKeyTranslateTable[UPARROWKEY ] = SCA_IInputDevice::KX_UPARROWKEY; - - gReverseKeyTranslateTable[PAD2 ] = SCA_IInputDevice::KX_PAD2; - gReverseKeyTranslateTable[PAD4 ] = SCA_IInputDevice::KX_PAD4; - gReverseKeyTranslateTable[PAD6 ] = SCA_IInputDevice::KX_PAD6; - gReverseKeyTranslateTable[PAD8 ] = SCA_IInputDevice::KX_PAD8; - - gReverseKeyTranslateTable[PAD1 ] = SCA_IInputDevice::KX_PAD1; - gReverseKeyTranslateTable[PAD3 ] = SCA_IInputDevice::KX_PAD3; - gReverseKeyTranslateTable[PAD5 ] = SCA_IInputDevice::KX_PAD5; - gReverseKeyTranslateTable[PAD7 ] = SCA_IInputDevice::KX_PAD7; - gReverseKeyTranslateTable[PAD9 ] = SCA_IInputDevice::KX_PAD9; - - gReverseKeyTranslateTable[PADPERIOD ] = SCA_IInputDevice::KX_PADPERIOD; - gReverseKeyTranslateTable[PADSLASHKEY ] = SCA_IInputDevice::KX_PADSLASHKEY; - gReverseKeyTranslateTable[PADASTERKEY ] = SCA_IInputDevice::KX_PADASTERKEY; - - gReverseKeyTranslateTable[PAD0 ] = SCA_IInputDevice::KX_PAD0; - gReverseKeyTranslateTable[PADMINUS ] = SCA_IInputDevice::KX_PADMINUS; - gReverseKeyTranslateTable[PADENTER ] = SCA_IInputDevice::KX_PADENTER; - gReverseKeyTranslateTable[PADPLUSKEY ] = SCA_IInputDevice::KX_PADPLUSKEY; - - - gReverseKeyTranslateTable[F1KEY ] = SCA_IInputDevice::KX_F1KEY; - gReverseKeyTranslateTable[F2KEY ] = SCA_IInputDevice::KX_F2KEY; - gReverseKeyTranslateTable[F3KEY ] = SCA_IInputDevice::KX_F3KEY; - gReverseKeyTranslateTable[F4KEY ] = SCA_IInputDevice::KX_F4KEY; - gReverseKeyTranslateTable[F5KEY ] = SCA_IInputDevice::KX_F5KEY; - gReverseKeyTranslateTable[F6KEY ] = SCA_IInputDevice::KX_F6KEY; - gReverseKeyTranslateTable[F7KEY ] = SCA_IInputDevice::KX_F7KEY; - gReverseKeyTranslateTable[F8KEY ] = SCA_IInputDevice::KX_F8KEY; - gReverseKeyTranslateTable[F9KEY ] = SCA_IInputDevice::KX_F9KEY; - gReverseKeyTranslateTable[F10KEY ] = SCA_IInputDevice::KX_F10KEY; - gReverseKeyTranslateTable[F11KEY ] = SCA_IInputDevice::KX_F11KEY; - gReverseKeyTranslateTable[F12KEY ] = SCA_IInputDevice::KX_F12KEY; - gReverseKeyTranslateTable[F13KEY ] = SCA_IInputDevice::KX_F13KEY; - gReverseKeyTranslateTable[F14KEY ] = SCA_IInputDevice::KX_F14KEY; - gReverseKeyTranslateTable[F15KEY ] = SCA_IInputDevice::KX_F15KEY; - gReverseKeyTranslateTable[F16KEY ] = SCA_IInputDevice::KX_F16KEY; - gReverseKeyTranslateTable[F17KEY ] = SCA_IInputDevice::KX_F17KEY; - gReverseKeyTranslateTable[F18KEY ] = SCA_IInputDevice::KX_F18KEY; - gReverseKeyTranslateTable[F19KEY ] = SCA_IInputDevice::KX_F19KEY; - - - gReverseKeyTranslateTable[PAUSEKEY ] = SCA_IInputDevice::KX_PAUSEKEY; - gReverseKeyTranslateTable[INSERTKEY ] = SCA_IInputDevice::KX_INSERTKEY; - gReverseKeyTranslateTable[HOMEKEY ] = SCA_IInputDevice::KX_HOMEKEY; - gReverseKeyTranslateTable[PAGEUPKEY ] = SCA_IInputDevice::KX_PAGEUPKEY; - gReverseKeyTranslateTable[PAGEDOWNKEY ] = SCA_IInputDevice::KX_PAGEDOWNKEY; - gReverseKeyTranslateTable[ENDKEY ] = SCA_IInputDevice::KX_ENDKEY; - } int executePriority = 0; int uniqueint = 0; @@ -470,9 +296,9 @@ void BL_ConvertSensors(struct Object* blenderobject, if (eventmgr) { gamesensor = new SCA_KeyboardSensor(eventmgr, - gReverseKeyTranslateTable[blenderkeybdsensor->key], - gReverseKeyTranslateTable[blenderkeybdsensor->qual], - gReverseKeyTranslateTable[blenderkeybdsensor->qual2], + ConvertKeyCode(blenderkeybdsensor->key), + ConvertKeyCode(blenderkeybdsensor->qual), + ConvertKeyCode(blenderkeybdsensor->qual2), (blenderkeybdsensor->type == SENS_ALL_KEYS), blenderkeybdsensor->targetName, blenderkeybdsensor->toggleName, diff --git a/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h b/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h index 5b267c92908..3d88dc467b0 100644 --- a/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h +++ b/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h @@ -57,6 +57,7 @@ protected: * System dependent keyboard codes are stored as ints. */ std::map<int, KX_EnumInputs> m_reverseKeyTranslateTable; + short m_exitkey; public: bool m_hookesc; diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index 7490e187824..f9403c9725a 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -40,6 +40,7 @@ #include "GPU_extensions.h" #include "GPG_Application.h" +#include "BL_BlenderDataConversion.h" #include <iostream> #include <MT_assert.h> @@ -626,6 +627,8 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) m_ketsjiengine->SetRasterizer(m_rasterizer); m_ketsjiengine->SetTimingDisplay(frameRate, false, false); + + KX_KetsjiEngine::SetExitKey(ConvertKeyCode(gm->exitkey)); #ifdef WITH_PYTHON CValue::SetDeprecationWarnings(nodepwarnings); #else @@ -908,12 +911,10 @@ bool GPG_Application::handleKey(GHOST_IEvent* event, bool isDown) { GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData(); GHOST_TEventKeyData* keyData = static_cast<GHOST_TEventKeyData*>(eventData); - //no need for this test - //if (fSystem->getFullScreen()) { - if (keyData->key == GHOST_kKeyEsc && !m_keyboard->m_hookesc && !m_isEmbedded) { - m_exitRequested = KX_EXIT_REQUEST_OUTSIDE; - } - //} + + if (m_keyboard->ToNative(keyData->key) == KX_KetsjiEngine::GetExitKey() && !m_keyboard->m_hookesc && !m_isEmbedded) { + m_exitRequested = KX_EXIT_REQUEST_OUTSIDE; + } m_keyboard->ConvertEvent(keyData->key, isDown); handled = true; } diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.h b/source/gameengine/GamePlayer/ghost/GPG_Application.h index a8a976f9dd2..37625dc8998 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.h +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.h @@ -103,6 +103,7 @@ protected: * Shuts the game engine down. */ void exitEngine(void); + short m_exitkey; /* The game data */ STR_String m_startSceneName; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index a9be588e6b2..29727dc04da 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -110,6 +110,7 @@ double KX_KetsjiEngine::m_suspendedtime = 0.0; double KX_KetsjiEngine::m_suspendeddelta = 0.0; double KX_KetsjiEngine::m_average_framerate = 0.0; bool KX_KetsjiEngine::m_restrict_anim_fps = false; +short KX_KetsjiEngine::m_exitkey = 130; //ESC Key /** @@ -1857,6 +1858,16 @@ double KX_KetsjiEngine::GetAverageFrameRate() return m_average_framerate; } +void KX_KetsjiEngine::SetExitKey(short key) +{ + m_exitkey = key; +} + +short KX_KetsjiEngine::GetExitKey() +{ + return m_exitkey; +} + void KX_KetsjiEngine::SetTimingDisplay(bool frameRate, bool profile, bool properties) { m_show_framerate = frameRate; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 5a02da07e43..96b737b686d 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -124,6 +124,8 @@ private: static double m_suspendedtime; static double m_suspendeddelta; + static short m_exitkey; /* Key used to exit the BGE */ + int m_exitcode; STR_String m_exitstring; /** @@ -352,6 +354,10 @@ public: */ static double GetAverageFrameRate(); + static void SetExitKey(short key); + + static short GetExitKey(); + /** * Activates or deactivates timing information display. * @param frameRate Display for frame rate on or off. diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 29871c2b3cd..9a2c0cb89b1 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -419,6 +419,20 @@ static PyObject* gPyGetLogicTicRate(PyObject*) return PyFloat_FromDouble(KX_KetsjiEngine::GetTicRate()); } +static PyObject* gPySetExitKey(PyObject*, PyObject* args) +{ + short exitkey; + if (!PyArg_ParseTuple(args, "h:setExitKey", &exitkey)) + return NULL; + KX_KetsjiEngine::SetExitKey(exitkey); + Py_RETURN_NONE; +} + +static PyObject* gPyGetExitKey(PyObject*) +{ + return PyLong_FromSsize_t(KX_KetsjiEngine::GetExitKey()); +} + static PyObject* gPySetMaxLogicFrame(PyObject*, PyObject* args) { int frame; @@ -812,6 +826,8 @@ static struct PyMethodDef game_methods[] = { {"setLogicTicRate", (PyCFunction) gPySetLogicTicRate, METH_VARARGS, (const char *)"Sets the logic tic rate"}, {"getPhysicsTicRate", (PyCFunction) gPyGetPhysicsTicRate, METH_NOARGS, (const char *)"Gets the physics tic rate"}, {"setPhysicsTicRate", (PyCFunction) gPySetPhysicsTicRate, METH_VARARGS, (const char *)"Sets the physics tic rate"}, + {"getExitKey", (PyCFunction) gPyGetExitKey, METH_NOARGS, (const char *)"Gets the key used to exit the game engine"}, + {"setExitKey", (PyCFunction) gPySetExitKey, METH_VARARGS, (const char *)"Sets the key used to exit the game engine"}, {"getAverageFrameRate", (PyCFunction) gPyGetAverageFrameRate, METH_NOARGS, (const char *)"Gets the estimated average frame rate"}, {"getBlendFileList", (PyCFunction)gPyGetBlendFileList, METH_VARARGS, (const char *)"Gets a list of blend files in the same directory as the current blend file"}, {"PrintGLInfo", (PyCFunction)pyPrintExt, METH_NOARGS, (const char *)"Prints GL Extension Info"}, diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt index 40d304ef4b9..74a0ad1c628 100644 --- a/source/tests/CMakeLists.txt +++ b/source/tests/CMakeLists.txt @@ -60,6 +60,11 @@ add_test(script_run_operators ${TEST_BLENDER_EXE} --python ${CMAKE_CURRENT_LIST_DIR}/bl_run_operators.py ) +# test running mathutils testing script +add_test(script_pyapi_mathutils ${TEST_BLENDER_EXE} + --python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_mathutils.py +) + # ------------------------------------------------------------------------------ # IO TESTS diff --git a/source/tests/bl_pyapi_mathutils.py b/source/tests/bl_pyapi_mathutils.py new file mode 100644 index 00000000000..f1d6d96c68b --- /dev/null +++ b/source/tests/bl_pyapi_mathutils.py @@ -0,0 +1,109 @@ +import unittest +from test import support +from mathutils import Matrix, Vector + + +class MatrixTesting(unittest.TestCase): + def test_matrix_column_access(self): + #mat = + #[ 1 2 3 4 ] + #[ 1 2 3 4 ] + #[ 1 2 3 4 ] + mat = Matrix(((1, 11, 111), + (2, 22, 222), + (3, 33, 333), + (4, 44, 444))) + + self.assertEqual(mat[0], Vector((1, 11, 111))) + self.assertEqual(mat[1], Vector((2, 22, 222))) + self.assertEqual(mat[2], Vector((3, 33, 333))) + self.assertEqual(mat[3], Vector((4, 44, 444))) + + def test_item_access(self): + args = ((1, 4, 0, -1), + (2, -1, 2, -2), + (0, 3, 8, 3), + (-2, 9, 1, 0)) + + mat = Matrix(args) + + for i in range(4): + for j in range(4): + self.assertEqual(mat[i][j], args[i][j]) + + self.assertEqual(mat[0][2], 0) + self.assertEqual(mat[3][1], 9) + self.assertEqual(mat[2][3], 3) + self.assertEqual(mat[0][0], 1) + self.assertEqual(mat[3][3], 0) + + def test_item_assignment(self): + mat = Matrix() - Matrix() + indices = (0, 0), (1, 3), (2, 0), (3, 2), (3, 1) + checked_indices = [] + for col, row in indices: + mat[col][row] = 1 + + for col in range(4): + for row in range(4): + if mat[col][row]: + checked_indices.append((col, row)) + + for item in checked_indices: + self.assertIn(item, indices) + + def test_matrix_to_3x3(self): + #mat = + #[ 1 2 3 4 ] + #[ 2 4 6 8 ] + #[ 3 6 9 12 ] + #[ 4 8 12 16 ] + mat = Matrix(tuple((i, 2 * i, 3 * i, 4 * i) for i in range(1, 5))) + mat_correct = Matrix(((1, 2, 3), (2, 4, 6), (3, 6, 9))) + self.assertEqual(mat.to_3x3(), mat_correct) + + def test_matrix_to_translation(self): + mat = Matrix() + mat[3] = (1, 2, 3, 4) + self.assertEqual(mat.to_translation(), Vector((1, 2, 3))) + + def test_matrix_inverse(self): + mat = Matrix(((1, 4, 0, -1), + (2, -1, 2, -2), + (0, 3, 8, 3), + (-2, 9, 1, 0))) + + inv_mat = (1 / 285) * Matrix(((195, -57, 27, -102), + (50, -19, 4, 6), + (-60, 57, 18, 27), + (110, -133, 43, -78))) + + self.assertEqual(mat.inverted(), inv_mat) + + def test_matrix_mult(self): + mat = Matrix(((1, 4, 0, -1), + (2, -1, 2, -2), + (0, 3, 8, 3), + (-2, 9, 1, 0))) + + prod_mat = Matrix(((11, -9, 7, -9), + (4, -3, 12, 6), + (0, 48, 73, 18), + (16, -14, 26, -13))) + + self.assertEqual(mat * mat, prod_mat) + + +def test_main(): + try: + support.run_unittest(MatrixTesting) + except: + import traceback + traceback.print_exc() + + # alert CTest we failed + import sys + sys.exit(1) + +if __name__ == '__main__': + test_main() |