diff --git a/CMakeLists.txt b/CMakeLists.txt index f201a5577f4..f64285314a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,6 +156,7 @@ endif() if(UNIX AND NOT APPLE) option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)" ON) + option(WITH_X11_XF86VMODE "Enable X11 video mode switching" OFF) option(WITH_BUILTIN_GLEW "Use GLEW OpenGL wrapper library bundled with blender" ON) option(WITH_XDG_USER_DIRS "Build with XDG Base Directory Specification (only config and documents for now)" OFF) mark_as_advanced(WITH_XDG_USER_DIRS) @@ -584,6 +585,17 @@ if(UNIX AND NOT APPLE) if(WITH_X11_XINPUT) set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} ${X11_Xinput_LIB}") endif() + + if(WITH_X11_XF86VMODE) + # XXX, why dont cmake make this available? + FIND_LIBRARY(X11_Xxf86vmode_LIB Xxf86vm ${X11_LIB_SEARCH_PATH}) + mark_as_advanced(X11_Xxf86vmode_LIB) + if(X11_Xxf86vmode_LIB) + set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} ${X11_Xxf86vmode_LIB}") + else() + set(WITH_X11_XF86VMODE OFF) + endif() + endif() endif() if(CMAKE_SYSTEM_NAME MATCHES "Linux") @@ -1547,6 +1559,7 @@ if(FIRST_RUN) info_cfg_text("System Options:") info_cfg_option(WITH_INSTALL_PORTABLE) + info_cfg_option(WITH_X11_XF86VMODE) info_cfg_option(WITH_X11_XINPUT) info_cfg_option(WITH_BUILTIN_GLEW) diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index b3c9cccfb5d..c7844782e78 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -78,8 +78,9 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< for(b_mesh.faces.begin(f); f != b_mesh.faces.end(); ++f) { int4 vi = get_int4(f->vertices_raw()); - int n= (vi[3] == 0)? 3: 4; - int shader = used_shaders[f->material_index()]; + int n = (vi[3] == 0)? 3: 4; + int mi = clamp(f->material_index(), 0, used_shaders.size()-1); + int shader = used_shaders[mi]; bool smooth = f->use_smooth(); mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth); diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 608c5fda5ac..caf5b0a99b1 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -234,13 +234,20 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d) object_free_duplilist(*b_ob); - /* check if we should render duplicator */ hide = true; - BL::Object::particle_systems_iterator b_psys; + } - for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) - if(b_psys->settings().use_render_emitter()) - hide = false; + /* check if we should render or hide particle emitter */ + BL::Object::particle_systems_iterator b_psys; + bool render_emitter = false; + + for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) { + if(b_psys->settings().use_render_emitter()) { + hide = false; + render_emitter = true; + } + else if(!render_emitter) + hide = true; } if(!hide) { diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 3443f76b1ce..286a9b5b24f 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -69,13 +69,13 @@ bool BlenderSync::sync_recalc() BL::BlendData::materials_iterator b_mat; for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) - if(b_mat->is_updated()) + if(b_mat->is_updated() || (b_mat->node_tree() && b_mat->node_tree().is_updated())) shader_map.set_recalc(*b_mat); BL::BlendData::lamps_iterator b_lamp; for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp) - if(b_lamp->is_updated()) + if(b_lamp->is_updated() || (b_lamp->node_tree() && b_lamp->node_tree().is_updated())) shader_map.set_recalc(*b_lamp); BL::BlendData::objects_iterator b_ob; @@ -107,7 +107,8 @@ bool BlenderSync::sync_recalc() BL::BlendData::worlds_iterator b_world; for(b_data.worlds.begin(b_world); b_world != b_data.worlds.end(); ++b_world) - if(world_map == b_world->ptr.data && b_world->is_updated()) + if(world_map == b_world->ptr.data && + (b_world->is_updated() || (b_world->node_tree() && b_world->node_tree().is_updated()))) world_recalc = true; bool recalc = diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index a84ff5825a9..35b617e5452 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -234,6 +234,13 @@ elseif(UNIX) ) endif() + if(WITH_X11_XF86VMODE) + add_definitions(-DWITH_X11_XF86VMODE) + list(APPEND INC_SYS + ${X11_xf86vmode_INCLUDE_PATH} + ) + endif() + if(WITH_INPUT_NDOF) list(APPEND SRC intern/GHOST_NDOFManagerX11.cpp diff --git a/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp b/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp index 1b73329f8bb..4c67616a4c4 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp +++ b/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp @@ -36,7 +36,7 @@ GHOST_DisplayManagerSDL::GHOST_DisplayManagerSDL(GHOST_SystemSDL *system) } GHOST_TSuccess -GHOST_DisplayManagerSDL::getNumDisplays(GHOST_TUns8& numDisplays) +GHOST_DisplayManagerSDL::getNumDisplays(GHOST_TUns8& numDisplays) const { numDisplays= SDL_GetNumVideoDisplays(); return GHOST_kSuccess; @@ -44,7 +44,7 @@ GHOST_DisplayManagerSDL::getNumDisplays(GHOST_TUns8& numDisplays) GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplaySettings(GHOST_TUns8 display, - GHOST_TInt32& numSettings) + GHOST_TInt32& numSettings) const { GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); numSettings= GHOST_TInt32(1); @@ -54,7 +54,7 @@ GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplaySettings(GHOST_TUns8 displa GHOST_TSuccess GHOST_DisplayManagerSDL::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, - GHOST_DisplaySetting& setting) + GHOST_DisplaySetting& setting) const { GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); @@ -74,7 +74,7 @@ GHOST_DisplayManagerSDL::getDisplaySetting(GHOST_TUns8 display, GHOST_TSuccess GHOST_DisplayManagerSDL::getCurrentDisplaySetting(GHOST_TUns8 display, - GHOST_DisplaySetting& setting) + GHOST_DisplaySetting& setting) const { return getDisplaySetting(display,GHOST_TInt32(0),setting); } diff --git a/intern/ghost/intern/GHOST_DisplayManagerSDL.h b/intern/ghost/intern/GHOST_DisplayManagerSDL.h index ff8ab13c4fa..297a61f41ff 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerSDL.h +++ b/intern/ghost/intern/GHOST_DisplayManagerSDL.h @@ -46,20 +46,20 @@ public: GHOST_DisplayManagerSDL(GHOST_SystemSDL *system); GHOST_TSuccess - getNumDisplays(GHOST_TUns8& numDisplays); + getNumDisplays(GHOST_TUns8& numDisplays) const; GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, - GHOST_TInt32& numSettings); + GHOST_TInt32& numSettings) const; GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, - GHOST_DisplaySetting& setting); + GHOST_DisplaySetting& setting) const; GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, - GHOST_DisplaySetting& setting); + GHOST_DisplaySetting& setting) const; GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp index 34f5fda2a16..411203b6475 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp +++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp @@ -20,7 +20,9 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Video mode switching + * Copyright (C) 1997-2001 Id Software, Inc. + * Ported from Quake 2 by Alex Fraser * * ***** END GPL LICENSE BLOCK ***** */ @@ -29,6 +31,10 @@ * \ingroup GHOST */ +#ifdef WITH_X11_XF86VMODE +# include +# include +#endif #include "GHOST_DisplayManagerX11.h" #include "GHOST_SystemX11.h" @@ -112,12 +118,74 @@ setCurrentDisplaySetting( GHOST_TUns8 display, const GHOST_DisplaySetting& setting ){ - // This is never going to work robustly in X - // but it's currently part of the full screen interface +#ifdef WITH_X11_XF86VMODE + // + // Mode switching code ported from Quake 2: + // ftp://ftp.idsoftware.com/idstuff/source/q2source-3.21.zip + // See linux/gl_glx.c:GLimp_SetMode + // + int majorVersion, minorVersion; + XF86VidModeModeInfo **vidmodes; + Display *dpy = m_system->getXDisplay(); + int scrnum, num_vidmodes; + int best_fit, best_dist, dist, x, y; - // we fudge it for now. + scrnum = DefaultScreen(dpy); + // Get video mode list + majorVersion = minorVersion = 0; + if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { + fprintf(stderr, "Error: XF86VidMode extension missing!\n"); + return GHOST_kFailure; + } +# ifdef _DEBUG + printf("Using XFree86-VidModeExtension Version %d.%d\n", + majorVersion, minorVersion); +# endif + + XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes); + + best_dist = 9999999; + best_fit = -1; + + for (int i = 0; i < num_vidmodes; i++) { + if (setting.xPixels > vidmodes[i]->hdisplay || + setting.yPixels > vidmodes[i]->vdisplay) + continue; + + x = setting.xPixels - vidmodes[i]->hdisplay; + y = setting.yPixels - vidmodes[i]->vdisplay; + dist = (x * x) + (y * y); + if (dist < best_dist) { + best_dist = dist; + best_fit = i; + } + } + + if (best_fit != -1) { +# ifdef _DEBUG + int actualWidth, actualHeight; + actualWidth = vidmodes[best_fit]->hdisplay; + actualHeight = vidmodes[best_fit]->vdisplay; + printf("Switching to video mode %dx%d\n", + actualWidth, actualHeight); +# endif + + // change to the mode + XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); + + // Move the viewport to top left + XF86VidModeSetViewPort(dpy, scrnum, 0, 0); + } else + return GHOST_kFailure; + + XFlush(dpy); return GHOST_kSuccess; + +#else + // Just pretend the request was successful. + return GHOST_kSuccess; +#endif } diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py index 01103aede0d..29e8a396088 100644 --- a/release/scripts/startup/bl_operators/anim.py +++ b/release/scripts/startup/bl_operators/anim.py @@ -239,7 +239,7 @@ class ClearUselessActions(Operator): @classmethod def poll(cls, context): - return len(bpy.data.actions) != 0 + return bool(bpy.data.actions) def execute(self, context): removed = 0 diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index fa59cc0ac53..5be9e57356c 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -158,7 +158,7 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel): row = layout.row() row.prop(group, "name") - if ob.mode == 'EDIT' and len(ob.vertex_groups) > 0: + if ob.vertex_groups and (ob.mode == 'EDIT' or (ob.mode == 'WEIGHT_PAINT' and ob.type == 'MESH' and ob.data.use_paint_mask_vertex)): row = layout.row() sub = row.row(align=True) diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py index d738e806320..6fa3aabaeb8 100644 --- a/release/scripts/startup/bl_ui/space_userpref_keymap.py +++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py @@ -219,7 +219,7 @@ class InputKeyMapPanel: filtered_items = [kmi for kmi in km.keymap_items if filter_text in kmi.name.lower()] - if len(filtered_items) != 0: + if filtered_items: col = layout.column() row = col.row() diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 947f612b446..48cab834787 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1051,7 +1051,7 @@ class VIEW3D_MT_vertex_group(Menu): layout.operator("object.vertex_group_assign", text="Assign to New Group").new = True ob = context.active_object - if ob.mode == 'EDIT': + if ob.mode == 'EDIT' or (ob.mode == 'WEIGHT_PAINT' and ob.type == 'MESH' and ob.data.use_paint_mask_vertex): if ob.vertex_groups.active: layout.separator() layout.operator("object.vertex_group_assign", text="Assign to Active Group") diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index f491761f3f2..dbefbd95a15 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -63,7 +63,8 @@ struct BVHTreeRayHit; #define LOOP_PARTICLES for(p=0, pa=psys->particles; ptotpart; p++, pa++) #define LOOP_EXISTING_PARTICLES for(p=0, pa=psys->particles; ptotpart; p++, pa++) if(!(pa->flag & PARS_UNEXIST)) #define LOOP_SHOWN_PARTICLES for(p=0, pa=psys->particles; ptotpart; p++, pa++) if(!(pa->flag & (PARS_UNEXIST|PARS_NO_DISP))) -#define LOOP_DYNAMIC_PARTICLES for(p=0, pa=psys->particles; ptotpart; p++, pa++) if(pa->state.time > 0.f) +/* OpenMP: Can only advance one variable within loop definition. */ +#define LOOP_DYNAMIC_PARTICLES for(p=0; ptotpart; p++ ) if((pa=psys->particles+p)->state.time > 0.f) #define PSYS_FRAND_COUNT 1024 #define PSYS_FRAND(seed) psys->frand[(seed) % PSYS_FRAND_COUNT] diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 45b0fb80944..7e69e67fca7 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -39,6 +39,10 @@ #include #include +#ifdef _OPENMP +#include +#endif + #include "MEM_guardedalloc.h" #include "DNA_anim_types.h" @@ -2302,6 +2306,7 @@ static EdgeHash *sph_springhash_build(ParticleSystem *psys) return springhash; } +#define SPH_NEIGHBORS 512 typedef struct SPHNeighbor { ParticleSystem *psys; @@ -2309,7 +2314,7 @@ typedef struct SPHNeighbor } SPHNeighbor; typedef struct SPHRangeData { - SPHNeighbor neighbors[128]; + SPHNeighbor neighbors[SPH_NEIGHBORS]; int tot_neighbors; float density, near_density; @@ -2320,10 +2325,6 @@ typedef struct SPHRangeData float massfac; int use_size; - - /* Same as SPHData::element_size */ - float element_size; - float flow[3]; } SPHRangeData; typedef struct SPHData { ParticleSystem *psys[10]; @@ -2333,9 +2334,15 @@ typedef struct SPHData { float *gravity; /* Average distance to neighbours (other particles in the support domain), for calculating the Courant number (adaptive time step). */ + int pass; float element_size; float flow[3]; + + /* Integrator callbacks. This allows different SPH implementations. */ + void (*force_cb) (void *sphdata_v, ParticleKey *state, float *force, float *impulse); + void (*density_cb) (void *rangedata_v, int index, float squared_dist); }SPHData; + static void sph_density_accum_cb(void *userdata, int index, float squared_dist) { SPHRangeData *pfr = (SPHRangeData *)userdata; @@ -2346,11 +2353,13 @@ static void sph_density_accum_cb(void *userdata, int index, float squared_dist) if(npa == pfr->pa || squared_dist < FLT_EPSILON) return; - /* Ugh! One particle has over 128 neighbors! Really shouldn't happen, - * but even if it does it shouldn't do any terrible harm if all are - * not taken into account - jahka + /* Ugh! One particle has too many neighbors! If some aren't taken into + * account, the forces will be biased by the tree search order. This + * effectively adds enery to the system, and results in a churning motion. + * But, we have to stop somewhere, and it's not the end of the world. + * - jahka and z0r */ - if(pfr->tot_neighbors >= 128) + if(pfr->tot_neighbors >= SPH_NEIGHBORS) return; pfr->neighbors[pfr->tot_neighbors].index = index; @@ -2360,15 +2369,38 @@ static void sph_density_accum_cb(void *userdata, int index, float squared_dist) dist = sqrtf(squared_dist); q = (1.f - dist/pfr->h) * pfr->massfac; - add_v3_v3(pfr->flow, npa->state.vel); - pfr->element_size += dist; - if(pfr->use_size) q *= npa->size; pfr->density += q*q; pfr->near_density += q*q*q; } +/* + * Find the Courant number for an SPH particle (used for adaptive time step). + */ +static void sph_particle_courant(SPHData *sphdata, SPHRangeData *pfr) { + ParticleData *pa, *npa; + int i; + float flow[3], offset[3], dist; + + flow[0] = flow[1] = flow[2] = 0.0f; + dist = 0.0f; + if (pfr->tot_neighbors > 0) { + pa = pfr->pa; + for (i=0; i < pfr->tot_neighbors; i++) { + npa = pfr->neighbors[i].psys->particles + pfr->neighbors[i].index; + sub_v3_v3v3(offset, pa->prev_state.co, npa->prev_state.co); + dist += len_v3(offset); + add_v3_v3(flow, npa->prev_state.vel); + } + dist += sphdata->psys[0]->part->fluid->radius; // TODO: remove this? - z0r + sphdata->element_size = dist / pfr->tot_neighbors; + mul_v3_v3fl(sphdata->flow, flow, 1.0f / pfr->tot_neighbors); + } else { + sphdata->element_size = MAXFLOAT; + VECCOPY(sphdata->flow, flow); + } +} static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, float *UNUSED(impulse)) { SPHData *sphdata = (SPHData *)sphdata_v; @@ -2409,24 +2441,14 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa pfr.density = pfr.near_density = 0.f; pfr.h = h; pfr.pa = pa; - pfr.element_size = fluid->radius; - pfr.flow[0] = pfr.flow[1] = pfr.flow[2] = 0.0f; for(i=0; i<10 && psys[i]; i++) { pfr.npsys = psys[i]; pfr.massfac = psys[i]->part->mass*inv_mass; pfr.use_size = psys[i]->part->flag & PART_SIZEMASS; - BLI_bvhtree_range_query(psys[i]->bvhtree, state->co, h, sph_density_accum_cb, &pfr); + BLI_bvhtree_range_query(psys[i]->bvhtree, state->co, h, sphdata->density_cb, &pfr); } - if (pfr.tot_neighbors > 0) { - pfr.element_size /= pfr.tot_neighbors; - mul_v3_fl(pfr.flow, 1.0f / pfr.tot_neighbors); - } else { - pfr.element_size = MAXFLOAT; - } - sphdata->element_size = pfr.element_size; - copy_v3_v3(sphdata->flow, pfr.flow); pressure = stiffness * (pfr.density - rest_density); near_pressure = stiffness_near_fac * pfr.near_density; @@ -2465,6 +2487,7 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa if(spring_constant > 0.f) { /* Viscoelastic spring force */ if (pfn->psys == psys[0] && fluid->flag & SPH_VISCOELASTIC_SPRINGS && springhash) { + /* BLI_edgehash_lookup appears to be thread-safe. - z0r */ spring_index = GET_INT_FROM_POINTER(BLI_edgehash_lookup(springhash, index, pfn->index)); if(spring_index) { @@ -2478,7 +2501,9 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa temp_spring.particle_index[1] = pfn->index; temp_spring.rest_length = (fluid->flag & SPH_CURRENT_REST_LENGTH) ? rij : rest_length; temp_spring.delete_flag = 0; - + + /* sph_spring_add is not thread-safe. - z0r */ + #pragma omp critical sph_spring_add(psys[0], &temp_spring); } } @@ -2491,29 +2516,52 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa /* Artificial buoyancy force in negative gravity direction */ if (fluid->buoyancy > 0.f && gravity) madd_v3_v3fl(force, gravity, fluid->buoyancy * (pfr.density-rest_density)); + + if (sphdata->pass == 0 && psys[0]->part->time_flag & PART_TIME_AUTOSF) + sph_particle_courant(sphdata, &pfr); + sphdata->pass++; } -static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float dfra, float *gravity, EdgeHash *springhash, float *element_size, float flow[3]) -{ +static void sph_solver_init(ParticleSimulationData *sim, SPHData *sphdata) { ParticleTarget *pt; int i; + // Add other coupled particle systems. + sphdata->psys[0] = sim->psys; + for(i=1, pt=sim->psys->targets.first; i<10; i++, pt=(pt?pt->next:NULL)) + sphdata->psys[i] = pt ? psys_get_target_system(sim->ob, pt) : NULL; + + if (psys_uses_gravity(sim)) + sphdata->gravity = sim->scene->physics_settings.gravity; + else + sphdata->gravity = NULL; + sphdata->eh = sph_springhash_build(sim->psys); + + // These per-particle values should be overridden later, but just for + // completeness we give them default values now. + sphdata->pa = NULL; + sphdata->mass = 1.0f; + + sphdata->force_cb = sph_force_cb; + sphdata->density_cb = sph_density_accum_cb; +} +static void sph_solver_finalise(SPHData *sphdata) { + if (sphdata->eh) { + BLI_edgehash_free(sphdata->eh, NULL); + sphdata->eh = NULL; + } +} +static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float dfra, SPHData *sphdata){ ParticleSettings *part = sim->psys->part; // float timestep = psys_get_timestep(sim); // UNUSED float pa_mass = part->mass * (part->flag & PART_SIZEMASS ? pa->size : 1.f); float dtime = dfra*psys_get_timestep(sim); // int steps = 1; // UNUSED float effector_acceleration[3]; - SPHData sphdata; - sphdata.psys[0] = sim->psys; - for(i=1, pt=sim->psys->targets.first; i<10; i++, pt=(pt?pt->next:NULL)) - sphdata.psys[i] = pt ? psys_get_target_system(sim->ob, pt) : NULL; - - sphdata.pa = pa; - sphdata.gravity = gravity; - sphdata.mass = pa_mass; - sphdata.eh = springhash; + sphdata->pa = pa; + sphdata->mass = pa_mass; + sphdata->pass = 0; //sphdata.element_size and sphdata.flow are set in the callback. /* restore previous state and treat gravity & effectors as external acceleration*/ @@ -2522,9 +2570,7 @@ static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float d copy_particle_key(&pa->state, &pa->prev_state, 0); - integrate_particle(part, pa, dtime, effector_acceleration, sph_force_cb, &sphdata); - *element_size = sphdata.element_size; - copy_v3_v3(flow, sphdata.flow); + integrate_particle(part, pa, dtime, effector_acceleration, sphdata->force_cb, sphdata); } /************************************************/ @@ -3624,15 +3670,15 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)) step, after the velocity has been updated. element_size defines the scale of the simulation, and is typically the distance to neighbourning particles. */ void update_courant_num(ParticleSimulationData *sim, ParticleData *pa, - float dtime, float element_size, float flow[3]) + float dtime, SPHData *sphdata) { float relative_vel[3]; float speed; - sub_v3_v3v3(relative_vel, pa->state.vel, flow); + sub_v3_v3v3(relative_vel, pa->prev_state.vel, sphdata->flow); speed = len_v3(relative_vel); - if (sim->courant_num < speed * dtime / element_size) - sim->courant_num = speed * dtime / element_size; + if (sim->courant_num < speed * dtime / sphdata->element_size) + sim->courant_num = speed * dtime / sphdata->element_size; } /* Update time step size to suit current conditions. */ float update_timestep(ParticleSystem *psys, ParticleSimulationData *sim, @@ -3718,11 +3764,11 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) case PART_PHYS_FLUID: { ParticleTarget *pt = psys->targets.first; - psys_update_particle_bvhtree(psys, psys->cfra); + psys_update_particle_bvhtree(psys, cfra); for(; pt; pt=pt->next) { /* Updating others systems particle tree for fluid-fluid interaction */ if(pt->ob) - psys_update_particle_bvhtree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), psys->cfra); + psys_update_particle_bvhtree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra); } break; } @@ -3804,37 +3850,32 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) } case PART_PHYS_FLUID: { - EdgeHash *springhash = sph_springhash_build(psys); - float *gravity = NULL; - float element_size, flow[3]; - - if(psys_uses_gravity(sim)) - gravity = sim->scene->physics_settings.gravity; + SPHData sphdata; + sph_solver_init(sim, &sphdata); + #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5) LOOP_DYNAMIC_PARTICLES { /* do global forces & effectors */ basic_integrate(sim, p, pa->state.time, cfra); /* actual fluids calculations */ - sph_integrate(sim, pa, pa->state.time, gravity, springhash, - &element_size, flow); + sph_integrate(sim, pa, pa->state.time, &sphdata); if(sim->colliders) collision_check(sim, p, pa->state.time, cfra); - /* SPH particles are not physical particles, just interpolation particles, thus rotation has not a direct sense for them */ + /* SPH particles are not physical particles, just interpolation + * particles, thus rotation has not a direct sense for them */ basic_rotate(part, pa, pa->state.time, timestep); + #pragma omp critical if (part->time_flag & PART_TIME_AUTOSF) - update_courant_num(sim, pa, dtime, element_size, flow); + update_courant_num(sim, pa, dtime, &sphdata); } sph_springs_modify(psys, timestep); - if(springhash) { - BLI_edgehash_free(springhash, NULL); - springhash = NULL; - } + sph_solver_finalise(&sphdata); break; } } diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index c27631098cf..6369d4e3faf 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -5067,7 +5067,6 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op) { int action = RNA_enum_get(op->ptr, "action"); - Object *ob = NULL; Scene *scene= CTX_data_scene(C); int multipaint = scene->toolsettings->multipaint; @@ -5100,8 +5099,8 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, NULL); - if(multipaint) { - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + if (multipaint) { + Object *ob = ED_object_context(C); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index 064defb1aef..5cdb9c76396 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -77,6 +77,7 @@ #include "ED_keyframing.h" #include "ED_keyframes_edit.h" #include "ED_screen.h" +#include "ED_object.h" #include "armature_intern.h" @@ -171,7 +172,7 @@ static Object *get_poselib_object (bContext *C) sa = CTX_wm_area(C); if (sa && (sa->spacetype == SPACE_BUTS)) - return CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + return ED_object_context(C); else return object_pose_armature_get(CTX_data_active_object(C)); } diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 8d35122650f..832ee55997b 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -73,6 +73,7 @@ #include "ED_keyframing.h" #include "ED_mesh.h" #include "ED_screen.h" +#include "ED_object.h" #include "UI_interface.h" #include "UI_resources.h" @@ -207,7 +208,7 @@ static int pose_calculate_paths_exec (bContext *C, wmOperator *op) /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -283,7 +284,7 @@ static int pose_clear_paths_exec (bContext *C, wmOperator *UNUSED(op)) /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -1221,7 +1222,7 @@ static int pose_group_add_exec (bContext *C, wmOperator *UNUSED(op)) /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -1261,7 +1262,7 @@ static int pose_group_remove_exec (bContext *C, wmOperator *UNUSED(op)) /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -1309,7 +1310,7 @@ static int pose_groups_menu_invoke (bContext *C, wmOperator *op, wmEvent *UNUSED /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -1358,7 +1359,7 @@ static int pose_group_assign_exec (bContext *C, wmOperator *op) /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -1421,7 +1422,7 @@ static int pose_group_unassign_exec (bContext *C, wmOperator *UNUSED(op)) /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -1466,7 +1467,7 @@ void POSE_OT_group_unassign (wmOperatorType *ot) static int group_move_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob = ED_object_context(C); bPose *pose= (ob) ? ob->pose : NULL; bPoseChannel *pchan; bActionGroup *grp; @@ -1564,7 +1565,7 @@ static int compare_agroup(const void *sgrp_a_ptr, const void *sgrp_b_ptr) static int group_sort_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob = ED_object_context(C); bPose *pose= (ob) ? ob->pose : NULL; bPoseChannel *pchan; tSortActionGroup *agrp_array; @@ -1656,7 +1657,7 @@ static int pose_group_select_exec (bContext *C, wmOperator *UNUSED(op)) /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); @@ -1694,7 +1695,7 @@ static int pose_group_deselect_exec (bContext *C, wmOperator *UNUSED(op)) /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); else ob= object_pose_armature_get(CTX_data_active_object(C)); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index e7d753ff45c..a52012283a3 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -56,7 +56,8 @@ struct wmOperator; struct wmOperatorType; /* object_edit.c */ -struct Object *ED_object_active_context(struct bContext *C); +struct Object *ED_object_context(struct bContext *C); /* context.object */ +struct Object *ED_object_active_context(struct bContext *C); /* context.object or context.active_object */ /* object_ops.c */ void ED_operatortypes_object(void); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 900cbbd5cbf..525b15ac7e3 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -114,6 +114,17 @@ typedef enum uiButtonJumpType { BUTTON_EDIT_JUMP_ALL } uiButtonJumpType; +typedef enum uiButtonDelimType { + BUTTON_DELIM_NONE, + BUTTON_DELIM_ALPHA, + BUTTON_DELIM_PUNCT, + BUTTON_DELIM_BRACE, + BUTTON_DELIM_OPERATOR, + BUTTON_DELIM_QUOTE, + BUTTON_DELIM_WHITESPACE, + BUTTON_DELIM_OTHER +} uiButtonDelimType; + typedef struct uiHandleButtonData { wmWindowManager *wm; wmWindow *window; @@ -1230,46 +1241,60 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, /* ************* in-button text selection/editing ************* */ /* return 1 if char ch is special character, otherwise return 0 */ -static short test_special_char(char ch) +static uiButtonDelimType test_special_char(const char ch) { + if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { + return BUTTON_DELIM_ALPHA; + } + switch(ch) { - case '\\': - case '/': - case '~': - case '!': - case '@': - case '#': - case '$': - case '%': - case '^': - case '&': - case '*': - case '(': - case ')': - case '+': - case '=': + case ',': + case '.': + return BUTTON_DELIM_PUNCT; + case '{': case '}': case '[': case ']': - case ':': - case ';': - case '\'': - case '\"': // " - an extra closing one for Aligorith's text editor + case '(': + case ')': + return BUTTON_DELIM_BRACE; + + case '+': + case '-': + case '=': + case '~': + case '%': + case '/': case '<': case '>': - case ',': - case '.': + case '^': + case '*': + case '&': + return BUTTON_DELIM_OPERATOR; + + case '\'': + case '\"': // " - an extra closing one for Aligorith's text editor + return BUTTON_DELIM_QUOTE; + + case ' ': + return BUTTON_DELIM_WHITESPACE; + + case '\\': + case '!': + case '@': + case '#': + case '$': + case ':': + case ';': case '?': case '_': - case '-': - case ' ': - return 1; - break; + return BUTTON_DELIM_OTHER; + default: break; } - return 0; + return BUTTON_DELIM_NONE; } static int ui_textedit_step_next_utf8(const char *str, size_t maxlen, short *pos) @@ -1308,12 +1333,13 @@ static void ui_textedit_step_utf8(const char *str, size_t maxlen, if(direction) { /* right*/ if(jump != BUTTON_EDIT_JUMP_NONE) { + const uiButtonDelimType is_special= (*pos) < maxlen ? test_special_char(str[(*pos)]) : BUTTON_DELIM_NONE; /* jump between special characters (/,\,_,-, etc.), * look at function test_special_char() for complete * list of special character, ctr -> */ while((*pos) < maxlen) { if (ui_textedit_step_next_utf8(str, maxlen, pos)) { - if((jump != BUTTON_EDIT_JUMP_ALL) && test_special_char(str[(*pos)])) break; + if((jump != BUTTON_EDIT_JUMP_ALL) && (is_special != test_special_char(str[(*pos)]))) break; } else { break; /* unlikely but just incase */ @@ -1326,6 +1352,7 @@ static void ui_textedit_step_utf8(const char *str, size_t maxlen, } else { /* left */ if(jump != BUTTON_EDIT_JUMP_NONE) { + const uiButtonDelimType is_special= (*pos) > 1 ? test_special_char(str[(*pos) - 1]) : BUTTON_DELIM_NONE; /* left only: compensate for index/change in direction */ ui_textedit_step_prev_utf8(str, maxlen, pos); @@ -1334,7 +1361,7 @@ static void ui_textedit_step_utf8(const char *str, size_t maxlen, * list of special character, ctr -> */ while ((*pos) > 0) { if (ui_textedit_step_prev_utf8(str, maxlen, pos)) { - if((jump != BUTTON_EDIT_JUMP_ALL) && test_special_char(str[(*pos)])) break; + if((jump != BUTTON_EDIT_JUMP_ALL) && (is_special != test_special_char(str[(*pos)]))) break; } else { break; diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 996ffd1fdb2..48aa69eff46 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -483,14 +483,14 @@ int ED_mesh_color_remove_named(bContext *C, Object *ob, Mesh *me, const char *na static int layers_poll(bContext *C) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); ID *data= (ob)? ob->data: NULL; return (ob && !ob->id.lib && ob->type==OB_MESH && data && !data->lib); } static int uv_texture_add_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Mesh *me= ob->data; if(!ED_mesh_uv_texture_add(C, me, NULL, TRUE)) @@ -599,7 +599,7 @@ void MESH_OT_drop_named_image(wmOperatorType *ot) static int uv_texture_remove_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Mesh *me= ob->data; if(!ED_mesh_uv_texture_remove(C, ob, me)) @@ -628,7 +628,7 @@ void MESH_OT_uv_texture_remove(wmOperatorType *ot) static int vertex_color_add_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Mesh *me= ob->data; if(!ED_mesh_color_add(C, scene, ob, me, NULL, TRUE)) @@ -654,7 +654,7 @@ void MESH_OT_vertex_color_add(wmOperatorType *ot) static int vertex_color_remove_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Mesh *me= ob->data; if(!ED_mesh_color_remove(C, ob, me)) @@ -684,7 +684,7 @@ static int sticky_add_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); View3D *v3d= CTX_wm_view3d(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Mesh *me= ob->data; /*if(me->msticky) @@ -715,7 +715,7 @@ void MESH_OT_sticky_add(wmOperatorType *ot) static int sticky_remove_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Mesh *me= ob->data; if(!me->msticky) diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index e4b27f58e05..b3e5232cfdc 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -112,6 +112,10 @@ static int pupmenu(const char *UNUSED(msg)) {return 0;} static bContext *evil_C; static void error_libdata(void) {} +Object *ED_object_context(bContext *C) +{ + return CTX_data_pointer_get_type(C, "object", &RNA_Object).data; +} /* find the correct active object per context * note: context can be NULL when called from a enum with PROP_ENUM_NO_CONTEXT */ @@ -119,7 +123,7 @@ Object *ED_object_active_context(bContext *C) { Object *ob= NULL; if(C) { - ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + ob= ED_object_context(C); if (!ob) ob= CTX_data_active_object(C); } return ob; diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c index bf0439b7044..74cf174d7b4 100644 --- a/source/blender/editors/object/object_group.c +++ b/source/blender/editors/object/object_group.c @@ -46,6 +46,7 @@ #include "BKE_report.h" #include "ED_screen.h" +#include "ED_object.h" #include "WM_api.h" #include "WM_types.h" @@ -230,7 +231,7 @@ void GROUP_OT_create(wmOperatorType *ot) static int group_add_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Group *group; if(ob == NULL) @@ -261,7 +262,7 @@ void OBJECT_OT_group_add(wmOperatorType *ot) static int group_link_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Group *group= BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group")); if(ELEM(NULL, ob, group)) @@ -299,7 +300,7 @@ void OBJECT_OT_group_link(wmOperatorType *ot) static int group_remove_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Group *group= CTX_data_pointer_get_type(C, "group", &RNA_Group).data; if(!ob || !group) diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index 28f9c88f950..956ec868104 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -61,6 +61,7 @@ #include "BLO_sys_types.h" // for intptr_t support +#include "ED_object.h" #include "ED_mesh.h" #include "RNA_access.h" @@ -269,14 +270,14 @@ static int object_shape_key_mirror(bContext *C, Object *ob) static int shape_key_mode_poll(bContext *C) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); ID *data= (ob)? ob->data: NULL; return (ob && !ob->id.lib && data && !data->lib && ob->mode != OB_MODE_EDIT); } static int shape_key_poll(bContext *C) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); ID *data= (ob)? ob->data: NULL; return (ob && !ob->id.lib && data && !data->lib); } @@ -284,7 +285,7 @@ static int shape_key_poll(bContext *C) static int shape_key_add_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); int from_mix = RNA_boolean_get(op->ptr, "from_mix"); ED_object_shape_key_add(C, scene, ob, from_mix); @@ -312,7 +313,7 @@ void OBJECT_OT_shape_key_add(wmOperatorType *ot) static int shape_key_remove_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); if(!ED_object_shape_key_remove(C, ob)) return OPERATOR_CANCELLED; @@ -337,7 +338,7 @@ void OBJECT_OT_shape_key_remove(wmOperatorType *ot) static int shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Key *key= ob_get_key(ob); KeyBlock *kb= ob_get_keyblock(ob); @@ -370,7 +371,7 @@ void OBJECT_OT_shape_key_clear(wmOperatorType *ot) static int shape_key_mirror_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); if(!object_shape_key_mirror(C, ob)) return OPERATOR_CANCELLED; @@ -395,7 +396,7 @@ void OBJECT_OT_shape_key_mirror(wmOperatorType *ot) static int shape_key_move_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); int type= RNA_enum_get(op->ptr, "type"); Key *key= ob_get_key(ob); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 4eed6195dfe..7a5fe38865b 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -69,6 +69,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "ED_object.h" #include "ED_mesh.h" #include "UI_resources.h" @@ -586,21 +587,44 @@ static void vgroup_select_verts(Object *ob, int select) if(ob->type == OB_MESH) { Mesh *me= ob->data; - BMEditMesh *em = me->edit_btmesh; - BMIter iter; - BMVert *eve; - BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { - if (!BM_TestHFlag(eve, BM_HIDDEN)) { - dv= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); - if (defvert_find_index(dv, def_nr)) { - BM_Select(em->bm, eve, select); + if (me->edit_btmesh) { + BMEditMesh *em = me->edit_btmesh; + BMIter iter; + BMVert *eve; + + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + if (!BM_TestHFlag(eve, BM_HIDDEN)) { + dv= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); + if (defvert_find_index(dv, def_nr)) { + BM_Select(em->bm, eve, select); + } } } + + /* this has to be called, because this function operates on vertices only */ + if(select) EDBM_selectmode_flush(em); // vertices to edges/faces + else EDBM_deselect_flush(em); + } + else { + if (me->dvert) { + MVert *mv; + MDeformVert *dv; + int i; + + mv = me->mvert; + dv = me->dvert; + + for (i=0; itotvert; i++, mv++, dv++) { + if (defvert_find_index(dv, def_nr)) { + if (select) mv->flag |= SELECT; + else mv->flag &= ~SELECT; + } + } + + paintvert_flush_flags(ob); + } } - /* this has to be called, because this function operates on vertices only */ - if(select) EDBM_selectmode_flush(em); // vertices to edges/faces - else EDBM_deselect_flush(em); } else if(ob->type == OB_LATTICE) { Lattice *lt= vgroup_edit_lattice(ob); @@ -1746,21 +1770,45 @@ static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg) /* removes from active defgroup, if allverts==0 only selected vertices */ static void vgroup_active_remove_verts(Object *ob, const int allverts, bDeformGroup *dg) { - BMVert *eve; MDeformVert *dv; const int def_nr= BLI_findindex(&ob->defbase, dg); if(ob->type == OB_MESH) { Mesh *me= ob->data; - BMEditMesh *em = me->edit_btmesh; - BMIter iter; - BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { - dv= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); + if (me->edit_btmesh) { + BMEditMesh *em = me->edit_btmesh; + BMVert *eve; + BMIter iter; - if(dv && dv->dw && (allverts || BM_TestHFlag(eve, BM_SELECT))) { - MDeformWeight *dw = defvert_find_index(dv, def_nr); - defvert_remove_group(dv, dw); /* dw can be NULL */ + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + dv= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); + + if(dv && dv->dw && (allverts || BM_TestHFlag(eve, BM_SELECT))) { + MDeformWeight *dw = defvert_find_index(dv, def_nr); + defvert_remove_group(dv, dw); /* dw can be NULL */ + } + } + } + else { + MVert *mv; + MDeformVert *dv; + int i; + + if (!me->dvert) { + ED_vgroup_data_create(&me->id); + } + + mv = me->mvert; + dv = me->dvert; + + for (i=0; itotvert; i++, mv++, dv++) { + if (mv->flag & SELECT) { + if (dv->dw && (allverts || (mv->flag & SELECT))) { + MDeformWeight *dw = defvert_find_index(dv, def_nr); + defvert_remove_group(dv, dw); /* dw can be NULL */ + } + } } } } @@ -1867,6 +1915,18 @@ static int vgroup_object_in_edit_mode(Object *ob) return 0; } +static int vgroup_object_in_wpaint_vert_select(Object *ob) +{ + if (ob->type == OB_MESH) { + Mesh *me = ob->data; + return ( (ob->mode & OB_MODE_WEIGHT_PAINT) && + (me->edit_btmesh == NULL) && + (ME_EDIT_PAINT_SEL_MODE(me) == SCE_SELECT_VERTEX) ); + } + + return 0; +} + static void vgroup_delete(Object *ob) { bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef-1); @@ -1913,21 +1973,46 @@ static void vgroup_assign_verts(Object *ob, const float weight) if(ob->type == OB_MESH) { Mesh *me= ob->data; - BMEditMesh *em = me->edit_btmesh; - BMIter iter; - BMVert *eve; - if(!CustomData_has_layer(&em->bm->vdata, CD_MDEFORMVERT)) - BM_add_data_layer(em->bm, &em->bm->vdata, CD_MDEFORMVERT); + if (me->edit_btmesh) { + BMEditMesh *em = me->edit_btmesh; + BMIter iter; + BMVert *eve; - /* Go through the list of editverts and assign them */ - BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { - if (BM_TestHFlag(eve, BM_SELECT)) { - MDeformWeight *dw; - dv= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); /* can be NULL */ - dw= defvert_verify_index(dv, def_nr); - if (dw) { - dw->weight= weight; + if(!CustomData_has_layer(&em->bm->vdata, CD_MDEFORMVERT)) + BM_add_data_layer(em->bm, &em->bm->vdata, CD_MDEFORMVERT); + + /* Go through the list of editverts and assign them */ + BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { + if (BM_TestHFlag(eve, BM_SELECT)) { + MDeformWeight *dw; + dv= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); /* can be NULL */ + dw= defvert_verify_index(dv, def_nr); + if (dw) { + dw->weight= weight; + } + } + } + } + else { + MVert *mv; + MDeformVert *dv; + int i; + + if (!me->dvert) { + ED_vgroup_data_create(&me->id); + } + + mv = me->mvert; + dv = me->dvert; + + for (i=0; itotvert; i++, mv++, dv++) { + if (mv->flag & SELECT) { + MDeformWeight *dw; + dw= defvert_verify_index(dv, def_nr); + if (dw) { + dw->weight= weight; + } } } } @@ -1974,14 +2059,14 @@ static void vgroup_remove_verts(Object *ob, int allverts) static int vertex_group_poll(bContext *C) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); ID *data= (ob)? ob->data: NULL; return (ob && !ob->id.lib && OB_TYPE_SUPPORT_VGROUP(ob->type) && data && !data->lib); } static int vertex_group_poll_edit(bContext *C) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); ID *data= (ob)? ob->data: NULL; if(!(ob && !ob->id.lib && data && !data->lib)) @@ -1990,9 +2075,22 @@ static int vertex_group_poll_edit(bContext *C) return vgroup_object_in_edit_mode(ob); } +/* editmode _or_ weight paint vertex sel */ +static int vertex_group_poll_edit_or_wpaint_vert_select(bContext *C) +{ + Object *ob= ED_object_context(C); + ID *data= (ob)? ob->data: NULL; + + if(!(ob && !ob->id.lib && data && !data->lib)) + return 0; + + return ( vgroup_object_in_edit_mode(ob) || + vgroup_object_in_wpaint_vert_select(ob) ); +} + static int vertex_group_add_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); ED_vgroup_add(ob); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -2018,7 +2116,7 @@ void OBJECT_OT_vertex_group_add(wmOperatorType *ot) static int vertex_group_remove_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); if(RNA_boolean_get(op->ptr, "all")) vgroup_delete_all(ob); @@ -2055,7 +2153,7 @@ void OBJECT_OT_vertex_group_remove(wmOperatorType *ot) static int vertex_group_assign_exec(bContext *C, wmOperator *op) { ToolSettings *ts= CTX_data_tool_settings(C); - Object *ob= CTX_data_edit_object(C); + Object *ob= ED_object_context(C); if(RNA_boolean_get(op->ptr, "new")) ED_vgroup_add(ob); @@ -2074,7 +2172,7 @@ void OBJECT_OT_vertex_group_assign(wmOperatorType *ot) ot->idname= "OBJECT_OT_vertex_group_assign"; /* api callbacks */ - ot->poll= vertex_group_poll_edit; + ot->poll= vertex_group_poll_edit_or_wpaint_vert_select; ot->exec= vertex_group_assign_exec; /* flags */ @@ -2089,7 +2187,7 @@ void OBJECT_OT_vertex_group_assign(wmOperatorType *ot) static int vertex_group_remove_from_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_edit_object(C); + Object *ob= ED_object_context(C); if(RNA_boolean_get(op->ptr, "all")) vgroup_remove_verts(ob, 0); @@ -2116,7 +2214,7 @@ void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot) ot->idname= "OBJECT_OT_vertex_group_remove_from"; /* api callbacks */ - ot->poll= vertex_group_poll_edit; + ot->poll= vertex_group_poll_edit_or_wpaint_vert_select; ot->exec= vertex_group_remove_from_exec; /* flags */ @@ -2131,7 +2229,7 @@ void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot) static int vertex_group_select_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_edit_object(C); + Object *ob= ED_object_context(C); if(!ob || ob->id.lib) return OPERATOR_CANCELLED; @@ -2149,7 +2247,7 @@ void OBJECT_OT_vertex_group_select(wmOperatorType *ot) ot->idname= "OBJECT_OT_vertex_group_select"; /* api callbacks */ - ot->poll= vertex_group_poll_edit; + ot->poll= vertex_group_poll_edit_or_wpaint_vert_select; ot->exec= vertex_group_select_exec; /* flags */ @@ -2158,7 +2256,7 @@ void OBJECT_OT_vertex_group_select(wmOperatorType *ot) static int vertex_group_deselect_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_edit_object(C); + Object *ob= ED_object_context(C); vgroup_select_verts(ob, 0); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data); @@ -2173,7 +2271,7 @@ void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot) ot->idname= "OBJECT_OT_vertex_group_deselect"; /* api callbacks */ - ot->poll= vertex_group_poll_edit; + ot->poll= vertex_group_poll_edit_or_wpaint_vert_select; ot->exec= vertex_group_deselect_exec; /* flags */ @@ -2182,7 +2280,7 @@ void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot) static int vertex_group_copy_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); vgroup_duplicate(ob); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -2208,7 +2306,7 @@ void OBJECT_OT_vertex_group_copy(wmOperatorType *ot) static int vertex_group_levels_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); float offset= RNA_float_get(op->ptr,"offset"); float gain= RNA_float_get(op->ptr,"gain"); @@ -2241,7 +2339,7 @@ void OBJECT_OT_vertex_group_levels(wmOperatorType *ot) static int vertex_group_normalize_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); vgroup_normalize(ob); @@ -2268,7 +2366,7 @@ void OBJECT_OT_vertex_group_normalize(wmOperatorType *ot) static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); int lock_active= RNA_boolean_get(op->ptr,"lock_active"); vgroup_normalize_all(ob, lock_active); @@ -2378,7 +2476,7 @@ void OBJECT_OT_vertex_group_lock(wmOperatorType *ot) static int vertex_group_invert_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); int auto_assign= RNA_boolean_get(op->ptr,"auto_assign"); int auto_remove= RNA_boolean_get(op->ptr,"auto_remove"); @@ -2412,7 +2510,7 @@ void OBJECT_OT_vertex_group_invert(wmOperatorType *ot) static int vertex_group_blend_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); vgroup_blend(ob); @@ -2441,7 +2539,7 @@ void OBJECT_OT_vertex_group_blend(wmOperatorType *ot) static int vertex_group_clean_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); float limit= RNA_float_get(op->ptr,"limit"); int all_groups= RNA_boolean_get(op->ptr,"all_groups"); @@ -2480,7 +2578,7 @@ void OBJECT_OT_vertex_group_clean(wmOperatorType *ot) static int vertex_group_mirror_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); ED_vgroup_mirror(ob, RNA_boolean_get(op->ptr,"mirror_weights"), @@ -2519,7 +2617,7 @@ void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot) static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Base *base; int retval= OPERATOR_CANCELLED; @@ -2559,7 +2657,7 @@ void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot) static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) { - Object *obact= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *obact= ED_object_context(C); int change= 0; int fail= 0; @@ -2602,7 +2700,7 @@ static EnumPropertyItem vgroup_items[]= { static int set_active_group_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); int nr= RNA_enum_get(op->ptr, "group"); BLI_assert(nr+1 >= 0); @@ -2616,7 +2714,7 @@ static int set_active_group_exec(bContext *C, wmOperator *op) static EnumPropertyItem *vgroup_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); EnumPropertyItem tmp = {0, "", 0, "", ""}; EnumPropertyItem *item= NULL; bDeformGroup *def; @@ -2758,7 +2856,7 @@ static int vgroup_sort(void *def_a_ptr, void *def_b_ptr) static int vertex_group_sort_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); char *name_array; int ret; @@ -2797,7 +2895,7 @@ void OBJECT_OT_vertex_group_sort(wmOperatorType *ot) static int vgroup_move_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); bDeformGroup *def; char *name_array; int dir= RNA_enum_get(op->ptr, "direction"), ret; diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c index 6e25307b786..cdcaae91070 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.c +++ b/source/blender/editors/physics/dynamicpaint_ops.c @@ -42,6 +42,7 @@ #include "ED_mesh.h" #include "ED_screen.h" +#include "ED_object.h" #include "RNA_access.h" #include "RNA_define.h" @@ -58,7 +59,7 @@ static int surface_slot_add_exec(bContext *C, wmOperator *UNUSED(op)) { DynamicPaintModifierData *pmd = NULL; - Object *cObject = CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *cObject = ED_object_context(C); DynamicPaintCanvasSettings *canvas; DynamicPaintSurface *surface; @@ -100,7 +101,7 @@ void DPAINT_OT_surface_slot_add(wmOperatorType *ot) static int surface_slot_remove_exec(bContext *C, wmOperator *UNUSED(op)) { DynamicPaintModifierData *pmd = NULL; - Object *cObject = CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *cObject = ED_object_context(C); DynamicPaintCanvasSettings *canvas; DynamicPaintSurface *surface; int id=0; @@ -148,7 +149,7 @@ void DPAINT_OT_surface_slot_remove(wmOperatorType *ot) static int type_toggle_exec(bContext *C, wmOperator *op) { - Object *cObject = CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *cObject = ED_object_context(C); Scene *scene = CTX_data_scene(C); DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(cObject, eModifierType_DynamicPaint); int type= RNA_enum_get(op->ptr, "type"); @@ -199,7 +200,7 @@ void DPAINT_OT_type_toggle(wmOperatorType *ot) static int output_toggle_exec(bContext *C, wmOperator *op) { - Object *ob = CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob = ED_object_context(C); Scene *scene = CTX_data_scene(C); DynamicPaintSurface *surface; DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint); @@ -344,7 +345,7 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) { DynamicPaintModifierData *pmd = NULL; DynamicPaintCanvasSettings *canvas; - Object *ob = CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob = ED_object_context(C); int status = 0; double timer = PIL_check_seconds_timer(); char result_str[80]; diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index dd46910fbc1..bc3cfa2ca92 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -59,6 +59,7 @@ #include "ED_particle.h" #include "ED_screen.h" +#include "ED_object.h" #include "physics_intern.h" @@ -66,7 +67,7 @@ static int particle_system_add_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Scene *scene = CTX_data_scene(C); if(!scene || !ob) @@ -97,7 +98,7 @@ void OBJECT_OT_particle_system_add(wmOperatorType *ot) static int particle_system_remove_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Scene *scene = CTX_data_scene(C); int mode_orig = ob->mode; if(!scene || !ob) @@ -581,7 +582,7 @@ static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys) static int disconnect_hair_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= NULL; int all = RNA_boolean_get(op->ptr, "all"); @@ -719,7 +720,7 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys) static int connect_hair_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= NULL; int all = RNA_boolean_get(op->ptr, "all"); diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index ba73bbdf31e..a9025b8cdfc 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -74,6 +74,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "ED_object.h" #include "ED_curve.h" #include "ED_mesh.h" #include "ED_node.h" @@ -92,7 +93,7 @@ static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); if(!ob) return OPERATOR_CANCELLED; @@ -121,7 +122,7 @@ void OBJECT_OT_material_slot_add(wmOperatorType *ot) static int material_slot_remove_exec(bContext *C, wmOperator *op) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); if(!ob) return OPERATOR_CANCELLED; @@ -157,7 +158,7 @@ void OBJECT_OT_material_slot_remove(wmOperatorType *ot) static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); if(!ob) return OPERATOR_CANCELLED; @@ -219,7 +220,7 @@ void OBJECT_OT_material_slot_assign(wmOperatorType *ot) static int material_slot_de_select(bContext *C, int select) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); if(!ob) return OPERATOR_CANCELLED; @@ -322,7 +323,7 @@ void OBJECT_OT_material_slot_deselect(wmOperatorType *ot) static int material_slot_copy_exec(bContext *C, wmOperator *UNUSED(op)) { - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Object *ob= ED_object_context(C); Material ***matar; if(!ob || !(matar= give_matarar(ob))) diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index 9e551f637de..a72c79a1e62 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -167,7 +167,7 @@ void GPU_update_mesh_buffers(GPU_Buffers *buffers, struct MVert *mvert, int *vert_indices, int totvert); GPU_Buffers *GPU_build_grid_buffers(struct DMGridData **grids, int *grid_indices, int totgrid, int gridsize); -void GPU_update_grid_buffers(GPU_Buffers *buffers_v, struct DMGridData **grids, +void GPU_update_grid_buffers(GPU_Buffers *buffers, struct DMGridData **grids, int *grid_indices, int totgrid, int gridsize, int smooth); void GPU_draw_buffers(GPU_Buffers *buffers); void GPU_free_buffers(GPU_Buffers *buffers); diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 0cbe5d72bfd..b128a6e46e7 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -1296,10 +1296,9 @@ struct GPU_Buffers { unsigned int tot_tri, tot_quad; }; -void GPU_update_mesh_buffers(GPU_Buffers *buffers_v, MVert *mvert, +void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert, int *vert_indices, int totvert) { - GPU_Buffers *buffers = buffers_v; VertexBufferFormat *vert_data; int i; @@ -1413,10 +1412,9 @@ GPU_Buffers *GPU_build_mesh_buffers(GHash *map, MVert *mvert, MFace *mface, return buffers; } -void GPU_update_grid_buffers(GPU_Buffers *buffers_v, DMGridData **grids, +void GPU_update_grid_buffers(GPU_Buffers *buffers, DMGridData **grids, int *grid_indices, int totgrid, int gridsize, int smooth) { - GPU_Buffers *buffers = buffers_v; DMGridData *vert_data; int i, j, k, totvert; @@ -1465,7 +1463,7 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers_v, DMGridData **grids, buffers->totgrid = totgrid; buffers->gridsize = gridsize; - //printf("node updated %p\n", buffers_v); + //printf("node updated %p\n", buffers); } GPU_Buffers *GPU_build_grid_buffers(DMGridData **UNUSED(grids), int *UNUSED(grid_indices), @@ -1558,10 +1556,8 @@ GPU_Buffers *GPU_build_grid_buffers(DMGridData **UNUSED(grids), int *UNUSED(grid return buffers; } -void GPU_draw_buffers(GPU_Buffers *buffers_v) +void GPU_draw_buffers(GPU_Buffers *buffers) { - GPU_Buffers *buffers = buffers_v; - if(buffers->vert_buf && buffers->index_buf) { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); @@ -1632,11 +1628,9 @@ void GPU_draw_buffers(GPU_Buffers *buffers_v) } } -void GPU_free_buffers(GPU_Buffers *buffers_v) +void GPU_free_buffers(GPU_Buffers *buffers) { - if(buffers_v) { - GPU_Buffers *buffers = buffers_v; - + if(buffers) { if(buffers->vert_buf) glDeleteBuffersARB(1, &buffers->vert_buf); if(buffers->index_buf) @@ -1645,4 +1639,3 @@ void GPU_free_buffers(GPU_Buffers *buffers_v) MEM_freeN(buffers); } } - diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index dc7400dd9ae..8258ef5b753 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -2649,6 +2649,7 @@ static void rna_generate_header(BlenderRNA *brna, FILE *f) static const char *cpp_classes = "" "\n" "#include \n" +"#include /* for memcpy */\n" "\n" "namespace BL {\n" "\n" @@ -2774,6 +2775,7 @@ static void rna_generate_header_cpp(BlenderRNA *brna, FILE *f) fprintf(f, "#include \"RNA_blender.h\"\n"); fprintf(f, "#include \"RNA_types.h\"\n"); + fprintf(f, "#include \"RNA_access.h\"\n"); fprintf(f, "%s", cpp_classes); diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index 0e52d43b525..f10d8c48c92 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -2409,13 +2409,13 @@ static int MatrixAccess_traverse(MatrixAccessObject *self, visitproc visit, void return 0; } -int MatrixAccess_clear(MatrixAccessObject *self) +static int MatrixAccess_clear(MatrixAccessObject *self) { Py_CLEAR(self->matrix_user); return 0; } -void MatrixAccess_dealloc(MatrixAccessObject *self) +static void MatrixAccess_dealloc(MatrixAccessObject *self) { if (self->matrix_user) { PyObject_GC_UnTrack(self); @@ -2434,6 +2434,38 @@ static int MatrixAccess_len(MatrixAccessObject *self) self->matrix_user->num_col; } +static PyObject *MatrixAccess_slice(MatrixAccessObject *self, int begin, int end) +{ + PyObject *tuple; + int count; + + /* row/col access */ + MatrixObject *matrix_user = self->matrix_user; + int matrix_access_len; + PyObject *(*Matrix_item_new)(MatrixObject *, int); + + if (self->type == MAT_ACCESS_ROW) { + matrix_access_len = matrix_user->num_row; + Matrix_item_new = Matrix_item_row; + } + else { /* MAT_ACCESS_ROW */ + matrix_access_len = matrix_user->num_col; + Matrix_item_new = Matrix_item_col; + } + + CLAMP(begin, 0, matrix_access_len); + if (end < 0) end = (matrix_access_len + 1) + end; + CLAMP(end, 0, matrix_access_len); + begin = MIN2(begin, end); + + tuple = PyTuple_New(end - begin); + for (count = begin; count < end; count++) { + PyTuple_SET_ITEM(tuple, count - begin, Matrix_item_new(matrix_user, count)); + } + + return tuple; +} + static PyObject *MatrixAccess_subscript(MatrixAccessObject *self, PyObject *item) { MatrixObject *matrix_user = self->matrix_user; @@ -2454,7 +2486,24 @@ static PyObject *MatrixAccess_subscript(MatrixAccessObject *self, PyObject *item return Matrix_item_col(matrix_user, i); } } - /* TODO, slice */ + else if (PySlice_Check(item)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((void *)item, MatrixAccess_len(self), &start, &stop, &step, &slicelength) < 0) + return NULL; + + if (slicelength <= 0) { + return PyTuple_New(0); + } + else if (step == 1) { + return MatrixAccess_slice(self, start, stop); + } + else { + PyErr_SetString(PyExc_IndexError, + "slice steps not supported with matrix accessors"); + return NULL; + } + } else { PyErr_Format(PyExc_TypeError, "matrix indices must be integers, not %.200s", @@ -2493,6 +2542,22 @@ static int MatrixAccess_ass_subscript(MatrixAccessObject *self, PyObject *item, } } +static PyObject *MatrixAccess_iter(MatrixAccessObject *self) +{ + /* Try get values from a collection */ + PyObject *ret; + PyObject *iter = NULL; + ret = MatrixAccess_slice(self, 0, MATRIX_MAX_DIM); + + /* we know this is a tuple so no need to PyIter_Check + * otherwise it could be NULL (unlikely) if conversion failed */ + if (ret) { + iter = PyObject_GetIter(ret); + Py_DECREF(ret); + } + + return iter; +} static PyMappingMethods MatrixAccess_AsMapping = { (lenfunc)MatrixAccess_len, @@ -2525,6 +2590,8 @@ PyTypeObject matrix_access_Type = { (traverseproc)MatrixAccess_traverse, //tp_traverse (inquiry)MatrixAccess_clear, //tp_clear NULL /* (richcmpfunc)MatrixAccess_richcmpr */ /* TODO*/, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + (getiterfunc)MatrixAccess_iter, /* getiterfunc tp_iter; */ }; static PyObject *MatrixAccess_CreatePyObject(MatrixObject *matrix, const eMatrixAccess_t type) diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index dc2de5fb450..78215498a47 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -170,6 +170,11 @@ RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, result= new_render_result(re, &disprect, 0, RR_USEMEM); BLI_addtail(&engine->fullresult, result); + + result->tilerect.xmin += re->disprect.xmin; + result->tilerect.xmax += re->disprect.xmin; + result->tilerect.ymin += re->disprect.ymin; + result->tilerect.ymax += re->disprect.ymin; return result; } @@ -190,11 +195,6 @@ 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/gameengine/GameLogic/CMakeLists.txt b/source/gameengine/GameLogic/CMakeLists.txt index 64c2af9031b..98255bb8b97 100644 --- a/source/gameengine/GameLogic/CMakeLists.txt +++ b/source/gameengine/GameLogic/CMakeLists.txt @@ -132,6 +132,10 @@ if(WITH_SDL) ) add_definitions(-DWITH_SDL) + + if(WITH_GHOST_SDL) + add_definitions(-DWITH_GHOST_SDL) + endif() endif() blender_add_lib(ge_logic "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp index 0547d97285d..15aeef242b7 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp +++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp @@ -88,8 +88,14 @@ SCA_Joystick *SCA_Joystick::GetInstance( short int joyindex ) if (m_refCount == 0) { int i; - // do this once only + // The video subsystem is required for joystick input to work. However, + // when GHOST is running under SDL, video is initialised elsewhere. + // Do this once only. +# ifdef WITH_GHOST_SDL + if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1 ){ +# else if(SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO) == -1 ){ +# endif echo("Error-Initializing-SDL: " << SDL_GetError()); return NULL; } @@ -124,7 +130,14 @@ void SCA_Joystick::ReleaseInstance() m_instance[i]= NULL; } + // The video subsystem is required for joystick input to work. However, + // when GHOST is running under SDL, video is freed elsewhere. + // Do this once only. +# ifdef WITH_GHOST_SDL + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); +# else SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO); +# endif #endif /* WITH_SDL */ } }