diff options
Diffstat (limited to 'source/blender')
89 files changed, 2395 insertions, 2183 deletions
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 9b26e7a54be..a387b416c38 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -479,7 +479,7 @@ void BLF_rotation_default(float angle) } } -static void blf_draw__start(FontBLF *font) +static void blf_draw__start(FontBLF *font, GLint *mode, GLint *param) { /* * The pixmap alignment hack is handle @@ -490,6 +490,14 @@ static void blf_draw__start(FontBLF *font) glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + /* Save the current matrix mode. */ + glGetIntegerv(GL_MATRIX_MODE, mode); + + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glLoadIdentity(); + + glMatrixMode(GL_MODELVIEW); glPushMatrix(); if (font->flags & BLF_MATRIX) @@ -509,11 +517,27 @@ static void blf_draw__start(FontBLF *font) /* always bind the texture for the first glyph */ font->tex_bind_state= -1; + /* Save the current parameter to restore it later. */ + glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, param); + if (*param != GL_MODULATE) + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } -static void blf_draw__end(void) +static void blf_draw__end(GLint mode, GLint param) { + /* and restore the original value. */ + if (param != GL_MODULATE) + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, param); + + glMatrixMode(GL_TEXTURE); glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + if (mode != GL_MODELVIEW) + glMatrixMode(mode); + glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); } @@ -521,22 +545,24 @@ static void blf_draw__end(void) void BLF_draw(int fontid, const char *str, size_t len) { FontBLF *font= BLF_get(fontid); + GLint mode, param; if (font && font->glyph_cache) { - blf_draw__start(font); + blf_draw__start(font, &mode, ¶m); blf_font_draw(font, str, len); - blf_draw__end(); + blf_draw__end(mode, param); } } void BLF_draw_ascii(int fontid, const char *str, size_t len) { FontBLF *font= BLF_get(fontid); + GLint mode, param; if (font && font->glyph_cache) { - blf_draw__start(font); + blf_draw__start(font, &mode, ¶m); blf_font_draw_ascii(font, str, len); - blf_draw__end(); + blf_draw__end(mode, param); } } diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index cb4fba43f8d..49cde9d6517 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 261 -#define BLENDER_SUBVERSION 0 +#define BLENDER_SUBVERSION 1 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 6234308048b..9fdae5b190e 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -374,6 +374,8 @@ int nodeUpdateID(struct bNodeTree *ntree, struct ID *id); void nodeFreePreview(struct bNode *node); +int nodeSocketIsHidden(struct bNodeSocket *sock); + /* ************** NODE TYPE ACCESS *************** */ struct bNodeTemplate nodeMakeTemplate(struct bNode *node); 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; p<psys->totpart; p++, pa++) #define LOOP_EXISTING_PARTICLES for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++) if(!(pa->flag & PARS_UNEXIST)) #define LOOP_SHOWN_PARTICLES for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++) if(!(pa->flag & (PARS_UNEXIST|PARS_NO_DISP))) -#define LOOP_DYNAMIC_PARTICLES for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++) if(pa->state.time > 0.f) +/* OpenMP: Can only advance one variable within loop definition. */ +#define LOOP_DYNAMIC_PARTICLES for(p=0; p<psys->totpart; 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/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h index 57746f3a68f..fdf1d09559d 100644 --- a/source/blender/blenkernel/BKE_sound.h +++ b/source/blender/blenkernel/BKE_sound.h @@ -94,14 +94,17 @@ void sound_update_fps(struct Scene *scene); void sound_update_scene_listener(struct Scene *scene); void* sound_scene_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip); +void* sound_scene_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence); void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip); +void* sound_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence); void sound_remove_scene_sound(struct Scene *scene, void* handle); void sound_mute_scene_sound(void* handle, char mute); void sound_move_scene_sound(struct Scene *scene, void* handle, int startframe, int endframe, int frameskip); +void sound_move_scene_sound_defaults(struct Scene *scene, struct Sequence *sequence); void sound_update_scene_sound(void* handle, struct bSound* sound); diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c index 1100c1c0ef5..1aad0a242f9 100644 --- a/source/blender/blenkernel/intern/bvhutils.c +++ b/source/blender/blenkernel/intern/bvhutils.c @@ -52,7 +52,7 @@ float bvhtree_ray_tri_intersection(const BVHTreeRay *ray, const float UNUSED(m_d { float dist; - if(isect_ray_tri_v3(ray->origin, ray->direction, v0, v1, v2, &dist, NULL)) + if(isect_ray_tri_epsilon_v3(ray->origin, ray->direction, v0, v1, v2, &dist, NULL, FLT_EPSILON)) return dist; return FLT_MAX; diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 878db6b3ed1..77a4a6a429c 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -41,6 +41,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_editVert.h" +#include "BLI_kdopbvh.h" #include "BLI_utildefines.h" #include "DNA_armature_types.h" @@ -64,6 +65,7 @@ #include "BKE_anim.h" /* for the curve calculation part */ #include "BKE_armature.h" #include "BKE_blender.h" +#include "BKE_bvhutils.h" #include "BKE_camera.h" #include "BKE_constraint.h" #include "BKE_displist.h" @@ -3950,6 +3952,7 @@ static void followtrack_id_looper (bConstraint *con, ConstraintIDFunc func, void func(con, (ID**)&data->clip, userdata); func(con, (ID**)&data->camera, userdata); + func(con, (ID**)&data->depth_ob, userdata); } static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets)) @@ -3985,7 +3988,6 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase if (data->flag & FOLLOWTRACK_USE_3D_POSITION) { if (track->flag & TRACK_HAS_BUNDLE) { - MovieTracking *tracking= &clip->tracking; float obmat[4][4], mat[4][4]; copy_m4_m4(obmat, cob->matrix); @@ -4008,9 +4010,8 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]); } } - } + } else { - MovieClipUser user; MovieTrackingMarker *marker; float vec[3], disp[3], axis[3], mat[4][4]; float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp); @@ -4035,8 +4036,7 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase CameraParams params; float pos[2], rmat[4][4]; - user.framenr= scene->r.cfra; - marker= BKE_tracking_get_marker(track, user.framenr); + marker= BKE_tracking_get_marker(track, scene->r.cfra); add_v2_v2v2(pos, marker->pos, track->offset); @@ -4078,6 +4078,34 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase copy_v3_v3(cob->matrix[3], disp); } + + if(data->depth_ob && data->depth_ob->derivedFinal) { + Object *depth_ob= data->depth_ob; + BVHTreeFromMesh treeData= NULL_BVHTreeFromMesh; + BVHTreeRayHit hit; + float ray_start[3], ray_end[3], ray_nor[3], imat[4][4]; + int result; + + invert_m4_m4(imat, depth_ob->obmat); + + mul_v3_m4v3(ray_start, imat, camob->obmat[3]); + mul_v3_m4v3(ray_end, imat, cob->matrix[3]); + + sub_v3_v3v3(ray_nor, ray_end, ray_start); + + bvhtree_from_mesh_faces(&treeData, depth_ob->derivedFinal, 0.0f, 4, 6); + + hit.dist= FLT_MAX; + hit.index= -1; + + result= BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_nor, 0.0f, &hit, treeData.raycast_callback, &treeData); + + if(result != -1) { + mul_v3_m4v3(cob->matrix[3], depth_ob->obmat, hit.co); + } + + free_bvhtree_from_mesh(&treeData); + } } } } diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 3cb2f8ce738..762aaf3efc1 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -657,6 +657,11 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O if((data->clip || data->flag&FOLLOWTRACK_ACTIVECLIP) && data->track[0]) depends_on_camera= 1; + + if(data->depth_ob) { + node2 = dag_get_node(dag, data->depth_ob); + dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB, cti->name); + } } else if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) depends_on_camera= 1; diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 408a141608d..ef2249409f0 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1248,8 +1248,6 @@ void mesh_set_smooth_flag(Object *meshOb, int enableSmooth) mf->flag &= ~ME_SMOOTH; } } - - mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); } void mesh_calc_normals(MVert *mverts, int numVerts, MFace *mfaces, int numFaces, float (*faceNors_r)[3]) diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index ab963f1e78c..4c78ab13874 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -860,7 +860,9 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip undist_marker.pos[1]/= height*aspy; } - tmpibuf= BKE_tracking_get_pattern_imbuf(ibuf, track, &undist_marker, 1, 1, scopes->track_pos, NULL); + /* NOTE: margin should be kept in sync with value from ui_draw_but_TRACKPREVIEW */ + tmpibuf= BKE_tracking_get_pattern_imbuf(ibuf, track, &undist_marker, 2 /* margin */, + 1 /* anchor */, scopes->track_pos, NULL); if(tmpibuf->rect_float) IMB_rect_from_float(tmpibuf); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index ce1dd429794..5253d7a9961 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1325,6 +1325,11 @@ void nodeSetActive(bNodeTree *ntree, bNode *node) node->flag |= NODE_ACTIVE_TEXTURE; } +int nodeSocketIsHidden(bNodeSocket *sock) +{ + return ((sock->flag & (SOCK_HIDDEN | SOCK_AUTO_HIDDEN | SOCK_UNAVAIL)) != 0); +} + /* ************** dependency stuff *********** */ /* node is guaranteed to be not checked before */ diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index ac612e3e996..fab59a7b88a 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -432,7 +432,8 @@ void unlink_object(Object *ob) if(pchan->custom==ob) pchan->custom= NULL; } - } else if(ELEM(OB_MBALL, ob->type, obt->type)) { + } + else if(ELEM(OB_MBALL, ob->type, obt->type)) { if(is_mball_basis_for(obt, ob)) obt->recalc|= OB_RECALC_DATA; } @@ -618,21 +619,6 @@ void unlink_object(Object *ob) sce= sce->id.next; } -#if 0 // XXX old animation system - /* ipos */ - ipo= bmain->ipo.first; - while(ipo) { - if(ipo->id.lib==NULL) { - IpoCurve *icu; - for(icu= ipo->curve.first; icu; icu= icu->next) { - if(icu->driver && icu->driver->ob==ob) - icu->driver->ob= NULL; - } - } - ipo= ipo->id.next; - } -#endif // XXX old animation system - /* screens */ sc= bmain->screen.first; while(sc) { @@ -1000,7 +986,7 @@ void copy_object_particlesystems(Object *obn, Object *ob) } else if (md->type==eModifierType_Smoke) { SmokeModifierData *smd = (SmokeModifierData*) md; - + if(smd->type==MOD_SMOKE_TYPE_FLOW) { if (smd->flow) { if (smd->flow->psys == psys) @@ -1036,22 +1022,6 @@ static void copy_object_pose(Object *obn, Object *ob) ListBase targets = {NULL, NULL}; bConstraintTarget *ct; -#if 0 // XXX old animation system - /* note that we can't change lib linked ipo blocks. for making - * proxies this still works correct however because the object - * is changed to object->proxy_from when evaluating the driver. */ - if(con->ipo && !con->ipo->id.lib) { - IpoCurve *icu; - - con->ipo= copy_ipo(con->ipo); - - for(icu= con->ipo->curve.first; icu; icu= icu->next) { - if(icu->driver && icu->driver->ob==ob) - icu->driver->ob= obn; - } - } -#endif // XXX old animation system - if (cti && cti->get_constraint_targets) { cti->get_constraint_targets(con, &targets); @@ -1081,8 +1051,7 @@ static int object_pose_context(Object *ob) } } -//Object *object_pose_armature_get(Object *ob) -Object *object_pose_armature_get(struct Object *ob) +Object *object_pose_armature_get(Object *ob) { if(ob==NULL) return NULL; @@ -1188,13 +1157,8 @@ Object *copy_object(Object *ob) static void extern_local_object(Object *ob) { - //bActionStrip *strip; ParticleSystem *psys; -#if 0 // XXX old animation system - id_lib_extern((ID *)ob->action); - id_lib_extern((ID *)ob->ipo); -#endif // XXX old animation system id_lib_extern((ID *)ob->data); id_lib_extern((ID *)ob->dup_group); id_lib_extern((ID *)ob->poselib); @@ -1202,11 +1166,6 @@ static void extern_local_object(Object *ob) extern_local_matarar(ob->mat, ob->totcol); -#if 0 // XXX old animation system - for (strip=ob->nlastrips.first; strip; strip=strip->next) { - id_lib_extern((ID *)strip->act); - } -#endif // XXX old animation system for(psys=ob->particlesystem.first; psys; psys=psys->next) id_lib_extern((ID *)psys->part); } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index e4dcfcf1354..4afe9412786 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -39,6 +39,10 @@ #include <math.h> #include <string.h> +#ifdef _OPENMP +#include <omp.h> +#endif + #include "MEM_guardedalloc.h" #include "DNA_anim_types.h" @@ -2301,6 +2305,7 @@ static EdgeHash *sph_springhash_build(ParticleSystem *psys) return springhash; } +#define SPH_NEIGHBORS 512 typedef struct SPHNeighbor { ParticleSystem *psys; @@ -2308,7 +2313,7 @@ typedef struct SPHNeighbor } SPHNeighbor; typedef struct SPHRangeData { - SPHNeighbor neighbors[128]; + SPHNeighbor neighbors[SPH_NEIGHBORS]; int tot_neighbors; float density, near_density; @@ -2319,10 +2324,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]; @@ -2332,9 +2333,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; @@ -2345,11 +2352,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; @@ -2359,15 +2368,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; @@ -2408,24 +2440,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); - } - 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; + BLI_bvhtree_range_query(psys[i]->bvhtree, state->co, h, sphdata->density_cb, &pfr); } - 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; @@ -2464,6 +2486,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) { @@ -2477,7 +2500,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); } } @@ -2490,29 +2515,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*/ @@ -2521,9 +2569,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); } /************************************************/ @@ -3623,15 +3669,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, @@ -3717,11 +3763,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; } @@ -3803,37 +3849,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/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 5a57299cf25..7ea4fd751c4 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -80,8 +80,6 @@ #include "FRS_freestyle_config.h" -//XXX #include "nla.h" - #ifdef WIN32 #else #include <sys/time.h> diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 718b3144677..731f82e1b80 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -1574,7 +1574,6 @@ typedef struct WipeZone { int flip; int xo, yo; int width; - float invwidth; float pythangle; } WipeZone; @@ -1585,33 +1584,25 @@ static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo wipezone->xo = xo; wipezone->yo = yo; wipezone->width = (int)(wipe->edgeWidth*((xo+yo)/2.0f)); - wipezone->pythangle = 1.0f/sqrtf(wipe->angle*wipe->angle + 1.0f); - - if(wipe->wipetype == DO_SINGLE_WIPE) - wipezone->invwidth = 1.0f/wipezone->width; - else - wipezone->invwidth = 1.0f/(0.5f*wipezone->width); + wipezone->pythangle = 1.0f/sqrtf(wipezone->angle*wipezone->angle + 1.0f); } // This function calculates the blur band for the wipe effects -static float in_band(WipeZone *wipezone,float width,float dist,float perc,int side,int dir) +static float in_band(float width,float dist,int side,int dir) { - float t1,t2,alpha; + float alpha; if(width == 0) return (float)side; - + if(width < dist) - return side; - - t1 = dist * wipezone->invwidth; //percentange of width that is - t2 = wipezone->invwidth; //amount of alpha per % point - + return (float)side; + if(side == 1) - alpha = (t1*t2*100) + (1-perc); // add point's alpha contrib to current position in wipe + alpha = (dist+0.5*width) / (width); else - alpha = (1-perc) - (t1*t2*100); - + alpha = (0.5*width-dist) / (width); + if(dir == 0) alpha = 1-alpha; @@ -1648,7 +1639,6 @@ float hyp3,hyp4,b4,b5 switch (wipe->wipetype) { case DO_SINGLE_WIPE: width = wipezone->width; - hwidth = width*0.5f; if(angle == 0.0f) { b1 = posy; @@ -1669,15 +1659,15 @@ float hyp3,hyp4,b4,b5 if(wipe->forward) { if(b1 < b2) - output = in_band(wipezone,width,hyp,facf0,1,1); + output = in_band(width,hyp,1,1); else - output = in_band(wipezone,width,hyp,facf0,0,1); + output = in_band(width,hyp,0,1); } else { if(b1 < b2) - output = in_band(wipezone,width,hyp,facf0,0,1); + output = in_band(width,hyp,0,1); else - output = in_band(wipezone,width,hyp,facf0,1,1); + output = in_band(width,hyp,1,1); } break; @@ -1700,27 +1690,23 @@ float hyp3,hyp4,b4,b5 b3 = (yo-posy*0.5f) - (-angle)*(xo-posx*0.5f); b2 = y - (-angle)*x; - hyp = abs(angle*x+y+(-posy*0.5f-angle*posx*0.5f))*wipezone->pythangle; - hyp2 = abs(angle*x+y+(-(yo-posy*0.5f)-angle*(xo-posx*0.5f)))*wipezone->pythangle; + hyp = fabsf(angle*x+y+(-posy*0.5f-angle*posx*0.5f))*wipezone->pythangle; + hyp2 = fabsf(angle*x+y+(-(yo-posy*0.5f)-angle*(xo-posx*0.5f)))*wipezone->pythangle; } - temp1 = xo*(1-facf0*0.5f)-xo*facf0*0.5f; - temp2 = yo*(1-facf0*0.5f)-yo*facf0*0.5f; - pointdist = sqrt(temp1*temp1 + temp2*temp2); + hwidth= MIN2(hwidth, fabsf(b3-b1)/2.0f); if(b2 < b1 && b2 < b3 ){ - if(hwidth < pointdist) - output = in_band(wipezone,hwidth,hyp,facf0,0,1); + output = in_band(hwidth,hyp,0,1); } else if(b2 > b1 && b2 > b3 ){ - if(hwidth < pointdist) - output = in_band(wipezone,hwidth,hyp2,facf0,0,1); + output = in_band(hwidth,hyp2,0,1); } else { if( hyp < hwidth && hyp2 > hwidth ) - output = in_band(wipezone,hwidth,hyp,facf0,1,1); + output = in_band(hwidth,hyp,1,1); else if( hyp > hwidth && hyp2 < hwidth ) - output = in_band(wipezone,hwidth,hyp2,facf0,1,1); + output = in_band(hwidth,hyp2,1,1); else - output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1); + output = in_band(hwidth,hyp2,1,1) * in_band(hwidth,hyp,1,1); } if(!wipe->forward)output = 1-output; break; @@ -1840,8 +1826,8 @@ float hyp3,hyp4,b4,b5 pointdist = sqrt(temp1*temp1 + temp1*temp1); temp2 = sqrt((halfx-x)*(halfx-x) + (halfy-y)*(halfy-y)); - if(temp2 > pointdist) output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,0,1); - else output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,1,1); + if(temp2 > pointdist) output = in_band(hwidth,fabs(temp2-pointdist),0,1); + else output = in_band(hwidth,fabs(temp2-pointdist),1,1); if(!wipe->forward) output = 1-output; diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index cc4b8917a32..6da9199ddc4 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -3070,10 +3070,10 @@ void seq_sound_init(Scene *scene, Sequence *seq) } else { if(seq->sound) { - seq->scene_sound = sound_add_scene_sound(scene, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seq->scene_sound = sound_add_scene_sound_defaults(scene, seq); } if(seq->scene) { - sound_scene_add_scene_sound(scene, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + sound_scene_add_scene_sound_defaults(scene, seq); } } } @@ -3227,10 +3227,8 @@ void seq_update_sound_bounds_all(Scene *scene) void seq_update_sound_bounds(Scene* scene, Sequence *seq) { - if(seq->scene_sound) { - sound_move_scene_sound(scene, seq->scene_sound, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); - /* mute is set in seq_update_muting_recursive */ - } + sound_move_scene_sound_defaults(scene, seq); + /* mute is set in seq_update_muting_recursive */ } static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, int mute) @@ -3772,7 +3770,7 @@ static Sequence *seq_dupli(struct Scene *scene, struct Scene *scene_to, Sequence } else if(seq->type == SEQ_SCENE) { seqn->strip->stripdata = NULL; if(seq->scene_sound) - seqn->scene_sound = sound_scene_add_scene_sound(sce_audio, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seqn->scene_sound = sound_scene_add_scene_sound_defaults(sce_audio, seqn); } else if(seq->type == SEQ_MOVIE) { seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); @@ -3781,7 +3779,7 @@ static Sequence *seq_dupli(struct Scene *scene, struct Scene *scene_to, Sequence seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata); if(seq->scene_sound) - seqn->scene_sound = sound_add_scene_sound(sce_audio, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seqn->scene_sound = sound_add_scene_sound_defaults(sce_audio, seqn); seqn->sound->id.us++; } else if(seq->type == SEQ_IMAGE) { diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index ceaba2502d9..649984a7934 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -449,6 +449,13 @@ void* sound_scene_add_scene_sound(struct Scene *scene, struct Sequence* sequence return NULL; } +void* sound_scene_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence) +{ + return sound_scene_add_scene_sound(scene, sequence, + sequence->startdisp, sequence->enddisp, + sequence->startofs + sequence->anim_startofs); +} + void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip) { void* handle = AUD_addSequence(scene->sound_scene, sequence->sound->playback_handle, startframe / FPS, endframe / FPS, frameskip / FPS); @@ -459,6 +466,13 @@ void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int return handle; } +void* sound_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence) +{ + return sound_add_scene_sound(scene, sequence, + sequence->startdisp, sequence->enddisp, + sequence->startofs + sequence->anim_startofs); +} + void sound_remove_scene_sound(struct Scene *scene, void* handle) { AUD_removeSequence(scene->sound_scene, handle); @@ -474,6 +488,15 @@ void sound_move_scene_sound(struct Scene *scene, void* handle, int startframe, i AUD_moveSequence(handle, startframe / FPS, endframe / FPS, frameskip / FPS); } +void sound_move_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence) +{ + if (sequence->scene_sound) { + sound_move_scene_sound(scene, sequence->scene_sound, + sequence->startdisp, sequence->enddisp, + sequence->startofs + sequence->anim_startofs); + } +} + void sound_update_scene_sound(void* handle, struct bSound* sound) { AUD_updateSequenceSound(handle, sound->playback_handle); @@ -781,11 +804,13 @@ void sound_create_scene(struct Scene *UNUSED(scene)) {} void sound_destroy_scene(struct Scene *UNUSED(scene)) {} void sound_mute_scene(struct Scene *UNUSED(scene), int UNUSED(muted)) {} void* sound_scene_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; } +void* sound_scene_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence)) { return NULL; } void* sound_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; } +void* sound_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence)) { return NULL; } void sound_remove_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle)) {} void sound_mute_scene_sound(void* UNUSED(handle), char UNUSED(mute)) {} void sound_move_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) {} -static void sound_start_play_scene(struct Scene *UNUSED(scene)) {} +void sound_move_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence)) {} void sound_play_scene(struct Scene *UNUSED(scene)) {} void sound_stop_scene(struct Scene *UNUSED(scene)) {} void sound_seek_scene(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene)) {} diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 7bfc7a8ef87..ff76fc14755 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -999,17 +999,24 @@ static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTracki if(anchored) add_v2_v2(mpos, track->offset); + if(pos) + zero_v2(pos); + x= mpos[0]*ibuf->x; y= mpos[1]*ibuf->y; - x1= x-(int)(-min[0]*ibuf->x); - y1= y-(int)(-min[1]*ibuf->y); - x2= x+(int)(max[0]*ibuf->x); - y2= y+(int)(max[1]*ibuf->y); - /* dimensions should be odd */ - w= (x2-x1)|1; - h= (y2-y1)|1; + w= (max[0]-min[0])*ibuf->x; + h= (max[1]-min[1])*ibuf->y; + + w= w|1; + h= h|1; + x1= x-(int)(w/2.0f); + y1= y-(int)(h/2.0f); + x2= x+(int)(w/2.0f); + y2= y+(int)(h/2.0f); + + /* dimensions should be odd */ tmpibuf= IMB_allocImBuf(w+margin*2, h+margin*2, 32, IB_rect); IMB_rectcpy(tmpibuf, ibuf, 0, 0, x1-margin, y1-margin, w+margin*2, h+margin*2); @@ -1023,13 +1030,17 @@ static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTracki origin[1]= y1-margin; } - if ((track->flag & TRACK_PREVIEW_GRAYSCALE) || - (track->flag & TRACK_DISABLE_RED) || - (track->flag & TRACK_DISABLE_GREEN) || - (track->flag & TRACK_DISABLE_BLUE) ) { + if((track->flag & TRACK_PREVIEW_GRAYSCALE) || + (track->flag & TRACK_DISABLE_RED) || + (track->flag & TRACK_DISABLE_GREEN) || + (track->flag & TRACK_DISABLE_BLUE)) + { disable_imbuf_channels(tmpibuf, track, 1 /* grayscale */); } + tmpibuf->ftype= PNG; + IMB_saveiff(tmpibuf, "/tmp/1.png", IB_rect); + return tmpibuf; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 3ffd8979b03..029e526c256 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -39,6 +39,7 @@ #include <fcntl.h> // for open #include <string.h> // for strrchr strncmp strstr #include <math.h> // for fabs +#include <stdarg.h> /* for va_start/end */ #ifndef WIN32 #include <unistd.h> // for read close @@ -250,6 +251,31 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname); static void direct_link_modifiers(FileData *fd, ListBase *lb); static void convert_tface_mt(FileData *fd, Main *main); +/* this function ensures that reports are printed, + * in the case of libraray linking errors this is important! + * + * bit kludge but better then doubling up on prints, + * we could alternatively have a versions of a report function which foces printing - campbell + */ +static void BKE_reportf_wrap(ReportList *reports, ReportType type, const char *format, ...) +{ + char fixed_buf[1024]; /* should be long enough */ + + va_list args; + + va_start(args, format); + vsnprintf(fixed_buf, sizeof(fixed_buf), format, args); + va_end(args); + + fixed_buf[sizeof(fixed_buf) - 1] = '\0'; + + BKE_report(reports, type, fixed_buf); + + if(G.background==0) { + printf("%s\n", fixed_buf); + } +} + static OldNewMap *oldnewmap_new(void) { OldNewMap *onm= MEM_callocN(sizeof(*onm), "OldNewMap"); @@ -4116,8 +4142,9 @@ static void lib_link_object(FileData *fd, Main *main) ob= ob->id.next; } - if(warn) + if(warn) { BKE_report(fd->reports, RPT_WARNING, "Warning in console"); + } } @@ -4699,8 +4726,9 @@ static void lib_link_scene(FileData *fd, Main *main) base->object= newlibadr_us(fd, sce->id.lib, base->object); if(base->object==NULL) { - BKE_reportf(fd->reports, RPT_ERROR, "LIB ERROR: Object lost from scene:'%s\'\n", sce->id.name+2); - if(G.background==0) printf("LIB ERROR: base removed from scene:'%s\'\n", sce->id.name+2); + BKE_reportf_wrap(fd->reports, RPT_ERROR, + "LIB ERROR: Object lost from scene:'%s\'\n", + sce->id.name+2); BLI_remlink(&sce->base, base); if(base==sce->basact) sce->basact= NULL; MEM_freeN(base); @@ -4713,7 +4741,7 @@ static void lib_link_scene(FileData *fd, Main *main) if(seq->scene) { seq->scene= newlibadr(fd, sce->id.lib, seq->scene); if(seq->scene) { - seq->scene_sound = sound_scene_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seq->scene_sound = sound_scene_add_scene_sound_defaults(sce, seq); } } if(seq->scene_camera) seq->scene_camera= newlibadr(fd, sce->id.lib, seq->scene_camera); @@ -4725,7 +4753,7 @@ static void lib_link_scene(FileData *fd, Main *main) seq->sound= newlibadr(fd, sce->id.lib, seq->sound); if (seq->sound) { seq->sound->id.us++; - seq->scene_sound = sound_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); + seq->scene_sound = sound_add_scene_sound_defaults(sce, seq); } } seq->anim= NULL; @@ -5812,8 +5840,9 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main) for(newmain= fd->mainlist.first; newmain; newmain= newmain->next) { if(newmain->curlib) { if(BLI_path_cmp(newmain->curlib->filepath, lib->filepath) == 0) { - printf("Fixed error in file; multiple instances of lib:\n %s\n", lib->filepath); - BKE_reportf(fd->reports, RPT_WARNING, "Library '%s', '%s' had multiple instances, save and reload!", lib->name, lib->filepath); + BKE_reportf_wrap(fd->reports, RPT_WARNING, + "Library '%s', '%s' had multiple instances, save and reload!", + lib->name, lib->filepath); change_idid_adr(&fd->mainlist, fd, lib, newmain->curlib); // change_idid_adr_fd(fd, lib, newmain->curlib); @@ -7707,6 +7736,32 @@ static void do_versions_nodetree_socket_use_flags_2_62(bNodeTree *ntree) } } +/* set the SOCK_AUTO_HIDDEN flag on collapsed nodes */ +static void do_versions_nodetree_socket_auto_hidden_flags_2_62(bNodeTree *ntree) +{ + bNode *node; + bNodeSocket *sock; + + for (node=ntree->nodes.first; node; node=node->next) { + if (node->flag & NODE_HIDDEN) { + for (sock=node->inputs.first; sock; sock=sock->next) { + if (sock->link==NULL) + sock->flag |= SOCK_AUTO_HIDDEN; + } + for(sock=node->outputs.first; sock; sock= sock->next) { + if(nodeCountSocketLinks(ntree, sock)==0) + sock->flag |= SOCK_AUTO_HIDDEN; + } + } + else { + for(sock=node->inputs.first; sock; sock= sock->next) + sock->flag &= ~SOCK_AUTO_HIDDEN; + for(sock=node->outputs.first; sock; sock= sock->next) + sock->flag &= ~SOCK_AUTO_HIDDEN; + } + } +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -12939,7 +12994,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } - /* put compatibility code here until next subversion bump */ + if (main->versionfile < 261 || (main->versionfile == 261 && main->subversionfile < 1)) { { /* update use flags for node sockets (was only temporary before) */ @@ -13022,6 +13077,60 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } } + { + /* Warn the user if he is using ["Text"] properties for Font objects */ + Object *ob; + bProperty *prop; + + for (ob= main->object.first; ob; ob= ob->id.next) { + if (ob->type == OB_FONT) { + prop = get_ob_property(ob, "Text"); + if (prop) { + BKE_reportf_wrap(fd->reports, RPT_WARNING, + "Game property name conflict in object: \"%s\".\nText objects reserve the " + "[\"Text\"] game property to change their content through Logic Bricks.\n", + ob->id.name+2); + } + } + } + } + { + /* set the SOCK_AUTO_HIDDEN flag on collapsed nodes */ + Scene *sce; + Material *mat; + Tex *tex; + Lamp *lamp; + World *world; + bNodeTree *ntree; + + for (sce=main->scene.first; sce; sce=sce->id.next) + if (sce->nodetree) + do_versions_nodetree_socket_auto_hidden_flags_2_62(sce->nodetree); + + for (mat=main->mat.first; mat; mat=mat->id.next) + if (mat->nodetree) + do_versions_nodetree_socket_auto_hidden_flags_2_62(mat->nodetree); + + for (tex=main->tex.first; tex; tex=tex->id.next) + if (tex->nodetree) + do_versions_nodetree_socket_auto_hidden_flags_2_62(tex->nodetree); + + for (lamp=main->lamp.first; lamp; lamp=lamp->id.next) + if (lamp->nodetree) + do_versions_nodetree_socket_auto_hidden_flags_2_62(lamp->nodetree); + + for (world=main->world.first; world; world=world->id.next) + if (world->nodetree) + do_versions_nodetree_socket_auto_hidden_flags_2_62(world->nodetree); + + for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) + do_versions_nodetree_socket_auto_hidden_flags_2_62(ntree); + } + } + + /* put compatibility code here until next subversion bump */ + { + } /* default values in Freestyle settings */ @@ -14527,8 +14636,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) if(fd==NULL) { /* printf and reports for now... its important users know this */ - BKE_reportf(basefd->reports, RPT_INFO, "read library: '%s', '%s'\n", mainptr->curlib->filepath, mainptr->curlib->name); - if(!G.background && basefd->reports) printf("read library: '%s', '%s'\n", mainptr->curlib->filepath, mainptr->curlib->name); + BKE_reportf_wrap(basefd->reports, RPT_INFO, + "read library: '%s', '%s'\n", + mainptr->curlib->filepath, mainptr->curlib->name); fd= blo_openblenderfile(mainptr->curlib->filepath, basefd->reports); @@ -14573,8 +14683,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) else mainptr->curlib->filedata= NULL; if (fd==NULL) { - BKE_reportf(basefd->reports, RPT_ERROR, "Can't find lib '%s'\n", mainptr->curlib->filepath); - if(!G.background && basefd->reports) printf("ERROR: can't find lib %s \n", mainptr->curlib->filepath); + BKE_reportf_wrap(basefd->reports, RPT_ERROR, + "Can't find lib '%s'\n", + mainptr->curlib->filepath); } } if(fd) { @@ -14591,8 +14702,10 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) append_id_part(fd, mainptr, id, &realid); if (!realid) { - BKE_reportf(fd->reports, RPT_ERROR, "LIB ERROR: %s:'%s' missing from '%s'\n", BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); - if(!G.background && basefd->reports) printf("LIB ERROR: %s:'%s' missing from '%s'\n", BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); + BKE_reportf_wrap(fd->reports, RPT_ERROR, + "LIB ERROR: %s:'%s' missing from '%s'\n", + BKE_idcode_to_name(GS(id->name)), + id->name+2, mainptr->curlib->filepath); } change_idid_adr(mainlist, basefd, id, realid); @@ -14628,13 +14741,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) ID *idn= id->next; if(id->flag & LIB_READ) { BLI_remlink(lbarray[a], id); - BKE_reportf(basefd->reports, RPT_ERROR, - "LIB ERROR: %s:'%s' unread libblock missing from '%s'\n", - BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); - if (!G.background && basefd->reports) { - printf("LIB ERROR: %s:'%s' unread libblock missing from '%s'\n", - BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); - } + BKE_reportf_wrap(basefd->reports, RPT_ERROR, + "LIB ERROR: %s:'%s' unread libblock missing from '%s'\n", + BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); change_idid_adr(mainlist, basefd, id, NULL); MEM_freeN(id); diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index beecbc7abed..f1dfbd40c11 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1914,6 +1914,10 @@ static size_t animdata_filter_ds_world (bAnimContext *ac, ListBase *anim_data, b /* textures for world */ if (!(ads->filterflag & ADS_FILTER_NOTEX)) items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)wo, filter_mode); + + /* nodes */ + if ((wo->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) + tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)wo, wo->nodetree, filter_mode); } END_ANIMFILTER_SUBCHANNELS; @@ -2009,12 +2013,12 @@ static size_t animdata_filter_dopesheet_scene (bAnimContext *ac, ListBase *anim_ } /* world */ - if ((wo && wo->adt) && !(ads->filterflag & ADS_FILTER_NOWOR)) { + if ((wo) && !(ads->filterflag & ADS_FILTER_NOWOR)) { tmp_items += animdata_filter_ds_world(ac, &tmp_data, ads, sce, wo, filter_mode); } /* nodetree */ - if ((ntree && ntree->adt) && !(ads->filterflag & ADS_FILTER_NONTREE)) { + if ((ntree) && !(ads->filterflag & ADS_FILTER_NONTREE)) { tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)sce, ntree, filter_mode); } diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c index 8e36e02bbb4..8c4e0065a19 100644 --- a/source/blender/editors/animation/anim_ipo_utils.c +++ b/source/blender/editors/animation/anim_ipo_utils.c @@ -161,6 +161,11 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu) * use the struct's icon if it is set */ icon= RNA_struct_ui_icon(ptr.type); + + /* valid path - remove the invalid tag since we now know how to use it saving + * users manual effort to reenable using "Revive Disabled FCurves" [#29629] + */ + fcu->flag &= ~FCURVE_DISABLED; } else { /* invalid path */ diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 48f3f78b849..becc7e9b68f 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 5c7d9249c5f..51d3c3f021b 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_draw.c b/source/blender/editors/interface/interface_draw.c index 6ebb67af67a..1f1228a9bc5 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1465,21 +1465,16 @@ static ImBuf *scale_trackpreview_ibuf(ImBuf *ibuf, float zoomx, float zoomy) { ImBuf *scaleibuf; int x, y, w= ibuf->x*zoomx, h= ibuf->y*zoomy; - const float max_x= ibuf->x-1.0f; - const float max_y= ibuf->y-1.0f; const float scalex= 1.0f/zoomx; const float scaley= 1.0f/zoomy; scaleibuf= IMB_allocImBuf(w, h, 32, IB_rect); - for(y= 0; y<scaleibuf->y; y++) { - for (x= 0; x<scaleibuf->x; x++) { + for(y= 0; y<h; y++) { + for (x= 0; x<w; x++) { float src_x= scalex*x; float src_y= scaley*y; - CLAMP(src_x, 0, max_x); - CLAMP(src_y, 0, max_y); - bicubic_interpolation(ibuf, scaleibuf, src_x, src_y, x, y); } } @@ -1514,28 +1509,36 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc ok= 1; } else if(scopes->track_preview) { - int a, off_x, off_y; - float zoomx, zoomy; + /* additional margin around image */ + /* NOTE: should be kept in sync with value from BKE_movieclip_update_scopes */ + const int margin= 2; + float zoomx, zoomy, track_pos[2], off_x, off_y; + int a; ImBuf *drawibuf; glPushMatrix(); + track_pos[0]= scopes->track_pos[0]-margin; + track_pos[1]= scopes->track_pos[1]-margin; + /* draw content of pattern area */ glScissor(ar->winrct.xmin+rect.xmin, ar->winrct.ymin+rect.ymin, scissor[2], scissor[3]); - zoomx= (rect.xmax-rect.xmin) / (scopes->track_preview->x-2.0f); - zoomy= (rect.ymax-rect.ymin) / (scopes->track_preview->y-2.0f); + zoomx= (rect.xmax-rect.xmin) / (scopes->track_preview->x-2*margin); + zoomy= (rect.ymax-rect.ymin) / (scopes->track_preview->y-2*margin); - off_x= ((int)scopes->track_pos[0]-scopes->track_pos[0]-0.5f)*zoomx; - off_y= ((int)scopes->track_pos[1]-scopes->track_pos[1]-0.5f)*zoomy; + off_x= ((int)track_pos[0]-track_pos[0]+0.5)*zoomx; + off_y= ((int)track_pos[1]-track_pos[1]+0.5)*zoomy; drawibuf= scale_trackpreview_ibuf(scopes->track_preview, zoomx, zoomy); - glaDrawPixelsSafe(off_x+rect.xmin, off_y+rect.ymin, rect.xmax-rect.xmin+1.f-off_x, rect.ymax-rect.ymin+1.f-off_y, drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect); - + glaDrawPixelsSafe(off_x+rect.xmin-zoomx*(margin-0.5f), off_y+rect.ymin-zoomy*(margin-0.5f), + rect.xmax-rect.xmin+2+(int)(zoomx*(margin-0.5f)-off_x), + rect.ymax-rect.ymin+2+(int)(zoomy*(margin-0.5f)-off_y), + drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect); IMB_freeImBuf(drawibuf); /* draw cross for pizel position */ - glTranslatef(off_x+rect.xmin+scopes->track_pos[0]*zoomx, off_y+rect.ymin+scopes->track_pos[1]*zoomy, 0.f); + glTranslatef(off_x+rect.xmin+track_pos[0]*zoomx, off_y+rect.ymin+track_pos[1]*zoomy, 0.f); glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin+rect.ymin, rect.xmax-rect.xmin, rect.ymax-rect.ymin); for(a= 0; a< 2; a++) { diff --git a/source/blender/editors/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 '.': + return BUTTON_DELIM_PUNCT; + + case '{': + case '}': + case '[': + case ']': + case '(': + case ')': + return BUTTON_DELIM_BRACE; + + 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 ')': - case '+': - case '=': - case '{': - case '}': - case '[': - case ']': case ':': case ';': - case '\'': - case '\"': // " - an extra closing one for Aligorith's text editor - 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/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 0670692a084..8df43b92760 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -55,6 +55,7 @@ #include "BKE_texture.h" #include "BKE_report.h" #include "BKE_displist.h" +#include "BKE_scene.h" #include "ED_screen.h" #include "ED_object.h" @@ -2126,6 +2127,7 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe else if(RNA_struct_is_a(itemptr->type, &RNA_MaterialSlot)) { /* provision to draw active node name */ Material *ma, *manode; + Scene *scene= CTX_data_scene(C); Object *ob= (Object*)ptr->id.data; int index= (Material**)itemptr->data - ob->mat; @@ -2133,7 +2135,7 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe uiItemL(sub, name, icon); ma= give_current_material(ob, index+1); - if(ma) { + if (ma && !scene_use_new_shading_nodes(scene)){ manode= give_node_material(ma); if(manode) { char str[MAX_ID_NAME + 12]; diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 5706da93fe9..a993e651b5f 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -248,20 +248,19 @@ static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event) view_pan_apply(op); } break; - + /* XXX - Mode switching isn't implemented. See comments in 36818. + * switch to zoom * case LEFTMOUSE: - /* switch to zoom */ if (event->val==KM_PRESS) { - /* calculate overall delta mouse-movement for redo */ + * calculate overall delta mouse-movement for redo * RNA_int_set(op->ptr, "deltax", (vpd->startx - vpd->lastx)); RNA_int_set(op->ptr, "deltay", (vpd->starty - vpd->lasty)); view_pan_exit(op); WM_cursor_restore(CTX_wm_window(C)); - WM_operator_name_call(C, "VIEW2D_OT_zoom", WM_OP_INVOKE_DEFAULT, NULL); return OPERATOR_FINISHED; - } + }*/ default: if (event->type == vpd->invoke_event || event->type==ESCKEY) { diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 7253d426ca6..7762203c371 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -318,14 +318,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)) @@ -435,7 +435,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)) @@ -464,7 +464,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)) @@ -490,7 +490,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)) @@ -520,7 +520,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) @@ -551,7 +551,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 fa308624454..6a68a264a28 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -108,9 +108,12 @@ static void waitcursor(int UNUSED(val)) {} static int pupmenu(const char *UNUSED(msg)) {return 0;} /* port over here */ -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 */ @@ -118,7 +121,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; @@ -718,240 +721,6 @@ static void spot_interactive(Object *ob, int mode) } #endif -static void UNUSED_FUNCTION(special_editmenu)(Scene *scene, View3D *v3d) -{ -// XXX static short numcuts= 2; - Object *ob= OBACT; - Object *obedit= NULL; // XXX - int nr,ret=0; - - if(ob==NULL) return; - - if(obedit==NULL) { - - if(ob->mode & OB_MODE_POSE) { -// XXX pose_special_editmenu(); - } - else if(paint_facesel_test(ob)) { - Mesh *me= get_mesh(ob); - MTFace *tface; - MFace *mface; - int a; - - if(me==NULL || me->mtface==NULL) return; - - nr= pupmenu("Specials%t|Set Tex%x1| Shared%x2| Light%x3| Invisible%x4| Collision%x5| TwoSide%x6|Clr Tex%x7| Shared%x8| Light%x9| Invisible%x10| Collision%x11| TwoSide%x12"); - - tface= me->mtface; - mface= me->mface; - for(a=me->totface; a>0; a--, tface++, mface++) { - if(mface->flag & ME_FACE_SEL) { - switch(nr) { - case 1: - tface->mode |= TF_TEX; break; - case 2: - tface->mode |= TF_SHAREDCOL; break; - case 3: - tface->mode |= TF_LIGHT; break; - case 4: - tface->mode |= TF_INVISIBLE; break; - case 5: - tface->mode |= TF_DYNAMIC; break; - case 6: - tface->mode |= TF_TWOSIDE; break; - case 7: - tface->mode &= ~TF_TEX; - tface->tpage= NULL; - break; - case 8: - tface->mode &= ~TF_SHAREDCOL; break; - case 9: - tface->mode &= ~TF_LIGHT; break; - case 10: - tface->mode &= ~TF_INVISIBLE; break; - case 11: - tface->mode &= ~TF_DYNAMIC; break; - case 12: - tface->mode &= ~TF_TWOSIDE; break; - } - } - } - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - } - else if(ob->mode & OB_MODE_VERTEX_PAINT) { - Mesh *me= get_mesh(ob); - - if(me==NULL || (me->mcol==NULL && me->mtface==NULL) ) return; - - nr= pupmenu("Specials%t|Shared VertexCol%x1"); - if(nr==1) { - -// XXX do_shared_vertexcol(me); - - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - } - } - else if(ob->mode & OB_MODE_WEIGHT_PAINT) { - Object *par= modifiers_isDeformedByArmature(ob); - - if(par && (par->mode & OB_MODE_POSE)) { -// XXX nr= pupmenu("Specials%t|Apply Bone Envelopes to Vertex Groups %x1|Apply Bone Heat Weights to Vertex Groups %x2"); - -// XXX if(nr==1 || nr==2) -// XXX pose_adds_vgroups(ob, (nr == 2)); - } - } - else if(ob->mode & OB_MODE_PARTICLE_EDIT) { -#if 0 - // XXX - ParticleSystem *psys = PE_get_current(ob); - ParticleEditSettings *pset = PE_settings(); - - if(!psys) - return; - - if(pset->selectmode & SCE_SELECT_POINT) - nr= pupmenu("Specials%t|Rekey%x1|Subdivide%x2|Select First%x3|Select Last%x4|Remove Doubles%x5"); - else - nr= pupmenu("Specials%t|Rekey%x1|Remove Doubles%x5"); - - switch(nr) { - case 1: -// XXX if(button(&pset->totrekey, 2, 100, "Number of Keys:")==0) return; - waitcursor(1); - PE_rekey(); - break; - case 2: - PE_subdivide(); - break; - case 3: - PE_select_root(); - break; - case 4: - PE_select_tip(); - break; - case 5: - PE_remove_doubles(); - break; - } - - DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); - - if(nr>0) waitcursor(0); -#endif - } - else { - Base *base, *base_select= NULL; - - /* Get the active object mesh. */ - Mesh *me= get_mesh(ob); - - /* Booleans, if the active object is a mesh... */ - if (me && ob->id.lib==NULL) { - - /* Bring up a little menu with the boolean operation choices on. */ - nr= pupmenu("Boolean Tools%t|Intersect%x1|Union%x2|Difference%x3|Add Intersect Modifier%x4|Add Union Modifier%x5|Add Difference Modifier%x6"); - - if (nr > 0) { - /* user has made a choice of a menu element. - All of the boolean functions require 2 mesh objects - we search through the object list to find the other - selected item and make sure it is distinct and a mesh. */ - - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - if(base->object != ob) base_select= base; - } - } - - if (base_select) { - if (get_mesh(base_select->object)) { - if(nr <= 3){ - waitcursor(1); -// XXX ret = NewBooleanMesh(BASACT,base_select,nr); - if (ret==0) { - error("An internal error occurred"); - } else if(ret==-1) { - error("Selected meshes must have faces to perform boolean operations"); - } else if (ret==-2) { - error("Both meshes must be a closed mesh"); - } - waitcursor(0); - } else { - BooleanModifierData *bmd = NULL; - bmd = (BooleanModifierData *)modifier_new(eModifierType_Boolean); - BLI_addtail(&ob->modifiers, bmd); - modifier_unique_name(&ob->modifiers, (ModifierData*)bmd); - bmd->object = base_select->object; - bmd->modifier.mode |= eModifierMode_Realtime; - switch(nr){ - case 4: bmd->operation = eBooleanModifierOp_Intersect; break; - case 5: bmd->operation = eBooleanModifierOp_Union; break; - case 6: bmd->operation = eBooleanModifierOp_Difference; break; - } -// XXX do_common_editbuts(B_CHANGEDEP); - } - } else { - error("Please select 2 meshes"); - } - } else { - error("Please select 2 meshes"); - } - } - - } - else if (ob->type == OB_FONT) { - /* removed until this gets a decent implementation (ton) */ -/* nr= pupmenu("Split %t|Characters%x1"); - if (nr > 0) { - switch(nr) { - case 1: split_font(); - } - } -*/ - } - } - } - else if(obedit->type==OB_MESH) { - } - else if(ELEM(obedit->type, OB_CURVE, OB_SURF)) { - } - else if(obedit->type==OB_ARMATURE) { - nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Switch Direction%x7|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6"); -// if(nr==1) -// XXX subdivide_armature(1); - if(nr==2) { -// XXX if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return; - waitcursor(1); -// XXX subdivide_armature(numcuts); - } -// else if(nr==3) -// XXX armature_flip_names(); - else if(ELEM3(nr, 4, 5, 6)) { -// XXX armature_autoside_names(nr-4); - } -// else if(nr == 7) -// XXX switch_direction_armature(); - } - else if(obedit->type==OB_LATTICE) { - Lattice *lt= obedit->data; - static float weight= 1.0f; - { // XXX -// XXX if(fbutton(&weight, 0.0f, 1.0f, 10, 10, "Set Weight")) { - Lattice *editlt= lt->editlatt->latt; - int a= editlt->pntsu*editlt->pntsv*editlt->pntsw; - BPoint *bp= editlt->def; - - while(a--) { - if(bp->f1 & SELECT) - bp->weight= weight; - bp++; - } - } - } - -} - static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob) { //XXX no longer used - to be removed - replaced by game_properties_copy_exec @@ -1674,102 +1443,6 @@ static void UNUSED_FUNCTION(image_aspect)(Scene *scene, View3D *v3d) } -static int vergbaseco(const void *a1, const void *a2) -{ - Base **x1, **x2; - - x1= (Base **) a1; - x2= (Base **) a2; - - if( (*x1)->sy > (*x2)->sy ) return 1; - else if( (*x1)->sy < (*x2)->sy) return -1; - else if( (*x1)->sx > (*x2)->sx ) return 1; - else if( (*x1)->sx < (*x2)->sx ) return -1; - - return 0; -} - - -static void UNUSED_FUNCTION(auto_timeoffs)(Scene *scene, View3D *v3d) -{ - Base *base, **basesort, **bs; - float start, delta; - int tot=0, a; - short offset=25; - - if(BASACT==NULL || v3d==NULL) return; -// XXX if(button(&offset, 0, 1000,"Total time")==0) return; - - /* make array of all bases, xco yco (screen) */ - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - tot++; - } - } - - delta= (float)offset/(float)tot; - start= OBACT->sf; - - bs= basesort= MEM_mallocN(sizeof(void *)*tot,"autotimeoffs"); - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - *bs= base; - bs++; - } - } - qsort(basesort, tot, sizeof(void *), vergbaseco); - - bs= basesort; - for(a=0; a<tot; a++) { - - (*bs)->object->sf= start; - start+= delta; - - bs++; - } - MEM_freeN(basesort); - -} - -static void UNUSED_FUNCTION(ofs_timeoffs)(Scene *scene, View3D *v3d) -{ - float offset=0.0f; - - if(BASACT==NULL || v3d==NULL) return; - -// XXX if(fbutton(&offset, -10000.0f, 10000.0f, 10, 10, "Offset")==0) return; - - /* make array of all bases, xco yco (screen) */ - CTX_DATA_BEGIN(evil_C, Object*, ob, selected_editable_objects) { - ob->sf += offset; - if (ob->sf < -MAXFRAMEF) ob->sf = -MAXFRAMEF; - else if (ob->sf > MAXFRAMEF) ob->sf = MAXFRAMEF; - } - CTX_DATA_END; - -} - - -static void UNUSED_FUNCTION(rand_timeoffs)(Scene *scene, View3D *v3d) -{ - Base *base; - float rand_ofs=0.0f; - - if(BASACT==NULL || v3d==NULL) return; - -// XXX if(fbutton(&rand_ofs, 0.0f, 10000.0f, 10, 10, "Randomize")==0) return; - - rand_ofs *= 2; - - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - base->object->sf += ((float)BLI_drand()-0.5f) * rand_ofs; - if (base->object->sf < -MAXFRAMEF) base->object->sf = -MAXFRAMEF; - else if (base->object->sf > MAXFRAMEF) base->object->sf = MAXFRAMEF; - } - } - -} static EnumPropertyItem *object_mode_set_itemsf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) { @@ -1932,16 +1605,21 @@ void ED_object_toggle_modes(bContext *C, int mode) /************************ Game Properties ***********************/ -static int game_property_new(bContext *C, wmOperator *UNUSED(op)) +static int game_property_new(bContext *C, wmOperator *op) { Object *ob= CTX_data_active_object(C); bProperty *prop; + char name[32]; + int type= RNA_enum_get(op->ptr, "type"); - if(!ob) - return OPERATOR_CANCELLED; - - prop= new_property(PROP_FLOAT); + prop= new_property(type); BLI_addtail(&ob->prop, prop); + + RNA_string_get(op->ptr, "name", name); + if (name[0] != '\0') { + BLI_strncpy(prop->name, name, sizeof(prop->name)); + } + unique_property(NULL, prop, 0); // make_unique_prop_names(prop->name); WM_event_add_notifier(C, NC_LOGIC, NULL); @@ -1962,6 +1640,9 @@ void OBJECT_OT_game_property_new(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "type", gameproperty_type_items, 2, "Type", "Type of game property to add"); + RNA_def_string(ot->srna, "name", "", 32, "Name", "Name of the game property to add"); } static int game_property_remove(bContext *C, wmOperator *op) diff --git a/source/blender/editors/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 bfb5d166e6f..dfe0b94605d 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -67,6 +67,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "ED_object.h" #include "ED_mesh.h" #include "UI_resources.h" @@ -582,23 +583,47 @@ static void vgroup_select_verts(Object *ob, int select) if(ob->type == OB_MESH) { Mesh *me= ob->data; - EditMesh *em = BKE_mesh_get_editmesh(me); - EditVert *eve; - for (eve=em->verts.first; eve; eve=eve->next) { - if (!eve->h) { - dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); - if (defvert_find_index(dv, def_nr)) { - if (select) eve->f |= SELECT; - else eve->f &= ~SELECT; + if (me->edit_mesh) { + EditMesh *em = BKE_mesh_get_editmesh(me); + EditVert *eve; + + for (eve=em->verts.first; eve; eve=eve->next) { + if (!eve->h) { + dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + if (defvert_find_index(dv, def_nr)) { + if (select) eve->f |= SELECT; + else eve->f &= ~SELECT; + } } } + /* this has to be called, because this function operates on vertices only */ + if(select) EM_select_flush(em); // vertices to edges/faces + else EM_deselect_flush(em); + + BKE_mesh_end_editmesh(me, em); } - /* this has to be called, because this function operates on vertices only */ - if(select) EM_select_flush(em); // vertices to edges/faces - else EM_deselect_flush(em); + else { + if (me->dvert) { + MVert *mv; + MDeformVert *dv; + int i; + + mv = me->mvert; + dv = me->dvert; + + for (i=0; i<me->totvert; i++, mv++, dv++) { + if (!(mv->flag & ME_HIDE)) { + if (defvert_find_index(dv, def_nr)) { + if (select) mv->flag |= SELECT; + else mv->flag &= ~SELECT; + } + } + } - BKE_mesh_end_editmesh(me, em); + paintvert_flush_flags(ob); + } + } } else if(ob->type == OB_LATTICE) { Lattice *lt= vgroup_edit_lattice(ob); @@ -1740,23 +1765,47 @@ 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) { - EditVert *eve; MDeformVert *dv; const int def_nr= BLI_findindex(&ob->defbase, dg); if(ob->type == OB_MESH) { Mesh *me= ob->data; - EditMesh *em = BKE_mesh_get_editmesh(me); - for(eve=em->verts.first; eve; eve=eve->next){ - dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + if (me->edit_mesh) { + EditVert *eve; + EditMesh *em = BKE_mesh_get_editmesh(me); - if(dv && dv->dw && (allverts || (eve->f & SELECT))){ - MDeformWeight *dw = defvert_find_index(dv, def_nr); - defvert_remove_group(dv, dw); /* dw can be NULL */ + for (eve=em->verts.first; eve; eve=eve->next) { + dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + + if (dv && dv->dw && (allverts || (eve->f & SELECT))) { + MDeformWeight *dw = defvert_find_index(dv, def_nr); + defvert_remove_group(dv, dw); /* dw can be NULL */ + } + } + BKE_mesh_end_editmesh(me, em); + } + 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; i<me->totvert; 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 */ + } + } } } - BKE_mesh_end_editmesh(me, em); } else if(ob->type == OB_LATTICE) { Lattice *lt= vgroup_edit_lattice(ob); @@ -1861,6 +1910,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_mesh == 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); @@ -1907,24 +1968,48 @@ static void vgroup_assign_verts(Object *ob, const float weight) if(ob->type == OB_MESH) { Mesh *me= ob->data; - EditMesh *em = BKE_mesh_get_editmesh(me); - EditVert *eve; + if (me->edit_mesh) { + EditMesh *em = BKE_mesh_get_editmesh(me); + EditVert *eve; - if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) - EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT, NULL); + if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) + EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT, NULL); - /* Go through the list of editverts and assign them */ - for (eve=em->verts.first; eve; eve=eve->next) { - if (eve->f & SELECT) { - MDeformWeight *dw; - dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); /* can be NULL */ - dw= defvert_verify_index(dv, def_nr); - if (dw) { - dw->weight= weight; + /* Go through the list of editverts and assign them */ + for (eve=em->verts.first; eve; eve=eve->next) { + if (eve->f & SELECT) { + MDeformWeight *dw; + dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); /* can be NULL */ + dw= defvert_verify_index(dv, def_nr); + if (dw) { + dw->weight= weight; + } + } + } + BKE_mesh_end_editmesh(me, em); + } + 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; i<me->totvert; i++, mv++, dv++) { + if (mv->flag & SELECT) { + MDeformWeight *dw; + dw= defvert_verify_index(dv, def_nr); + if (dw) { + dw->weight= weight; + } } } } - BKE_mesh_end_editmesh(me, em); } else if(ob->type == OB_LATTICE) { Lattice *lt= vgroup_edit_lattice(ob); @@ -1968,14 +2053,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)) @@ -1984,9 +2069,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); @@ -2012,7 +2110,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); @@ -2049,7 +2147,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); @@ -2068,7 +2166,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 */ @@ -2083,7 +2181,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); @@ -2110,7 +2208,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 */ @@ -2125,7 +2223,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; @@ -2143,7 +2241,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 */ @@ -2152,7 +2250,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); @@ -2167,7 +2265,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 */ @@ -2176,7 +2274,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); @@ -2202,7 +2300,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"); @@ -2235,7 +2333,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); @@ -2262,7 +2360,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); @@ -2372,7 +2470,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"); @@ -2406,7 +2504,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); @@ -2435,7 +2533,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"); @@ -2474,7 +2572,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"), @@ -2513,7 +2611,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; @@ -2553,7 +2651,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; @@ -2596,7 +2694,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); @@ -2610,7 +2708,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; @@ -2751,7 +2849,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; @@ -2790,7 +2888,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 bbff2239a38..b26661da4a2 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 96018de130b..937f43dfadb 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -77,6 +77,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" @@ -95,7 +96,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; @@ -124,7 +125,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; @@ -160,7 +161,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; @@ -220,7 +221,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; @@ -326,7 +327,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/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index ffdfea7fde5..98f85009140 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3309,7 +3309,6 @@ static void SCREEN_OT_delete(wmOperatorType *ot) static int scene_new_exec(bContext *C, wmOperator *op) { Scene *newscene, *scene= CTX_data_scene(C); - bScreen *screen= CTX_wm_screen(C); Main *bmain= CTX_data_main(C); int type= RNA_enum_get(op->ptr, "type"); @@ -3328,11 +3327,9 @@ static int scene_new_exec(bContext *C, wmOperator *op) } } - /* this notifier calls ED_screen_set_scene, doing a lot of UI stuff, not for inside event loops */ - WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, newscene); + ED_screen_set_scene(C, newscene); - if(screen) - screen->scene= newscene; + WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, newscene); return OPERATOR_FINISHED; } @@ -3368,9 +3365,14 @@ static void SCENE_OT_new(wmOperatorType *ot) static int scene_delete_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); - + + ED_screen_delete_scene(C, scene); + + if(G.f & G_DEBUG) + printf("scene delete %p\n", scene); + WM_event_add_notifier(C, NC_SCENE|NA_REMOVED, scene); - + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index 31aab956754..fe2dc1fb913 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -278,7 +278,6 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float ScreenshotJob *sj= sjv; RenderData rd= sj->scene->r; bMovieHandle *mh= BKE_get_movie_handle(sj->scene->r.im_format.imtype); - int cfra= 1; /* we need this as local variables for renderdata */ rd.frs_sec= U.scrcastfps; @@ -303,9 +302,9 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float if(sj->dumprect) { if(mh) { - if(mh->append_movie(&rd, cfra, (int *)sj->dumprect, sj->dumpsx, sj->dumpsy, &sj->reports)) { - BKE_reportf(&sj->reports, RPT_INFO, "Appended frame: %d", cfra); - printf("Appended frame %d\n", cfra); + if(mh->append_movie(&rd, rd.cfra, (int *)sj->dumprect, sj->dumpsx, sj->dumpsy, &sj->reports)) { + BKE_reportf(&sj->reports, RPT_INFO, "Appended frame: %d", rd.cfra); + printf("Appended frame %d\n", rd.cfra); } else break; } @@ -314,7 +313,7 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float char name[FILE_MAX]; int ok; - BKE_makepicstring(name, rd.pic, sj->bmain->name, cfra, rd.im_format.imtype, rd.scemode & R_EXTENSION, TRUE); + BKE_makepicstring(name, rd.pic, sj->bmain->name, rd.cfra, rd.im_format.imtype, rd.scemode & R_EXTENSION, TRUE); ibuf->rect= sj->dumprect; ok= BKE_write_ibuf(ibuf, name, &rd.im_format); @@ -338,7 +337,7 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float *do_update= 1; - cfra++; + rd.cfra++; } else diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index c0ccaeaea90..6927a78332f 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -1,6 +1,4 @@ /* - * $Id$ - * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 7b692f55965..da7f22b2030 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -233,7 +233,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) /* output sockets */ for(nsock= node->outputs.first; nsock; nsock= nsock->next) { - if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { + if(!nodeSocketIsHidden(nsock)) { nsock->locx= locx + node->width; nsock->locy= dy - NODE_DYS; dy-= NODE_DY; @@ -312,7 +312,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) /* input sockets */ for(nsock= node->inputs.first; nsock; nsock= nsock->next) { - if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { + if(!nodeSocketIsHidden(nsock)) { nsock->locx= locx; nsock->locy= dy - NODE_DYS; dy-= NODE_DY; @@ -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)) && (nsock->flag & SOCK_IN_USE)) + if(!nodeSocketIsHidden(nsock)) totin++; for(nsock= node->outputs.first; nsock; nsock= nsock->next) - if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (nsock->flag & SOCK_IN_USE)) + if(!nodeSocketIsHidden(nsock)) 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)) && (nsock->flag & SOCK_IN_USE)) { + if(!nodeSocketIsHidden(nsock)) { 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)) && (nsock->flag & SOCK_IN_USE)) { + if(!nodeSocketIsHidden(nsock)) { nsock->locx= node->totr.xmin + hiddenrad + (float)sin(rad)*hiddenrad; nsock->locy= node->totr.ymin + hiddenrad + (float)cos(rad)*hiddenrad; rad+= drad; @@ -713,7 +713,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN for(sock= node->inputs.first; sock; sock= sock->next) { bNodeSocketType *stype= ntreeGetSocketType(sock->type); - if(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) + if(nodeSocketIsHidden(sock)) continue; node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE); @@ -736,7 +736,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN RNA_pointer_create((ID*)ntree, &RNA_NodeSocket, sock, &sockptr); - if(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) + if(nodeSocketIsHidden(sock)) continue; node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE); @@ -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)) && (sock->flag & SOCK_IN_USE)) + if(!nodeSocketIsHidden(sock)) 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)) && (sock->flag & SOCK_IN_USE)) + if(!nodeSocketIsHidden(sock)) node_socket_circle_draw(snode->nodetree, sock, socket_size); } diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 87a56274035..20fb385efdd 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -1600,40 +1600,38 @@ void NODE_OT_resize(wmOperatorType *ot) /* ********************** hidden sockets ******************** */ -int node_has_hidden_sockets(bNode *node) +int node_has_hidden_sockets(bNode *node, short flag) { bNodeSocket *sock; for(sock= node->inputs.first; sock; sock= sock->next) - if(sock->flag & SOCK_HIDDEN) + if(sock->flag & flag) return 1; for(sock= node->outputs.first; sock; sock= sock->next) - if(sock->flag & SOCK_HIDDEN) + if(sock->flag & flag) return 1; return 0; } -/* note: call node_tree_verify_groups(snode->nodetree) after this - */ -void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set) +void node_set_hidden_sockets(SpaceNode *snode, bNode *node, short flag, int set) { bNodeSocket *sock; if(set==0) { for(sock= node->inputs.first; sock; sock= sock->next) - sock->flag &= ~SOCK_HIDDEN; + sock->flag &= ~flag; for(sock= node->outputs.first; sock; sock= sock->next) - sock->flag &= ~SOCK_HIDDEN; + sock->flag &= ~flag; } else { /* hide unused sockets */ for(sock= node->inputs.first; sock; sock= sock->next) { if(sock->link==NULL) - sock->flag |= SOCK_HIDDEN; + sock->flag |= flag; } for(sock= node->outputs.first; sock; sock= sock->next) { if(nodeCountSocketLinks(snode->edittree, sock)==0) - sock->flag |= SOCK_HIDDEN; + sock->flag |= flag; } } } @@ -1680,14 +1678,14 @@ static void node_link_viewer(SpaceNode *snode, bNode *tonode) /* find a socket after the previously connected socket */ for(sock=sock->next; sock; sock= sock->next) - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) + if(!nodeSocketIsHidden(sock)) break; } /* find a socket starting from the first socket */ if(!sock) { for(sock= tonode->outputs.first; sock; sock= sock->next) - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) + if(!nodeSocketIsHidden(sock)) break; } @@ -1805,7 +1803,7 @@ static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket ** if(in_out & SOCK_IN) { for(sock= node->inputs.first; sock; sock= sock->next) { - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { + if(!nodeSocketIsHidden(sock)) { if(BLI_in_rctf(&rect, sock->locx, sock->locy)) { if(node == visible_node(snode, &rect)) { *nodep= node; @@ -1818,7 +1816,7 @@ static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket ** } if(in_out & SOCK_OUT) { for(sock= node->outputs.first; sock; sock= sock->next) { - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { + if(!nodeSocketIsHidden(sock)) { if(BLI_in_rctf(&rect, sock->locx, sock->locy)) { if(node == visible_node(snode, &rect)) { *nodep= node; @@ -1836,7 +1834,7 @@ static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket ** */ if(in_out & SOCK_IN) { for(sock= snode->edittree->outputs.first; sock; sock= sock->next) { - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { + if(!nodeSocketIsHidden(sock)) { if(BLI_in_rctf(&rect, sock->locx, sock->locy)) { *nodep= NULL; /* NULL node pointer indicates group socket */ *sockp= sock; @@ -1847,7 +1845,7 @@ static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket ** } if(in_out & SOCK_OUT) { for(sock= snode->edittree->inputs.first; sock; sock= sock->next) { - if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) { + if(!nodeSocketIsHidden(sock)) { if(BLI_in_rctf(&rect, sock->locx, sock->locy)) { *nodep= NULL; /* NULL node pointer indicates group socket */ *sockp= sock; @@ -1930,13 +1928,12 @@ static int sort_nodes_locx(void *a, void *b) static int socket_is_available(bNodeTree *ntree, bNodeSocket *sock, int allow_used) { - if (sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) + if (nodeSocketIsHidden(sock)) + return 0; + + if (!allow_used && (sock->flag & SOCK_IN_USE)) return 0; - if (!allow_used) { - if (nodeCountSocketLinks(ntree, sock) > 0) - return 0; - } return 1; } @@ -2246,7 +2243,7 @@ static void node_remove_extra_links(SpaceNode *snode, bNodeSocket *tsock, bNodeL } if(sock) { tlink->tosock= sock; - sock->flag &= ~SOCK_HIDDEN; + sock->flag &= ~(SOCK_HIDDEN|SOCK_AUTO_HIDDEN); } else { nodeRemLink(snode->edittree, tlink); @@ -2644,26 +2641,26 @@ static bNodeSocket *socket_best_match(ListBase *sockets, int type) /* first, match type */ for(sock= sockets->first; sock; sock= sock->next) - if(!(sock->flag & SOCK_HIDDEN)) + if(!nodeSocketIsHidden(sock)) if(type == sock->type) return sock; /* then just use first unhidden socket */ for(sock= sockets->first; sock; sock= sock->next) - if(!(sock->flag & SOCK_HIDDEN)) + if(!nodeSocketIsHidden(sock)) return sock; /* OK, let's unhide proper one */ for(sock= sockets->first; sock; sock= sock->next) { if(type == sock->type) { - sock->flag &= ~SOCK_HIDDEN; + sock->flag &= ~(SOCK_HIDDEN|SOCK_AUTO_HIDDEN); return sock; } } /* just the first */ sock= sockets->first; - sock->flag &= ~SOCK_HIDDEN; + sock->flag &= ~(SOCK_HIDDEN|SOCK_AUTO_HIDDEN); return sockets->first; } @@ -3003,10 +3000,20 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag) if(toggle_flag== NODE_OPTIONS && (node->typeinfo->flag & NODE_OPTIONS)==0) continue; - if( (tot_eq && tot_neq) || tot_eq==0) + if( (tot_eq && tot_neq) || tot_eq==0) { node->flag |= toggle_flag; - else + + /* hide/unhide node also toggles unlinked socket display */ + if (toggle_flag== NODE_HIDDEN) + node_set_hidden_sockets(snode, node, SOCK_AUTO_HIDDEN, 1); + } + else { node->flag &= ~toggle_flag; + + /* hide/unhide node also toggles unlinked socket display */ + if (toggle_flag== NODE_HIDDEN) + node_set_hidden_sockets(snode, node, SOCK_AUTO_HIDDEN, 0); + } } } } @@ -3119,7 +3126,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op)) hidden = 0; for(node= snode->edittree->nodes.first; node; node= node->next) { if(node->flag & SELECT) { - if(node_has_hidden_sockets(node)) { + if(node_has_hidden_sockets(node, SOCK_HIDDEN)) { hidden= 1; break; } @@ -3128,7 +3135,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op)) for(node= snode->edittree->nodes.first; node; node= node->next) { if(node->flag & SELECT) { - node_set_hidden_sockets(snode, node, !hidden); + node_set_hidden_sockets(snode, node, SOCK_HIDDEN, !hidden); } } diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 9068493360e..186ad3768be 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -118,8 +118,8 @@ void snode_composite_job(const struct bContext *C, ScrArea *sa); bNode *node_tree_get_editgroup(bNodeTree *ntree); void node_tree_verify_groups(bNodeTree *nodetree); void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace); -int node_has_hidden_sockets(bNode *node); -void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set); +int node_has_hidden_sockets(bNode *node, short flag); +void node_set_hidden_sockets(SpaceNode *snode, bNode *node, short flag, int set); int node_render_changed_exec(bContext *, wmOperator *); void NODE_OT_duplicate(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index 6027a272270..a733d45c20b 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -1,6 +1,4 @@ /* - * $Id$ - * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 5fd3d3b45d6..56c2e0ee4d1 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2711,8 +2711,8 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op) calc_sequence(scene, seq_act); calc_sequence(scene, seq_other); - if(seq_act->sound) sound_add_scene_sound(scene, seq_act, seq_act->startdisp, seq_act->enddisp, seq_act->startofs + seq_act->anim_startofs); - if(seq_other->sound) sound_add_scene_sound(scene, seq_other, seq_other->startdisp, seq_other->enddisp, seq_other->startofs + seq_other->anim_startofs); + if(seq_act->sound) sound_add_scene_sound_defaults(scene, seq_act); + if(seq_other->sound) sound_add_scene_sound_defaults(scene, seq_other); WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index ad2a0da4510..6bc1b3acce6 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -768,8 +768,7 @@ static void bundle_midpoint(Scene *scene, Object *ob, float vec[3]) tracking= &clip->tracking; - if(scene->camera) - copy_m4_m4(cammat, scene->camera->obmat); + copy_m4_m4(cammat, ob->obmat); BKE_get_tracking_mat(scene, ob, mat); 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 919dc3f6403..99dd3987937 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/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index fb1d10b5491..93ea067cfb7 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -1120,7 +1120,11 @@ static void do_material_tex(GPUShadeInput *shi) // to inverting the bump map. Should this ever change // this negate must be removed. norfac = -hScale * mtex->norfac; - if(found_deriv_map) norfac /= sqrtf(ima_x*ima_y); + if(found_deriv_map) + { + float fVirtDim = sqrtf(fabsf(ima_x*mtex->size[0]*ima_y*mtex->size[1])); + norfac /= MAX2(fVirtDim, FLT_EPSILON); + } tnorfac = GPU_uniform(&norfac); diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 7f99fc3ffc7..996bfd35581 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -380,7 +380,7 @@ void IMB_color_to_bw(struct ImBuf *ibuf); /* converting pixel buffers */ void IMB_buffer_byte_from_float(unsigned char *rect_to, const float *rect_from, - int channels_from, int dither, int profile_to, int profile_from, int predivide, + int channels_from, float dither, int profile_to, int profile_from, int predivide, int width, int height, int stride_to, int stride_from); void IMB_buffer_float_from_byte(float *rect_to, const unsigned char *rect_from, int profile_to, int profile_from, int predivide, @@ -426,14 +426,6 @@ void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *col, flo * @attention defined in readimage.c * @deprecated Only here for backwards compatibility of the * @deprecated plugin system. - */ -struct ImBuf *IMB_loadiffmem(int *mem, int flags); - -/** - * - * @attention defined in readimage.c - * @deprecated Only here for backwards compatibility of the - * @deprecated plugin system. */ struct ImBuf *IMB_loadifffile(int file, int flags, const char *descr); diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index 45264fa862b..e6d09285685 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -768,8 +768,8 @@ static int ffmpeg_decode_video_frame(struct anim * anim) == AV_NOPTS_VALUE) ? -1 : (long long int)anim->pFrame->pkt_pts, (long long int)anim->next_pts); + break; } - break; } av_free_packet(&anim->next_packet); anim->next_packet.stream_index = -1; diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index 0dfc1852e29..034b5724ca6 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -123,7 +123,7 @@ MINLINE void float_to_byte_dither_v4(uchar b[4], const float f[4], float dither) /* float to byte pixels, output 4-channel RGBA */ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from, - int channels_from, int dither, int profile_to, int profile_from, int predivide, + int channels_from, float dither, int profile_to, int profile_from, int predivide, int width, int height, int stride_to, int stride_from) { float tmp[4]; diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 8fdbde60bab..c829d5be294 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -417,6 +417,7 @@ typedef struct bFollowTrackConstraint { int flag, pad; char object[24]; struct Object *camera; + struct Object *depth_ob; } bFollowTrackConstraint; /* Camera Solver constraints */ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 5fe9851738a..77fa03aeedc 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -313,13 +313,13 @@ typedef struct DisplaceModifierData { char uvlayer_name[32]; int uvlayer_tmp; int texmapping; - int pad10; /* end MappingInfoModifierData */ float strength; int direction; char defgrp_name[32]; float midlevel; + int pad; } DisplaceModifierData; /* DisplaceModifierData->direction */ @@ -336,7 +336,7 @@ enum { MOD_DISP_MAP_LOCAL, MOD_DISP_MAP_GLOBAL, MOD_DISP_MAP_OBJECT, - MOD_DISP_MAP_UV, + MOD_DISP_MAP_UV }; typedef struct UVProjectModifierData { @@ -401,13 +401,6 @@ typedef struct CastModifierData { short flag, type; } CastModifierData; -enum { - MOD_WAV_MAP_LOCAL, - MOD_WAV_MAP_GLOBAL, - MOD_WAV_MAP_OBJECT, - MOD_WAV_MAP_UV, -}; - /* WaveModifierData.flag */ #define MOD_WAVE_X (1<<1) #define MOD_WAVE_Y (1<<2) @@ -420,20 +413,22 @@ enum { typedef struct WaveModifierData { ModifierData modifier; - struct Object *objectcenter; - char defgrp_name[32]; + /* keep in sync with MappingInfoModifierData */ struct Tex *texture; struct Object *map_object; + char uvlayer_name[32]; + int uvlayer_tmp; + int texmapping; + /* end MappingInfoModifierData */ + + struct Object *objectcenter; + char defgrp_name[32]; short flag, pad; float startx, starty, height, width; float narrow, speed, damp, falloff; - int texmapping, uvlayer_tmp; - - char uvlayer_name[32]; - float timeoffs, lifetime; float pad1; } WaveModifierData; @@ -822,19 +817,17 @@ typedef struct WarpModifierData { char uvlayer_name[32]; int uvlayer_tmp; int texmapping; - int pad10; /* end MappingInfoModifierData */ - float strength; - struct Object *object_from; struct Object *object_to; struct CurveMapping *curfalloff; char defgrp_name[32]; /* optional vertexgroup name */ + float strength; float falloff_radius; char flag; /* not used yet */ char falloff_type; - char pad[2]; + char pad[6]; } WarpModifierData; #define MOD_WARP_VOLUME_PRESERVE 1 diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index aa9b43584fd..e2d612169e7 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -129,6 +129,8 @@ typedef struct bNodeSocket { #define SOCK_COLLAPSED 64 /* hide socket value, if it gets auto default */ #define SOCK_HIDE_VALUE 128 + /* socket hidden automatically, to distinguish from manually hidden */ +#define SOCK_AUTO_HIDDEN 256 typedef struct bNodePreview { unsigned char *rect; diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index bff1c214b4f..a6e3d16a5f5 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -615,9 +615,9 @@ extern StructRNA RNA_VoxelData; extern StructRNA RNA_VoxelDataTexture; extern StructRNA RNA_WarpModifier; extern StructRNA RNA_WaveModifier; -extern StructRNA RNA_WeightVGEditModifier; -extern StructRNA RNA_WeightVGMixModifier; -extern StructRNA RNA_WeightVGProximityModifier; +extern StructRNA RNA_VertexWeightEditModifier; +extern StructRNA RNA_VertexWeightMixModifier; +extern StructRNA RNA_VertexWeightProximityModifier; extern StructRNA RNA_Window; extern StructRNA RNA_WindowManager; extern StructRNA RNA_WipeSequence; diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index fb6e2544296..7daa92b1788 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -104,6 +104,8 @@ extern EnumPropertyItem property_type_items[]; extern EnumPropertyItem property_subtype_items[]; extern EnumPropertyItem property_unit_items[]; +extern EnumPropertyItem gameproperty_type_items[]; + extern EnumPropertyItem viewport_shade_items[]; extern EnumPropertyItem nodetree_type_items[]; diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index dc6b7e4d456..70bc8254476 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -43,9 +43,14 @@ #define RNA_VERSION_DATE "FIXME-RNA_VERSION_DATE" #ifdef _WIN32 -#ifndef snprintf -#define snprintf _snprintf +# ifndef snprintf +# define snprintf _snprintf +# endif #endif + +/* so we can use __func__ everywhere */ +#if defined(_MSC_VER) +# define __func__ __FUNCTION__ #endif /* Replace if different */ @@ -448,11 +453,9 @@ static int rna_enum_bitmask(PropertyRNA *prop) static int rna_color_quantize(PropertyRNA *prop, PropertyDefRNA *dp) { - if(prop->type == PROP_FLOAT && (prop->subtype==PROP_COLOR || prop->subtype==PROP_COLOR_GAMMA)) - if(strcmp(dp->dnatype, "float") != 0 && strcmp(dp->dnatype, "double") != 0) - return 1; - - return 0; + return ( (prop->type == PROP_FLOAT) && + (prop->subtype==PROP_COLOR || prop->subtype==PROP_COLOR_GAMMA) && + (IS_DNATYPE_FLOAT_COMPAT(dp->dnatype) == 0) ); } static const char *rna_function_string(void *func) @@ -484,7 +487,8 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr if(!manualfunc) { if(!dp->dnastructname || !dp->dnaname) { - fprintf(stderr, "rna_def_property_get_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s (0): %s.%s has no valid dna info.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; return NULL; } @@ -495,7 +499,8 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr if(prop->type == PROP_FLOAT) { if(IS_DNATYPE_FLOAT_COMPAT(dp->dnatype) == 0) { if(prop->subtype != PROP_COLOR_GAMMA) { /* colors are an exception. these get translated */ - fprintf(stderr, "rna_def_property_get_func1: %s.%s is a '%s' but wrapped as type '%s'.\n", srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type)); + fprintf(stderr, "%s (1): %s.%s is a '%s' but wrapped as type '%s'.\n", + __func__, srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type)); DefRNA.error= 1; return NULL; } @@ -503,7 +508,8 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr } else if(prop->type == PROP_INT || prop->type == PROP_BOOLEAN || prop->type == PROP_ENUM) { if(IS_DNATYPE_INT_COMPAT(dp->dnatype) == 0) { - fprintf(stderr, "rna_def_property_get_func2: %s.%s is a '%s' but wrapped as type '%s'.\n", srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type)); + fprintf(stderr, "%s (2): %s.%s is a '%s' but wrapped as type '%s'.\n", + __func__, srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type)); DefRNA.error= 1; return NULL; } @@ -724,7 +730,8 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr if(!manualfunc) { if(!dp->dnastructname || !dp->dnaname) { if(prop->flag & PROP_EDITABLE) { - fprintf(stderr, "rna_def_property_set_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s has no valid dna info.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; } return NULL; @@ -902,7 +909,8 @@ static char *rna_def_property_length_func(FILE *f, StructRNA *srna, PropertyRNA if(prop->type == PROP_STRING) { if(!manualfunc) { if(!dp->dnastructname || !dp->dnaname) { - fprintf(stderr, "rna_def_property_length_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s has no valid dna info.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; return NULL; } @@ -924,7 +932,8 @@ static char *rna_def_property_length_func(FILE *f, StructRNA *srna, PropertyRNA else if(prop->type == PROP_COLLECTION) { if(!manualfunc) { if(prop->type == PROP_COLLECTION && (!(dp->dnalengthname || dp->dnalengthfixed)|| !dp->dnaname)) { - fprintf(stderr, "rna_def_property_length_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s has no valid dna info.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; return NULL; } @@ -959,7 +968,8 @@ static char *rna_def_property_begin_func(FILE *f, StructRNA *srna, PropertyRNA * if(!manualfunc) { if(!dp->dnastructname || !dp->dnaname) { - fprintf(stderr, "rna_def_property_begin_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s has no valid dna info.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; return NULL; } @@ -1270,7 +1280,8 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp) pprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (const char*)pprop->get); pprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (const char*)pprop->set); if(!pprop->type) { - fprintf(stderr, "rna_def_property_funcs: %s.%s, pointer must have a struct type.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s, pointer must have a struct type.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; } break; @@ -1298,20 +1309,24 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp) if(!(prop->flag & PROP_IDPROPERTY)) { if(!cprop->begin) { - fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a begin function.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s, collection must have a begin function.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; } if(!cprop->next) { - fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a next function.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s, collection must have a next function.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; } if(!cprop->get) { - fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a get function.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s, collection must have a get function.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; } } if(!cprop->item_type) { - fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a struct type.\n", srna->identifier, prop->identifier); + fprintf(stderr, "%s: %s.%s, collection must have a struct type.\n", + __func__, srna->identifier, prop->identifier); DefRNA.error= 1; } break; @@ -2136,19 +2151,22 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr if(prop->flag & PROP_ENUM_FLAG) { if(eprop->defaultvalue & ~totflag) { - fprintf(stderr, "rna_generate_structs: %s%s.%s, enum default includes unused bits (%d).\n", srna->identifier, errnest, prop->identifier, eprop->defaultvalue & ~totflag); + fprintf(stderr, "%s: %s%s.%s, enum default includes unused bits (%d).\n", + __func__, srna->identifier, errnest, prop->identifier, eprop->defaultvalue & ~totflag); DefRNA.error= 1; } } else { if(!defaultfound) { - fprintf(stderr, "rna_generate_structs: %s%s.%s, enum default is not in items.\n", srna->identifier, errnest, prop->identifier); + fprintf(stderr, "%s: %s%s.%s, enum default is not in items.\n", + __func__, srna->identifier, errnest, prop->identifier); DefRNA.error= 1; } } } else { - fprintf(stderr, "rna_generate_structs: %s%s.%s, enum must have items defined.\n", srna->identifier, errnest, prop->identifier); + fprintf(stderr, "%s: %s%s.%s, enum must have items defined.\n", + __func__, srna->identifier, errnest, prop->identifier); DefRNA.error= 1; } break; @@ -2262,7 +2280,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr if(prop->arraydimension && prop->totarraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); else fprintf(f, "NULL\n"); break; - } + } case PROP_FLOAT: { FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop; fprintf(f, "\t%s, %s, %s, %s, %s, ", rna_function_string(fprop->get), rna_function_string(fprop->set), rna_function_string(fprop->getarray), rna_function_string(fprop->setarray), rna_function_string(fprop->range)); @@ -2276,7 +2294,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr if(prop->arraydimension && prop->totarraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); else fprintf(f, "NULL\n"); break; - } + } case PROP_STRING: { StringPropertyRNA *sprop= (StringPropertyRNA*)prop; fprintf(f, "\t%s, %s, %s, %d, ", rna_function_string(sprop->get), rna_function_string(sprop->length), rna_function_string(sprop->set), sprop->maxlength); @@ -2299,7 +2317,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr if(pprop->type) fprintf(f, "&RNA_%s\n", (const char*)pprop->type); else fprintf(f, "NULL\n"); break; - } + } case PROP_COLLECTION: { CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop; fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, ", rna_function_string(cprop->begin), rna_function_string(cprop->next), rna_function_string(cprop->end), rna_function_string(cprop->get), rna_function_string(cprop->length), rna_function_string(cprop->lookupint), rna_function_string(cprop->lookupstring), rna_function_string(cprop->assignint)); @@ -2421,7 +2439,8 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f) fprintf(f, "\t%s,\n", rna_function_string(srna->idproperties)); if(srna->reg && !srna->refine) { - fprintf(stderr, "rna_generate_struct: %s has a register function, must also have refine function.\n", srna->identifier); + fprintf(stderr, "%s: %s has a register function, must also have refine function.\n", + __func__, srna->identifier); DefRNA.error= 1; } @@ -2631,6 +2650,7 @@ static void rna_generate_header(BlenderRNA *brna, FILE *f) static const char *cpp_classes = "" "\n" "#include <string>\n" +"#include <string.h> /* for memcpy */\n" "\n" "namespace BL {\n" "\n" @@ -2756,6 +2776,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); @@ -2842,7 +2863,7 @@ static int rna_preprocess(const char *outfile) file = fopen(deffile, "w"); if(!file) { - printf ("Unable to open file: %s\n", deffile); + fprintf(stderr, "Unable to open file: %s\n", deffile); status = 1; } else { @@ -2870,7 +2891,7 @@ static int rna_preprocess(const char *outfile) file = fopen(deffile, "w"); if(!file) { - printf ("Unable to open file: %s\n", deffile); + fprintf(stderr, "Unable to open file: %s\n", deffile); status = 1; } else { @@ -2899,7 +2920,7 @@ static int rna_preprocess(const char *outfile) file = fopen(deffile, "w"); if(!file) { - printf ("Unable to open file: %s\n", deffile); + fprintf(stderr, "Unable to open file: %s\n", deffile); status = 1; } else { @@ -2929,18 +2950,18 @@ int main(int argc, char **argv) int totblock, return_status = 0; if(argc<2) { - printf("Usage: %s outdirectory/\n", argv[0]); + fprintf(stderr, "Usage: %s outdirectory/\n", argv[0]); return_status = 1; } else { - printf("Running makesrna, program versions %s\n", RNA_VERSION_DATE); + fprintf(stderr, "Running makesrna, program versions %s\n", RNA_VERSION_DATE); makesrna_path= argv[0]; return_status= rna_preprocess(argv[1]); } totblock= MEM_get_memory_blocks_in_use(); if(totblock!=0) { - printf("Error Totblock: %d\n",totblock); + fprintf(stderr, "Error Totblock: %d\n",totblock); MEM_set_error_callback(mem_error_cb); MEM_printmemlist(); } diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 6439d22e808..3258b8c3dcb 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -358,6 +358,34 @@ static void rna_Constraint_followTrack_camera_set(PointerRNA *ptr, PointerRNA va } } +static void rna_Constraint_followTrack_depthObject_set(PointerRNA *ptr, PointerRNA value) +{ + bConstraint *con= (bConstraint*)ptr->data; + bFollowTrackConstraint *data= (bFollowTrackConstraint*)con->data; + Object *ob= (Object*)value.data; + + if (ob) { + if (ob->type == OB_MESH && ob != (Object*)ptr->id.data) { + data->depth_ob= ob; + } + } else { + data->depth_ob= NULL; + } +} + +static int rna_Constraint_followTrack_depthObject_poll(PointerRNA *ptr, PointerRNA value) +{ + Object *ob= (Object*)value.data; + + if(ob) { + if (ob->type == OB_MESH && ob != (Object*)ptr->id.data) { + return 1; + } + } + + return 0; +} + static void rna_Constraint_objectSolver_camera_set(PointerRNA *ptr, PointerRNA value) { bConstraint *con= (bConstraint*)ptr->data; @@ -2126,6 +2154,14 @@ static void rna_def_constraint_follow_track(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); RNA_def_property_pointer_funcs(prop, NULL, "rna_Constraint_followTrack_camera_set", NULL, "rna_Constraint_cameraObject_poll"); + + /* depth object */ + prop= RNA_def_property(srna, "depth_object", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "depth_ob"); + RNA_def_property_ui_text(prop, "Depth Object", "Object used to define depth in camera space by projecting onto surface of this object"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_Constraint_followTrack_depthObject_set", NULL, "rna_Constraint_followTrack_depthObject_poll"); } static void rna_def_constraint_camera_solver(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index caf43793996..53944f7ec5c 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -1628,6 +1628,7 @@ void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, const char *propname) { PropertyDefRNA *dp; + FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop; StructRNA *srna= DefRNA.laststruct; if(!DefRNA.preprocess) { @@ -1652,6 +1653,11 @@ void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, cons } } } + + if(dp->dnatype && strcmp(dp->dnatype, "char") == 0) { + fprop->hardmin= fprop->softmin= 0.0f; + fprop->hardmax= fprop->softmax= 1.0f; + } } rna_def_property_sdna(prop, structname, propname); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 9474c572d88..3a7d453fa79 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -452,12 +452,6 @@ static void RNA_WarpModifier_vgroup_set(PointerRNA *ptr, const char *value) rna_object_vgroup_name_set(ptr, value, tmd->defgrp_name, sizeof(tmd->defgrp_name)); } -static void rna_WaveModifier_uvlayer_set(PointerRNA *ptr, const char *value) -{ - WaveModifierData *wmd= (WaveModifierData*)ptr->data; - rna_object_uvlayer_name_set(ptr, value, wmd->uvlayer_name, sizeof(wmd->uvlayer_name)); -} - static void rna_WeightVGModifier_mask_uvlayer_set(PointerRNA *ptr, const char *value) { ModifierData *md = (ModifierData*)ptr->data; @@ -1125,13 +1119,6 @@ static void rna_def_modifier_wave(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem prop_texture_coordinates_items[] = { - {MOD_WAV_MAP_LOCAL, "LOCAL", 0, "Local", ""}, - {MOD_WAV_MAP_GLOBAL, "GLOBAL", 0, "Global", ""}, - {MOD_WAV_MAP_OBJECT, "OBJECT", 0, "Object", ""}, - {MOD_WAV_MAP_UV, "MAP_UV", 0, "UV", ""}, - {0, NULL, 0, NULL, NULL}}; - srna= RNA_def_struct(brna, "WaveModifier", "Modifier"); RNA_def_struct_ui_text(srna, "Wave Modifier", "Wave effect modifier"); RNA_def_struct_sdna(srna, "WaveModifierData"); @@ -1223,29 +1210,6 @@ static void rna_def_modifier_wave(BlenderRNA *brna) RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WaveModifier_vgroup_set"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); - prop= RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE); - RNA_def_property_ui_text(prop, "Texture", "Texture for modulating the wave"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, 0, "rna_Modifier_update"); - - prop= RNA_def_property(srna, "texture_coords", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "texmapping"); - RNA_def_property_enum_items(prop, prop_texture_coordinates_items); - RNA_def_property_ui_text(prop, "Texture Coordinates", "Texture coordinates used for modulating input"); - RNA_def_property_update(prop, 0, "rna_Modifier_update"); - - prop= RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "uvlayer_name"); - RNA_def_property_ui_text(prop, "UV Map", "UV map name"); - RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WaveModifier_uvlayer_set"); - RNA_def_property_update(prop, 0, "rna_Modifier_update"); - - prop= RNA_def_property(srna, "texture_coords_object", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "map_object"); - RNA_def_property_ui_text(prop, "Texture Coordinates Object", ""); - RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK); - RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); - prop= RNA_def_property(srna, "speed", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); RNA_def_property_ui_range(prop, -1, 1, 10, 2); @@ -1270,6 +1234,8 @@ static void rna_def_modifier_wave(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0, 10, 10, 2); RNA_def_property_ui_text(prop, "Narrowness", "Distance between the top and the base of a wave, the higher the value, the more narrow the wave"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + rna_def_modifier_generic_map_info(srna); } static void rna_def_modifier_armature(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_property.c b/source/blender/makesrna/intern/rna_property.c index e8ef61b6d74..dfdc175d18b 100644 --- a/source/blender/makesrna/intern/rna_property.c +++ b/source/blender/makesrna/intern/rna_property.c @@ -35,6 +35,15 @@ #include "WM_types.h" +EnumPropertyItem gameproperty_type_items[] ={ + {GPROP_BOOL, "BOOL", 0, "Boolean", "Boolean Property"}, + {GPROP_INT, "INT", 0, "Integer", "Integer Property"}, + {GPROP_FLOAT, "FLOAT", 0, "Float", "Floating-Point Property"}, + {GPROP_STRING, "STRING", 0, "String", "String Property"}, + {GPROP_TIME, "TIMER", 0, "Timer", "Timer Property"}, + {0, NULL, 0, NULL, NULL}}; + + #ifdef RNA_RUNTIME #include "BKE_property.h" @@ -98,14 +107,6 @@ void RNA_def_gameproperty(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem gameproperty_type_items[] ={ - {GPROP_BOOL, "BOOL", 0, "Boolean", "Boolean Property"}, - {GPROP_INT, "INT", 0, "Integer", "Integer Property"}, - {GPROP_FLOAT, "FLOAT", 0, "Float", "Floating-Point Property"}, - {GPROP_STRING, "STRING", 0, "String", "String Property"}, - {GPROP_TIME, "TIMER", 0, "Timer", "Timer Property"}, - {0, NULL, 0, NULL, NULL}}; - /* Base Struct for GameProperty */ srna= RNA_def_struct(brna, "GameProperty", NULL); RNA_def_struct_ui_text(srna , "Game Property", "Game engine user defined object property"); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 72cab2ce104..0d7a7195b44 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -3883,14 +3883,14 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "fg_stamp"); RNA_def_property_array(prop, 4); RNA_def_property_range(prop,0.0,1.0); - RNA_def_property_ui_text(prop, "Stamp Text Color", "Color to use for stamp text"); + RNA_def_property_ui_text(prop, "Text Color", "Color to use for stamp text"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); prop= RNA_def_property(srna, "stamp_background", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "bg_stamp"); RNA_def_property_array(prop, 4); RNA_def_property_range(prop,0.0,1.0); - RNA_def_property_ui_text(prop, "Stamp Background", "Color to use behind stamp text"); + RNA_def_property_ui_text(prop, "Background", "Color to use behind stamp text"); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); /* sequencer draw options */ diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c index c8792ef30f3..fa1f6c72430 100644 --- a/source/blender/makesrna/intern/rna_screen.c +++ b/source/blender/makesrna/intern/rna_screen.c @@ -54,6 +54,7 @@ EnumPropertyItem region_type_items[] = { #ifdef RNA_RUNTIME +#include "BKE_global.h" static void rna_Screen_scene_set(PointerRNA *ptr, PointerRNA value) { @@ -62,7 +63,6 @@ static void rna_Screen_scene_set(PointerRNA *ptr, PointerRNA value) if(value.data == NULL) return; - /* exception: can't set screens inside of area/region handers */ sc->newscene= value.data; } @@ -70,10 +70,14 @@ static void rna_Screen_scene_update(bContext *C, PointerRNA *ptr) { bScreen *sc= (bScreen*)ptr->data; - /* exception: can't set screens inside of area/region handers, and must - use context so notifier gets to the right window */ + /* exception: must use context so notifier gets to the right window */ if(sc->newscene) { + ED_screen_set_scene(C, sc->newscene); WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, sc->newscene); + + if(G.f & G_DEBUG) + printf("scene set %p\n", sc->newscene); + sc->newscene= NULL; } } diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index bbec6484c5f..c29d655feb2 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -305,7 +305,14 @@ static void rna_trackingObject_tracks_begin(CollectionPropertyIterator *iter, Po { MovieTrackingObject *object= (MovieTrackingObject* )ptr->data; - rna_iterator_listbase_begin(iter, &object->tracks, NULL); + if(object->flag&TRACKING_OBJECT_CAMERA) { + MovieClip *clip= (MovieClip*)ptr->id.data; + + rna_iterator_listbase_begin(iter, &clip->tracking.tracks, NULL); + } + else { + rna_iterator_listbase_begin(iter, &object->tracks, NULL); + } } static PointerRNA rna_tracking_active_object_get(PointerRNA *ptr) diff --git a/source/blender/modifiers/SConscript b/source/blender/modifiers/SConscript index ce413faec86..03fcee399bd 100644 --- a/source/blender/modifiers/SConscript +++ b/source/blender/modifiers/SConscript @@ -14,10 +14,10 @@ incs += ' ' + env['BF_ZLIB_INC'] defs = [] if env ['WITH_BF_BOOLEAN']: - incs += ' #/intern/dualcon' defs.append('WITH_MOD_BOOLEAN') if env['WITH_BF_REMESH']: + incs += ' #/intern/dualcon' defs.append('WITH_MOD_REMESH') if env ['WITH_BF_DECIMATE']: diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c index c698985efc3..bc67237fb40 100644 --- a/source/blender/modifiers/intern/MOD_remesh.c +++ b/source/blender/modifiers/intern/MOD_remesh.c @@ -1,27 +1,24 @@ /* -* $Id$ -* -* ***** BEGIN GPL LICENSE BLOCK ***** -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -* -* The Original Code is Copyright (C) 2011 by Nicholas Bishop. -* -* ***** END GPL LICENSE BLOCK ***** -* -*/ + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2011 by Nicholas Bishop. + * + * ***** END GPL LICENSE BLOCK ***** + */ /** \file blender/modifiers/intern/MOD_remesh.c * \ingroup modifiers @@ -152,7 +149,7 @@ static DerivedMesh *applyModifier(ModifierData *md, DualConInput input; DerivedMesh *result; DualConFlags flags = 0; - DualConMode mode; + DualConMode mode = 0; rmd = (RemeshModifierData*)md; diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index cc7a5e54fbd..5be7eb6af3d 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -107,36 +107,19 @@ void get_texture_coords(MappingInfoModifierData *dmd, Object *ob, /* verts are given the UV from the first face that uses them */ for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) { - if(!done[mf->v1]) { - texco[mf->v1][0] = tf->uv[0][0]; - texco[mf->v1][1] = tf->uv[0][1]; - texco[mf->v1][2] = 0; - done[mf->v1] = 1; - } - if(!done[mf->v2]) { - texco[mf->v2][0] = tf->uv[1][0]; - texco[mf->v2][1] = tf->uv[1][1]; - texco[mf->v2][2] = 0; - done[mf->v2] = 1; - } - if(!done[mf->v3]) { - texco[mf->v3][0] = tf->uv[2][0]; - texco[mf->v3][1] = tf->uv[2][1]; - texco[mf->v3][2] = 0; - done[mf->v3] = 1; - } - if(!done[mf->v4]) { - texco[mf->v4][0] = tf->uv[3][0]; - texco[mf->v4][1] = tf->uv[3][1]; - texco[mf->v4][2] = 0; - done[mf->v4] = 1; - } - } + unsigned int fidx= mf->v4 ? 3:2; + + do { + unsigned int vidx = *(&mf->v1 + fidx); + + if (done[vidx] == 0) { + /* remap UVs from [0, 1] to [-1, 1] */ + texco[vidx][0] = (tf->uv[fidx][0] * 2.0f) - 1.0f; + texco[vidx][1] = (tf->uv[fidx][1] * 2.0f) - 1.0f; + done[vidx] = 1; + } - /* remap UVs from [0, 1] to [-1, 1] */ - for(i = 0; i < numVerts; ++i) { - texco[i][0] = texco[i][0] * 2 - 1; - texco[i][1] = texco[i][1] * 2 - 1; + } while (fidx--); } MEM_freeN(done); diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index 38c2073b6a5..c89fdb3a0ee 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -287,41 +287,34 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, if(override_image || !image || tface->tpage == image) { if(num_projectors == 1) { if(projectors[0].uci) { - 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->v4) - project_from_camera(tface->uv[3], coords[mf->v4], projectors[0].uci); + unsigned int fidx= mf->v4 ? 3:2; + do { + unsigned int vidx= *(&mf->v1 + fidx); + project_from_camera(tface->uv[fidx], coords[vidx], projectors[0].uci); + } while (fidx--); } else { /* apply transformed coords as UVs */ - copy_v2_v2(tface->uv[0], coords[mf->v1]); - copy_v2_v2(tface->uv[1], coords[mf->v2]); - copy_v2_v2(tface->uv[2], coords[mf->v3]); - if (mf->v4) { - copy_v2_v2(tface->uv[3], coords[mf->v4]); - } + unsigned int fidx= mf->v4 ? 3:2; + do { + unsigned int vidx= *(&mf->v1 + fidx); + copy_v2_v2(tface->uv[fidx], coords[vidx]); + } while (fidx--); } } else { /* multiple projectors, select the closest to face normal * direction */ - float co1[3], co2[3], co3[3], co4[3]; float face_no[3]; int j; Projector *best_projector; float best_dot; - copy_v3_v3(co1, coords[mf->v1]); - copy_v3_v3(co2, coords[mf->v2]); - copy_v3_v3(co3, coords[mf->v3]); - /* get the untransformed face normal */ if(mf->v4) { - copy_v3_v3(co4, coords[mf->v4]); - normal_quad_v3(face_no, co1, co2, co3, co4); + normal_quad_v3(face_no, coords[mf->v1], coords[mf->v2], coords[mf->v3], coords[mf->v4]); } else { - normal_tri_v3(face_no, co1, co2, co3); + normal_tri_v3(face_no, coords[mf->v1], coords[mf->v2], coords[mf->v3]); } /* find the projector which the face points at most directly @@ -340,26 +333,23 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, } if(best_projector->uci) { - 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->v4) - project_from_camera(tface->uv[3], coords[mf->v4], best_projector->uci); + unsigned int fidx= mf->v4 ? 3:2; + do { + unsigned int vidx= *(&mf->v1 + fidx); + project_from_camera(tface->uv[fidx], coords[vidx], best_projector->uci); + } while (fidx--); } else { - mul_project_m4_v3(best_projector->projmat, co1); - mul_project_m4_v3(best_projector->projmat, co2); - mul_project_m4_v3(best_projector->projmat, co3); - if(mf->v4) - mul_project_m4_v3(best_projector->projmat, co4); + unsigned int fidx= mf->v4 ? 3:2; + do { + unsigned int vidx= *(&mf->v1 + fidx); + float tco[3]; - /* apply transformed coords as UVs */ - copy_v2_v2(tface->uv[0], co1); - copy_v2_v2(tface->uv[1], co2); - copy_v2_v2(tface->uv[2], co3); - if (mf->v4) { - copy_v2_v2(tface->uv[3], co4); - } + copy_v3_v3(tco, coords[vidx]); + mul_project_m4_v3(best_projector->projmat, tco); + copy_v2_v2(tface->uv[fidx], tco); + + } while (fidx--); } } } diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c index 398a078bf38..e83aa9e3fb9 100644 --- a/source/blender/modifiers/intern/MOD_wave.c +++ b/source/blender/modifiers/intern/MOD_wave.c @@ -73,7 +73,7 @@ static void initData(ModifierData *md) wmd->lifetime= 0.0f; wmd->damp= 10.0f; wmd->falloff= 0.0f; - wmd->texmapping = MOD_WAV_MAP_LOCAL; + wmd->texmapping = MOD_DISP_MAP_LOCAL; wmd->defgrp_name[0] = 0; } @@ -160,7 +160,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) /* ask for UV coordinates if we need them */ - if(wmd->texture && wmd->texmapping == MOD_WAV_MAP_UV) + if(wmd->texture && wmd->texmapping == MOD_DISP_MAP_UV) dataMask |= CD_MASK_MTFACE; /* ask for vertexgroups if we need them */ @@ -170,91 +170,6 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) return dataMask; } -static void wavemod_get_texture_coords(WaveModifierData *wmd, Object *ob, - DerivedMesh *dm, - float (*co)[3], float (*texco)[3], - int numVerts) -{ - int i; - int texmapping = wmd->texmapping; - - if(texmapping == MOD_WAV_MAP_OBJECT) { - if(wmd->map_object) - invert_m4_m4(wmd->map_object->imat, wmd->map_object->obmat); - else /* if there is no map object, default to local */ - texmapping = MOD_WAV_MAP_LOCAL; - } - - /* UVs need special handling, since they come from faces */ - if(texmapping == MOD_WAV_MAP_UV) { - if(CustomData_has_layer(&dm->faceData, CD_MTFACE)) { - MFace *mface = dm->getFaceArray(dm); - MFace *mf; - char *done = MEM_callocN(sizeof(*done) * numVerts, - "get_texture_coords done"); - int numFaces = dm->getNumFaces(dm); - char uvname[32]; - MTFace *tf; - - CustomData_validate_layer_name(&dm->faceData, CD_MTFACE, wmd->uvlayer_name, uvname); - tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname); - - /* verts are given the UV from the first face that uses them */ - for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) { - if(!done[mf->v1]) { - texco[mf->v1][0] = tf->uv[0][0]; - texco[mf->v1][1] = tf->uv[0][1]; - texco[mf->v1][2] = 0; - done[mf->v1] = 1; - } - if(!done[mf->v2]) { - texco[mf->v2][0] = tf->uv[1][0]; - texco[mf->v2][1] = tf->uv[1][1]; - texco[mf->v2][2] = 0; - done[mf->v2] = 1; - } - if(!done[mf->v3]) { - texco[mf->v3][0] = tf->uv[2][0]; - texco[mf->v3][1] = tf->uv[2][1]; - texco[mf->v3][2] = 0; - done[mf->v3] = 1; - } - if(!done[mf->v4]) { - texco[mf->v4][0] = tf->uv[3][0]; - texco[mf->v4][1] = tf->uv[3][1]; - texco[mf->v4][2] = 0; - done[mf->v4] = 1; - } - } - - /* remap UVs from [0, 1] to [-1, 1] */ - for(i = 0; i < numVerts; ++i) { - texco[i][0] = texco[i][0] * 2 - 1; - texco[i][1] = texco[i][1] * 2 - 1; - } - - MEM_freeN(done); - return; - } else /* if there are no UVs, default to local */ - texmapping = MOD_WAV_MAP_LOCAL; - } - - for(i = 0; i < numVerts; ++i, ++co, ++texco) { - switch(texmapping) { - case MOD_WAV_MAP_LOCAL: - copy_v3_v3(*texco, *co); - break; - case MOD_WAV_MAP_GLOBAL: - mul_v3_m4v3(*texco, ob->obmat, *co); - break; - case MOD_WAV_MAP_OBJECT: - mul_v3_m4v3(*texco, ob->obmat, *co); - mul_m4_v3(wmd->map_object->imat, *texco); - break; - } - } -} - static void waveModifier_do(WaveModifierData *md, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) @@ -305,7 +220,7 @@ static void waveModifier_do(WaveModifierData *md, if(wmd->texture) { tex_co = MEM_mallocN(sizeof(*tex_co) * numVerts, "waveModifier_do tex_co"); - wavemod_get_texture_coords(wmd, ob, dm, vertexCos, tex_co, numVerts); + get_texture_coords((MappingInfoModifierData *)wmd, ob, dm, vertexCos, tex_co, numVerts); } if(lifefac != 0.0f) { diff --git a/source/blender/nodes/composite/node_composite_util.c b/source/blender/nodes/composite/node_composite_util.c index 72037f232ad..c99cae7ed7b 100644 --- a/source/blender/nodes/composite/node_composite_util.c +++ b/source/blender/nodes/composite/node_composite_util.c @@ -427,6 +427,18 @@ static float *compbuf_get_pixel(CompBuf *cbuf, float *defcol, float *use, int x, /* **************************************************** */ +static CompBuf *composit_check_compbuf(CompBuf *cbuf, int type, CompBuf *outbuf) +{ + /* check type */ + CompBuf *dbuf= typecheck_compbuf(cbuf, type); + + /* if same as output and translated, duplicate so pixels don't interfere */ + if(dbuf == outbuf && !dbuf->rect_procedural && (dbuf->xof || dbuf->yof)) + dbuf= dupalloc_compbuf(dbuf); + + return dbuf; +} + /* Pixel-to-Pixel operation, 1 Image in, 1 out */ void composit1_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, float *src_col, void (*func)(bNode *, float *, float *), @@ -437,7 +449,7 @@ void composit1_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, floa float color[4]; /* local color if compbuf is procedural */ int xrad, yrad, x, y; - src_use= typecheck_compbuf(src_buf, src_type); + src_use= composit_check_compbuf(src_buf, src_type, out); xrad= out->xrad; yrad= out->yrad; @@ -463,8 +475,8 @@ void composit2_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, floa float color[4]; /* local color if compbuf is procedural */ int xrad, yrad, x, y; - src_use= typecheck_compbuf(src_buf, src_type); - fac_use= typecheck_compbuf(fac_buf, fac_type); + src_use= composit_check_compbuf(src_buf, src_type, out); + fac_use= composit_check_compbuf(fac_buf, fac_type, out); xrad= out->xrad; yrad= out->yrad; @@ -493,9 +505,9 @@ void composit3_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_buf, flo float color[4]; /* local color if compbuf is procedural */ int xrad, yrad, x, y; - src1_use= typecheck_compbuf(src1_buf, src1_type); - src2_use= typecheck_compbuf(src2_buf, src2_type); - fac_use= typecheck_compbuf(fac_buf, fac_type); + src1_use= composit_check_compbuf(src1_buf, src1_type, out); + src2_use= composit_check_compbuf(src2_buf, src2_type, out); + fac_use= composit_check_compbuf(fac_buf, fac_type, out); xrad= out->xrad; yrad= out->yrad; @@ -529,10 +541,10 @@ void composit4_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_buf, flo float color[4]; /* local color if compbuf is procedural */ int xrad, yrad, x, y; - src1_use= typecheck_compbuf(src1_buf, src1_type); - src2_use= typecheck_compbuf(src2_buf, src2_type); - fac1_use= typecheck_compbuf(fac1_buf, fac1_type); - fac2_use= typecheck_compbuf(fac2_buf, fac2_type); + src1_use= composit_check_compbuf(src1_buf, src1_type, out); + src2_use= composit_check_compbuf(src2_buf, src2_type, out); + fac1_use= composit_check_compbuf(fac1_buf, fac1_type, out); + fac2_use= composit_check_compbuf(fac2_buf, fac2_type, out); xrad= out->xrad; yrad= out->yrad; diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index 5ad84da45d2..fdce1f92948 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -609,7 +609,7 @@ void node_group_expose_all_sockets(bNodeTree *ngroup) for (node=ngroup->nodes.first; node; node=node->next) { for (sock=node->inputs.first; sock; sock=sock->next) { - if (!sock->link && !(sock->flag & SOCK_HIDDEN)) { + if (!sock->link && !nodeSocketIsHidden(sock)) { gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_IN); /* initialize the default value. */ @@ -619,7 +619,7 @@ void node_group_expose_all_sockets(bNodeTree *ngroup) } } for (sock=node->outputs.first; sock; sock=sock->next) { - if (nodeCountSocketLinks(ngroup, sock)==0 && !(sock->flag & SOCK_HIDDEN)) { + if (nodeCountSocketLinks(ngroup, sock)==0 && !nodeSocketIsHidden(sock)) { gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_OUT); /* initialize the default value. */ diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c index 8b8afc3d846..1bfb986fdde 100644 --- a/source/blender/nodes/shader/node_shader_util.c +++ b/source/blender/nodes/shader/node_shader_util.c @@ -184,7 +184,7 @@ void nodeShaderSynchronizeID(bNode *node, int copyto) /* hrmf, case in loop isnt super fast, but we dont edit 100s of material at same time either! */ for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) { - if(!(sock->flag & SOCK_HIDDEN)) { + if(!nodeSocketIsHidden(sock)) { if(copyto) { switch(a) { case MAT_IN_COLOR: diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index d911fcb99b1..9dfbe64e905 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -4073,7 +4073,6 @@ static PyObject *pyrna_struct_as_pointer(BPy_StructRNA *self) return PyLong_FromVoidPtr(self->ptr.data); } -/* TODO, get (string, lib) pair */ PyDoc_STRVAR(pyrna_prop_collection_get_doc, ".. method:: get(key, default=None)\n" "\n" @@ -4120,6 +4119,51 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args return Py_INCREF(def), def; } +PyDoc_STRVAR(pyrna_prop_collection_find_doc, +".. method:: find(key)\n" +"\n" +" Returns the index of a key in a collection or -1 when not found\n" +" (matches pythons string find function of the same name).\n" +"\n" +" :arg key: The identifier for the collection member.\n" +" :type key: string\n" +" :return: index of the key.\n" +" :rtype: int\n" +); +static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key_ob) +{ + Py_ssize_t key_len_ssize_t; + const char *key = _PyUnicode_AsStringAndSize(key_ob, &key_len_ssize_t); + const int key_len = (int)key_len_ssize_t; /* comare with same type */ + + char name[256], *nameptr; + int namelen; + int i = 0; + int index = -1; + + PYRNA_PROP_CHECK_OBJ(self); + + RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) { + nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); + + if (nameptr) { + if ((key_len == namelen) && memcmp(nameptr, key, key_len) == 0) { + index = i; + break; + } + + if (name != nameptr) { + MEM_freeN(nameptr); + } + } + + i++; + } + RNA_PROP_END; + + return PyLong_FromSsize_t(index); +} + static void foreach_attr_type( BPy_PropertyRNA *self, const char *attr, /* values to assign */ RawPropertyType *raw_type, int *attr_tot, int *attr_signed) @@ -4503,6 +4547,7 @@ static struct PyMethodDef pyrna_prop_collection_methods[] = { {"values", (PyCFunction)pyrna_prop_collection_values, METH_NOARGS, pyrna_prop_collection_values_doc}, {"get", (PyCFunction)pyrna_prop_collection_get, METH_VARARGS, pyrna_prop_collection_get_doc}, + {"find", (PyCFunction)pyrna_prop_collection_find, METH_O, pyrna_prop_collection_find_doc}, {NULL, NULL, 0, NULL} }; diff --git a/source/blender/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/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c index e137c7846bb..5848e6e8c75 100644 --- a/source/blender/python/mathutils/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -334,18 +334,18 @@ PyDoc_STRVAR(Vector_normalize_doc, "\n" " Normalize the vector, making the length of the vector always 1.0.\n" "\n" -" .. warning:: Normalizing a vector where all values are zero results\n" -" in all axis having a nan value (not a number).\n" +" .. warning:: Normalizing a vector where all values are zero has no effect.\n" "\n" " .. note:: Normalize works for vectors of all sizes,\n" " however 4D Vectors w axis is left untouched.\n" ); static PyObject *Vector_normalize(VectorObject *self) { + int size = (self->size == 4 ? 3 : self->size); if (BaseMath_ReadCallback(self) == -1) return NULL; - normalize_vn(self->vec, self->size); + normalize_vn(self->vec, size); (void)BaseMath_WriteCallback(self); Py_RETURN_NONE; @@ -1480,10 +1480,10 @@ static PyObject *Vector_isub(PyObject *v1, PyObject *v2) mulplication*/ -/* COLUMN VECTOR Multiplication (Vector X Matrix) - * [a] * [1][4][7] - * [b] * [2][5][8] - * [c] * [3][6][9] +/* COLUMN VECTOR Multiplication (Matrix X Vector) + * [1][4][7] [a] + * [2][5][8] * [b] + * [3][6][9] [c] * * note: vector/matrix multiplication IS NOT COMMUTATIVE!!!! * note: assume read callbacks have been done first. @@ -1500,8 +1500,8 @@ int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec, else { PyErr_SetString(PyExc_TypeError, "matrix * vector: " - "matrix.row_size and len(vector) must be the same, " - "except for 3D vector * 4x4 matrix."); + "len(matrix.col) and len(vector) must be the same, " + "except for 4x4 matrix * 3D vector."); return -1; } } diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index 9982eb86460..4ca8f6213bb 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -67,6 +67,7 @@ set(SRC intern/source/pointdensity.c intern/source/rayshade.c intern/source/rendercore.c + intern/source/render_result.c intern/source/render_texture.c intern/source/renderdatabase.c intern/source/shadbuf.c @@ -97,6 +98,7 @@ set(SRC intern/include/rayintersection.h intern/include/raycounter.h intern/include/render_types.h + intern/include/render_result.h intern/include/rendercore.h intern/include/renderdatabase.h intern/include/renderpipeline.h diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index ba211ba396d..1016a242341 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -182,9 +182,6 @@ float *RE_RenderLayerGetPass(struct RenderLayer *rl, int passtype); /* obligatory initialize call, disprect is optional */ void RE_InitState (struct Render *re, struct Render *source, struct RenderData *rd, struct SceneRenderLayer *srl, int winx, int winy, rcti *disprect); -/* use this to change disprect of active render */ -void RE_SetDispRect (struct Render *re, rcti *disprect); - /* set up the viewplane/perspective matrix, three choices */ struct Object *RE_GetCamera(struct Render *re); /* return camera override if set */ void RE_SetCamera(struct Render *re, struct Object *camera); diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h new file mode 100644 index 00000000000..93cbc6fe9c9 --- /dev/null +++ b/source/blender/render/intern/include/render_result.h @@ -0,0 +1,94 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/render/intern/include/render_result.h + * \ingroup render + */ + +#ifndef RENDER_RESULT_H +#define RENDER_RESULT_H + +#define PASS_VECTOR_MAX 10000.0f + +#define RR_USE_MEM 0 +#define RR_USE_EXR 1 + +struct ImBuf; +struct ListBase; +struct Render; +struct RenderData; +struct RenderLayer; +struct RenderResult; +struct Scene; +struct rcti; + +/* New */ + +struct RenderResult *render_result_new(struct Render *re, + struct rcti *partrct, int crop, int savebuffers); +struct RenderResult *render_result_new_full_sample(struct Render *re, + struct ListBase *lb, struct rcti *partrct, int crop, int savebuffers); + +struct RenderResult *render_result_new_from_exr(void *exrhandle, int rectx, int recty); + +/* Merge */ + +void render_result_merge(struct RenderResult *rr, struct RenderResult *rrpart); + +/* Free */ + +void render_result_free(struct RenderResult *rr); +void render_result_free_list(struct ListBase *lb, struct RenderResult *rr); + +/* Single Layer Render */ + +void render_result_single_layer_begin(struct Render *re); +void render_result_single_layer_end(struct Render *re); + +/* EXR Tile File Render */ + +void render_result_exr_file_begin(struct Render *re); +void render_result_exr_file_end(struct Render *re); + +void render_result_exr_file_merge(struct RenderResult *rr, struct RenderResult *rrpart); + +void render_result_exr_file_path(struct Scene *scene, int sample, char *filepath); +int render_result_exr_file_read(struct Render *re, int sample); +int render_result_exr_file_read_path(struct RenderResult *rr, const char *filepath); + +/* Combined Pixel Rect */ + +struct ImBuf *render_result_rect_to_ibuf(struct RenderResult *rr, struct RenderData *rd); +void render_result_rect_from_ibuf(struct RenderResult *rr, struct RenderData *rd, + struct ImBuf *ibuf); + +void render_result_rect_fill_zero(struct RenderResult *rr); +void render_result_rect_get_pixels(struct RenderResult *rr, struct RenderData *rd, + unsigned int *rect, int rectx, int recty); + +#endif /* RENDER_RESULT_H */ + diff --git a/source/blender/render/intern/include/renderpipeline.h b/source/blender/render/intern/include/renderpipeline.h index fc46ea83309..9a87cf84012 100644 --- a/source/blender/render/intern/include/renderpipeline.h +++ b/source/blender/render/intern/include/renderpipeline.h @@ -33,22 +33,12 @@ #ifndef PIPELINE_H #define PIPELINE_H -struct ListBase; struct Render; -struct RenderResult; struct RenderLayer; -struct rcti; +struct RenderResult; struct RenderLayer *render_get_active_layer(struct Render *re, struct RenderResult *rr); float panorama_pixel_rot(struct Render *re); -#define PASS_VECTOR_MAX 10000.0f - -#define RR_USEMEM 0 - -struct RenderResult *new_render_result(struct Render *re, struct rcti *partrct, int crop, int savebuffers); -void merge_render_result(struct RenderResult *rr, struct RenderResult *rrpart); -void free_render_result(struct ListBase *lb, struct RenderResult *rr); - #endif /* PIPELINE_H */ diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index dc2de5fb450..703ca23c15b 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -54,7 +54,7 @@ #include "RE_pipeline.h" #include "render_types.h" -#include "renderpipeline.h" +#include "render_result.h" /* Render Engine Types */ @@ -168,8 +168,13 @@ RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, disprect.ymin= y; disprect.ymax= y+h; - result= new_render_result(re, &disprect, 0, RR_USEMEM); + result= render_result_new(re, &disprect, 0, RR_USE_MEM); 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,15 +195,10 @@ 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))) - merge_render_result(re->result, result); + render_result_merge(re->result, result); /* draw */ if(!re->test_break(re->tbh)) { @@ -207,7 +207,7 @@ void RE_engine_end_result(RenderEngine *engine, RenderResult *result) } /* free */ - free_render_result(&engine->fullresult, result); + render_result_free_list(&engine->fullresult, result); } /* Cancel */ @@ -286,8 +286,9 @@ int RE_engine_render(Render *re, int do_all) /* create render result */ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); if(re->result==NULL || !(re->r.scemode & R_PREVIEWBUTS)) { - RE_FreeRenderResult(re->result); - re->result= new_render_result(re, &re->disprect, 0, 0); + if(re->result) + render_result_free(re->result); + re->result= render_result_new(re, &re->disprect, 0, 0); } BLI_rw_mutex_unlock(&re->resultmutex); @@ -316,7 +317,7 @@ int RE_engine_render(Render *re, int do_all) if(type->render) type->render(engine, re->scene); - free_render_result(&engine->fullresult, engine->fullresult.first); + render_result_free_list(&engine->fullresult, engine->fullresult.first); RE_engine_free(engine); diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 785d9ac69d8..0b6e1b8ee01 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -203,6 +203,13 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul ibuf->rect+= (ibuf->x*ibuf->y); } + /* keep this before interpolation [#29761] */ + if (tex->imaflag & TEX_USEALPHA) { + if ((tex->imaflag & TEX_CALCALPHA) == 0) { + texres->talpha = TRUE; + } + } + /* interpolate */ if (tex->imaflag & TEX_INTERPOL) { float filterx, filtery; @@ -225,11 +232,6 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul ibuf->rect-= (ibuf->x*ibuf->y); } - if(tex->imaflag & TEX_USEALPHA) { - if(tex->imaflag & TEX_CALCALPHA); - else texres->talpha= 1; - } - if(texres->nor) { if(tex->imaflag & TEX_NORMALMAP) { // qdn: normal from color diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index f80bea97c9b..edf8e9aeebf 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -54,7 +54,6 @@ #include "BKE_library.h" #include "BKE_main.h" #include "BKE_node.h" -#include "BKE_object.h" #include "BKE_pointcache.h" #include "BKE_report.h" #include "BKE_scene.h" @@ -63,30 +62,28 @@ #include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */ #include "BLI_math.h" -#include "BLI_blenlib.h" +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_path_util.h" +#include "BLI_fileops.h" #include "BLI_rand.h" -#include "BLI_threads.h" #include "BLI_callbacks.h" -#include "BLI_utildefines.h" #include "PIL_time.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -#include "intern/openexr/openexr_multi.h" - #include "RE_engine.h" #include "RE_pipeline.h" #include "FRS_freestyle.h" -#include "FRS_freestyle_config.h" /* internal */ +#include "render_result.h" #include "render_types.h" #include "renderpipeline.h" #include "renderdatabase.h" #include "rendercore.h" -#include "envmap.h" #include "initrender.h" #include "shadbuf.h" #include "pixelblending.h" @@ -188,345 +185,7 @@ static void stats_background(void *UNUSED(arg), RenderStats *rs) void RE_FreeRenderResult(RenderResult *res) { - if(res==NULL) return; - - while(res->layers.first) { - RenderLayer *rl= res->layers.first; - - if(rl->rectf) MEM_freeN(rl->rectf); - /* acolrect and scolrect are optionally allocated in shade_tile, only free here since it can be used for drawing */ - if(rl->acolrect) MEM_freeN(rl->acolrect); - if(rl->scolrect) MEM_freeN(rl->scolrect); - - while(rl->passes.first) { - RenderPass *rpass= rl->passes.first; - if(rpass->rect) MEM_freeN(rpass->rect); - BLI_remlink(&rl->passes, rpass); - MEM_freeN(rpass); - } - BLI_remlink(&res->layers, rl); - MEM_freeN(rl); - } - - if(res->rect32) - MEM_freeN(res->rect32); - if(res->rectz) - MEM_freeN(res->rectz); - if(res->rectf) - MEM_freeN(res->rectf); - if(res->text) - MEM_freeN(res->text); - - MEM_freeN(res); -} - -/* version that's compatible with fullsample buffers */ -void free_render_result(ListBase *lb, RenderResult *rr) -{ - RenderResult *rrnext; - - for(; rr; rr= rrnext) { - rrnext= rr->next; - - if(lb && lb->first) - BLI_remlink(lb, rr); - - RE_FreeRenderResult(rr); - } -} - - -/* all layers except the active one get temporally pushed away */ -static void push_render_result(Render *re) -{ - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - - /* officially pushed result should be NULL... error can happen with do_seq */ - RE_FreeRenderResult(re->pushedresult); - - re->pushedresult= re->result; - re->result= NULL; - - BLI_rw_mutex_unlock(&re->resultmutex); -} - -/* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */ -static void pop_render_result(Render *re) -{ - if(re->result==NULL) { - printf("pop render result error; no current result!\n"); - return; - } - - if(re->pushedresult) { - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - - if(re->pushedresult->rectx==re->result->rectx && re->pushedresult->recty==re->result->recty) { - /* find which layer in pushedresult should be replaced */ - SceneRenderLayer *srl; - RenderLayer *rlpush; - RenderLayer *rl= re->result->layers.first; - int nr; - - /* render result should be empty after this */ - BLI_remlink(&re->result->layers, rl); - - /* reconstruct render result layers */ - for(nr=0, srl= re->scene->r.layers.first; srl; srl= srl->next, nr++) { - if(nr==re->r.actlay) - BLI_addtail(&re->result->layers, rl); - else { - rlpush= RE_GetRenderLayer(re->pushedresult, srl->name); - if(rlpush) { - BLI_remlink(&re->pushedresult->layers, rlpush); - BLI_addtail(&re->result->layers, rlpush); - } - } - } - } - - RE_FreeRenderResult(re->pushedresult); - re->pushedresult= NULL; - - BLI_rw_mutex_unlock(&re->resultmutex); - } -} - -/* NOTE: OpenEXR only supports 32 chars for layer+pass names - In blender we now use max 10 chars for pass, max 20 for layer */ -static const char *get_pass_name(int passtype, int channel) -{ - - if(passtype == SCE_PASS_COMBINED) { - if(channel==-1) return "Combined"; - if(channel==0) return "Combined.R"; - if(channel==1) return "Combined.G"; - if(channel==2) return "Combined.B"; - return "Combined.A"; - } - if(passtype == SCE_PASS_Z) { - if(channel==-1) return "Depth"; - return "Depth.Z"; - } - if(passtype == SCE_PASS_VECTOR) { - if(channel==-1) return "Vector"; - if(channel==0) return "Vector.X"; - if(channel==1) return "Vector.Y"; - if(channel==2) return "Vector.Z"; - return "Vector.W"; - } - if(passtype == SCE_PASS_NORMAL) { - if(channel==-1) return "Normal"; - if(channel==0) return "Normal.X"; - if(channel==1) return "Normal.Y"; - return "Normal.Z"; - } - if(passtype == SCE_PASS_UV) { - if(channel==-1) return "UV"; - if(channel==0) return "UV.U"; - if(channel==1) return "UV.V"; - return "UV.A"; - } - if(passtype == SCE_PASS_RGBA) { - if(channel==-1) return "Color"; - if(channel==0) return "Color.R"; - if(channel==1) return "Color.G"; - if(channel==2) return "Color.B"; - return "Color.A"; - } - if(passtype == SCE_PASS_EMIT) { - if(channel==-1) return "Emit"; - if(channel==0) return "Emit.R"; - if(channel==1) return "Emit.G"; - return "Emit.B"; - } - if(passtype == SCE_PASS_DIFFUSE) { - if(channel==-1) return "Diffuse"; - if(channel==0) return "Diffuse.R"; - if(channel==1) return "Diffuse.G"; - return "Diffuse.B"; - } - if(passtype == SCE_PASS_SPEC) { - if(channel==-1) return "Spec"; - if(channel==0) return "Spec.R"; - if(channel==1) return "Spec.G"; - return "Spec.B"; - } - if(passtype == SCE_PASS_SHADOW) { - if(channel==-1) return "Shadow"; - if(channel==0) return "Shadow.R"; - if(channel==1) return "Shadow.G"; - return "Shadow.B"; - } - if(passtype == SCE_PASS_AO) { - if(channel==-1) return "AO"; - if(channel==0) return "AO.R"; - if(channel==1) return "AO.G"; - return "AO.B"; - } - if(passtype == SCE_PASS_ENVIRONMENT) { - if(channel==-1) return "Env"; - if(channel==0) return "Env.R"; - if(channel==1) return "Env.G"; - return "Env.B"; - } - if(passtype == SCE_PASS_INDIRECT) { - if(channel==-1) return "Indirect"; - if(channel==0) return "Indirect.R"; - if(channel==1) return "Indirect.G"; - return "Indirect.B"; - } - if(passtype == SCE_PASS_REFLECT) { - if(channel==-1) return "Reflect"; - if(channel==0) return "Reflect.R"; - if(channel==1) return "Reflect.G"; - return "Reflect.B"; - } - if(passtype == SCE_PASS_REFRACT) { - if(channel==-1) return "Refract"; - if(channel==0) return "Refract.R"; - if(channel==1) return "Refract.G"; - return "Refract.B"; - } - if(passtype == SCE_PASS_INDEXOB) { - if(channel==-1) return "IndexOB"; - return "IndexOB.X"; - } - if(passtype == SCE_PASS_INDEXMA) { - if(channel==-1) return "IndexMA"; - return "IndexMA.X"; - } - if(passtype == SCE_PASS_MIST) { - if(channel==-1) return "Mist"; - return "Mist.Z"; - } - if(passtype == SCE_PASS_RAYHITS) - { - if(channel==-1) return "Rayhits"; - if(channel==0) return "Rayhits.R"; - if(channel==1) return "Rayhits.G"; - return "Rayhits.B"; - } - return "Unknown"; -} - -static int passtype_from_name(const char *str) -{ - - if(strcmp(str, "Combined")==0) - return SCE_PASS_COMBINED; - - if(strcmp(str, "Depth")==0) - return SCE_PASS_Z; - - if(strcmp(str, "Vector")==0) - return SCE_PASS_VECTOR; - - if(strcmp(str, "Normal")==0) - return SCE_PASS_NORMAL; - - if(strcmp(str, "UV")==0) - return SCE_PASS_UV; - - if(strcmp(str, "Color")==0) - return SCE_PASS_RGBA; - - if(strcmp(str, "Emit")==0) - return SCE_PASS_EMIT; - - if(strcmp(str, "Diffuse")==0) - return SCE_PASS_DIFFUSE; - - if(strcmp(str, "Spec")==0) - return SCE_PASS_SPEC; - - if(strcmp(str, "Shadow")==0) - return SCE_PASS_SHADOW; - - if(strcmp(str, "AO")==0) - return SCE_PASS_AO; - - if(strcmp(str, "Env")==0) - return SCE_PASS_ENVIRONMENT; - - if(strcmp(str, "Indirect")==0) - return SCE_PASS_INDIRECT; - - if(strcmp(str, "Reflect")==0) - return SCE_PASS_REFLECT; - - if(strcmp(str, "Refract")==0) - return SCE_PASS_REFRACT; - - if(strcmp(str, "IndexOB")==0) - return SCE_PASS_INDEXOB; - - if(strcmp(str, "IndexMA")==0) - return SCE_PASS_INDEXMA; - - if(strcmp(str, "Mist")==0) - return SCE_PASS_MIST; - - if(strcmp(str, "RayHits")==0) - return SCE_PASS_RAYHITS; - return 0; -} - -static void scene_unique_exr_name(Scene *scene, char *str, int sample) -{ - char di[FILE_MAX], name[FILE_MAXFILE+MAX_ID_NAME+100], fi[FILE_MAXFILE]; - - BLI_strncpy(di, G.main->name, FILE_MAX); - BLI_splitdirstring(di, fi); - - if(sample==0) - BLI_snprintf(name, sizeof(name), "%s_%s.exr", fi, scene->id.name+2); - else - BLI_snprintf(name, sizeof(name), "%s_%s%d.exr", fi, scene->id.name+2, sample); - - BLI_make_file_string("/", str, BLI_temporary_dir(), name); -} - -static void render_unique_exr_name(Render *re, char *str, int sample) -{ - scene_unique_exr_name(re->scene, str, sample); -} - -static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype) -{ - const char *typestr= get_pass_name(passtype, 0); - RenderPass *rpass= MEM_callocN(sizeof(RenderPass), typestr); - int rectsize= rr->rectx*rr->recty*channels; - - BLI_addtail(&rl->passes, rpass); - rpass->passtype= passtype; - rpass->channels= channels; - rpass->rectx= rl->rectx; - rpass->recty= rl->recty; - - if(rr->exrhandle) { - int a; - for(a=0; a<channels; a++) - IMB_exr_add_channel(rr->exrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL); - } - else { - float *rect; - int x; - - rpass->rect= MEM_mapallocN(sizeof(float)*rectsize, typestr); - - if(passtype==SCE_PASS_VECTOR) { - /* initialize to max speed */ - rect= rpass->rect; - for(x= rectsize-1; x>=0; x--) - rect[x]= PASS_VECTOR_MAX; - } - else if(passtype==SCE_PASS_Z) { - rect= rpass->rect; - for(x= rectsize-1; x>=0; x--) - rect[x]= 10e10; - } - } + render_result_free(res); } float *RE_RenderLayerGetPass(RenderLayer *rl, int passtype) @@ -551,141 +210,19 @@ RenderLayer *RE_GetRenderLayer(RenderResult *rr, const char *name) return NULL; } -/* called by main render as well for parts */ -/* will read info from Render *re to define layers */ -/* called in threads */ -/* re->winx,winy is coordinate space of entire image, partrct the part within */ -RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int savebuffers) +RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty) { - RenderResult *rr; - RenderLayer *rl; - SceneRenderLayer *srl; - int rectx, recty, nr; - - rectx= partrct->xmax - partrct->xmin; - recty= partrct->ymax - partrct->ymin; - - if(rectx<=0 || recty<=0) - return NULL; - - rr= MEM_callocN(sizeof(RenderResult), "new render result"); - rr->rectx= rectx; - rr->recty= recty; - rr->renrect.xmin= 0; rr->renrect.xmax= rectx-2*crop; - /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */ - rr->crop= crop; - - /* tilerect is relative coordinates within render disprect. do not subtract crop yet */ - rr->tilerect.xmin= partrct->xmin - re->disprect.xmin; - rr->tilerect.xmax= partrct->xmax - re->disprect.xmax; - rr->tilerect.ymin= partrct->ymin - re->disprect.ymin; - rr->tilerect.ymax= partrct->ymax - re->disprect.ymax; - - if(savebuffers) { - rr->exrhandle= IMB_exr_get_handle(); - } - - /* check renderdata for amount of layers */ - for(nr=0, srl= re->r.layers.first; srl; srl= srl->next, nr++) { - - if((re->r.scemode & R_SINGLE_LAYER) && nr!=re->r.actlay) - continue; - if(srl->layflag & SCE_LAY_DISABLE) - continue; - - rl= MEM_callocN(sizeof(RenderLayer), "new render layer"); - BLI_addtail(&rr->layers, rl); - - BLI_strncpy(rl->name, srl->name, sizeof(rl->name)); - rl->lay= srl->lay; - rl->lay_zmask= srl->lay_zmask; - rl->layflag= srl->layflag; - rl->passflag= srl->passflag; // for debugging: srl->passflag|SCE_PASS_RAYHITS; - rl->pass_xor= srl->pass_xor; - rl->light_override= srl->light_override; - rl->mat_override= srl->mat_override; - rl->rectx= rectx; - rl->recty= recty; - - if(rr->exrhandle) { - IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL); - IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL); - IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL); - IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL); - } - else - rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba"); - - if(srl->passflag & SCE_PASS_Z) - render_layer_add_pass(rr, rl, 1, SCE_PASS_Z); - if(srl->passflag & SCE_PASS_VECTOR) - render_layer_add_pass(rr, rl, 4, SCE_PASS_VECTOR); - if(srl->passflag & SCE_PASS_NORMAL) - render_layer_add_pass(rr, rl, 3, SCE_PASS_NORMAL); - if(srl->passflag & SCE_PASS_UV) - render_layer_add_pass(rr, rl, 3, SCE_PASS_UV); - if(srl->passflag & SCE_PASS_RGBA) - render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA); - if(srl->passflag & SCE_PASS_EMIT) - render_layer_add_pass(rr, rl, 3, SCE_PASS_EMIT); - if(srl->passflag & SCE_PASS_DIFFUSE) - render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE); - if(srl->passflag & SCE_PASS_SPEC) - render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC); - if(srl->passflag & SCE_PASS_AO) - render_layer_add_pass(rr, rl, 3, SCE_PASS_AO); - if(srl->passflag & SCE_PASS_ENVIRONMENT) - render_layer_add_pass(rr, rl, 3, SCE_PASS_ENVIRONMENT); - if(srl->passflag & SCE_PASS_INDIRECT) - render_layer_add_pass(rr, rl, 3, SCE_PASS_INDIRECT); - if(srl->passflag & SCE_PASS_SHADOW) - render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW); - if(srl->passflag & SCE_PASS_REFLECT) - render_layer_add_pass(rr, rl, 3, SCE_PASS_REFLECT); - if(srl->passflag & SCE_PASS_REFRACT) - render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT); - if(srl->passflag & SCE_PASS_INDEXOB) - render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB); - if(srl->passflag & SCE_PASS_INDEXMA) - render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXMA); - if(srl->passflag & SCE_PASS_MIST) - render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST); - if(rl->passflag & SCE_PASS_RAYHITS) - render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS); - - } - /* sss, previewrender and envmap don't do layers, so we make a default one */ - if(rr->layers.first==NULL) { - rl= MEM_callocN(sizeof(RenderLayer), "new render layer"); - BLI_addtail(&rr->layers, rl); - - rl->rectx= rectx; - rl->recty= recty; - - /* duplicate code... */ - if(rr->exrhandle) { - IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL); - IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL); - IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL); - IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL); - } - else - rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba"); - - /* note, this has to be in sync with scene.c */ - rl->lay= (1<<20) -1; - rl->layflag= 0x7FFF; /* solid ztra halo strand */ - rl->passflag= SCE_PASS_COMBINED; - FRS_add_freestyle_config( srl ); - - re->r.actlay= 0; - } - - /* border render; calculate offset for use in compositor. compo is centralized coords */ - rr->xof= re->disprect.xmin + (re->disprect.xmax - re->disprect.xmin)/2 - re->winx/2; - rr->yof= re->disprect.ymin + (re->disprect.ymax - re->disprect.ymin)/2 - re->winy/2; + return render_result_new_from_exr(exrhandle, rectx, recty); +} + +RenderLayer *render_get_active_layer(Render *re, RenderResult *rr) +{ + RenderLayer *rl= BLI_findlink(&rr->layers, re->r.actlay); - return rr; + if(rl) + return rl; + else + return rr->layers.first; } static int render_scene_needs_vector(Render *re) @@ -700,344 +237,6 @@ static int render_scene_needs_vector(Render *re) return 0; } -static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize) -{ - int y, ofs, copylen, tilex, tiley; - - copylen= tilex= rrpart->rectx; - tiley= rrpart->recty; - - if(rrpart->crop) { /* filters add pixel extra */ - tile+= pixsize*(rrpart->crop + rrpart->crop*tilex); - - copylen= tilex - 2*rrpart->crop; - tiley -= 2*rrpart->crop; - - ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop); - target+= pixsize*ofs; - } - else { - ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin); - target+= pixsize*ofs; - } - - copylen *= sizeof(float)*pixsize; - tilex *= pixsize; - ofs= pixsize*rr->rectx; - - for(y=0; y<tiley; y++) { - memcpy(target, tile, copylen); - target+= ofs; - tile+= tilex; - } -} - -/* used when rendering to a full buffer, or when reading the exr part-layer-pass file */ -/* no test happens here if it fits... we also assume layers are in sync */ -/* is used within threads */ -void merge_render_result(RenderResult *rr, RenderResult *rrpart) -{ - RenderLayer *rl, *rlp; - RenderPass *rpass, *rpassp; - - for(rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) { - - /* combined */ - if(rl->rectf && rlp->rectf) - do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4); - - /* passes are allocated in sync */ - for(rpass= rl->passes.first, rpassp= rlp->passes.first; rpass && rpassp; rpass= rpass->next, rpassp= rpassp->next) { - do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels); - } - } -} - - -static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart) -{ - RenderLayer *rlp; - RenderPass *rpassp; - int offs, partx, party; - - BLI_lock_thread(LOCK_IMAGE); - - for(rlp= rrpart->layers.first; rlp; rlp= rlp->next) { - - if(rrpart->crop) { /* filters add pixel extra */ - offs= (rrpart->crop + rrpart->crop*rrpart->rectx); - } - else { - offs= 0; - } - - /* combined */ - if(rlp->rectf) { - int a, xstride= 4; - for(a=0; a<xstride; a++) - IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a), - xstride, xstride*rrpart->rectx, rlp->rectf+a + xstride*offs); - } - - /* passes are allocated in sync */ - for(rpassp= rlp->passes.first; rpassp; rpassp= rpassp->next) { - int a, xstride= rpassp->channels; - for(a=0; a<xstride; a++) - IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a), - xstride, xstride*rrpart->rectx, rpassp->rect+a + xstride*offs); - } - - } - - party= rrpart->tilerect.ymin + rrpart->crop; - partx= rrpart->tilerect.xmin + rrpart->crop; - IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0); - - BLI_unlock_thread(LOCK_IMAGE); - -} - -static void save_empty_result_tiles(Render *re) -{ - RenderPart *pa; - RenderResult *rr; - - for(rr= re->result; rr; rr= rr->next) { - IMB_exrtile_clear_channels(rr->exrhandle); - - for(pa= re->parts.first; pa; pa= pa->next) { - if(pa->ready==0) { - int party= pa->disprect.ymin - re->disprect.ymin + pa->crop; - int partx= pa->disprect.xmin - re->disprect.xmin + pa->crop; - IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0); - } - } - } -} - - -/* for passes read from files, these have names stored */ -static char *make_pass_name(RenderPass *rpass, int chan) -{ - static char name[16]; - int len; - - BLI_strncpy(name, rpass->name, EXR_PASS_MAXNAME); - len= strlen(name); - name[len]= '.'; - name[len+1]= rpass->chan_id[chan]; - name[len+2]= 0; - - return name; -} - -/* filename already made absolute */ -/* called from within UI, saves both rendered result as a file-read result */ -int RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *filename, int compress) -{ - RenderLayer *rl; - RenderPass *rpass; - void *exrhandle= IMB_exr_get_handle(); - int success; - - BLI_make_existing_file(filename); - - /* composite result */ - if(rr->rectf) { - IMB_exr_add_channel(exrhandle, "Composite", "Combined.R", 4, 4*rr->rectx, rr->rectf); - IMB_exr_add_channel(exrhandle, "Composite", "Combined.G", 4, 4*rr->rectx, rr->rectf+1); - IMB_exr_add_channel(exrhandle, "Composite", "Combined.B", 4, 4*rr->rectx, rr->rectf+2); - IMB_exr_add_channel(exrhandle, "Composite", "Combined.A", 4, 4*rr->rectx, rr->rectf+3); - } - - /* add layers/passes and assign channels */ - for(rl= rr->layers.first; rl; rl= rl->next) { - - /* combined */ - if(rl->rectf) { - int a, xstride= 4; - for(a=0; a<xstride; a++) - IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a), - xstride, xstride*rr->rectx, rl->rectf+a); - } - - /* passes are allocated in sync */ - for(rpass= rl->passes.first; rpass; rpass= rpass->next) { - int a, xstride= rpass->channels; - for(a=0; a<xstride; a++) { - if(rpass->passtype) - IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a), - xstride, xstride*rr->rectx, rpass->rect+a); - else - IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a), - xstride, xstride*rr->rectx, rpass->rect+a); - } - } - } - - /* when the filename has no permissions, this can fail */ - if(IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty, compress)) { - IMB_exr_write_channels(exrhandle); - success= TRUE; - } - else { - /* TODO, get the error from openexr's exception */ - BKE_report(reports, RPT_ERROR, "Error Writing Render Result, see console"); - success= FALSE; - } - IMB_exr_close(exrhandle); - - return success; -} - -/* callbacks for RE_MultilayerConvert */ -static void *ml_addlayer_cb(void *base, char *str) -{ - RenderResult *rr= base; - RenderLayer *rl; - - rl= MEM_callocN(sizeof(RenderLayer), "new render layer"); - BLI_addtail(&rr->layers, rl); - - BLI_strncpy(rl->name, str, EXR_LAY_MAXNAME); - return rl; -} -static void ml_addpass_cb(void *UNUSED(base), void *lay, char *str, float *rect, int totchan, char *chan_id) -{ - RenderLayer *rl= lay; - RenderPass *rpass= MEM_callocN(sizeof(RenderPass), "loaded pass"); - int a; - - BLI_addtail(&rl->passes, rpass); - rpass->channels= totchan; - - rpass->passtype= passtype_from_name(str); - if(rpass->passtype==0) printf("unknown pass %s\n", str); - rl->passflag |= rpass->passtype; - - BLI_strncpy(rpass->name, str, EXR_PASS_MAXNAME); - /* channel id chars */ - for(a=0; a<totchan; a++) - rpass->chan_id[a]= chan_id[a]; - - rpass->rect= rect; -} - -/* from imbuf, if a handle was returned we convert this to render result */ -RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty) -{ - RenderResult *rr= MEM_callocN(sizeof(RenderResult), "loaded render result"); - RenderLayer *rl; - RenderPass *rpass; - - rr->rectx= rectx; - rr->recty= recty; - - IMB_exr_multilayer_convert(exrhandle, rr, ml_addlayer_cb, ml_addpass_cb); - - for(rl=rr->layers.first; rl; rl=rl->next) { - rl->rectx= rectx; - rl->recty= recty; - - for(rpass=rl->passes.first; rpass; rpass=rpass->next) { - rpass->rectx= rectx; - rpass->recty= recty; - } - } - - return rr; -} - -/* called in end of render, to add names to passes... for UI only */ -static void renderresult_add_names(RenderResult *rr) -{ - RenderLayer *rl; - RenderPass *rpass; - - for(rl= rr->layers.first; rl; rl= rl->next) - for(rpass= rl->passes.first; rpass; rpass= rpass->next) - BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name)); -} - -/* called for reading temp files, and for external engines */ -static int read_render_result_from_file(const char *filename, RenderResult *rr) -{ - RenderLayer *rl; - RenderPass *rpass; - void *exrhandle= IMB_exr_get_handle(); - int rectx, recty; - - if(IMB_exr_begin_read(exrhandle, filename, &rectx, &recty)==0) { - printf("failed being read %s\n", filename); - IMB_exr_close(exrhandle); - return 0; - } - - if(rr == NULL || rectx!=rr->rectx || recty!=rr->recty) { - if(rr) - printf("error in reading render result: dimensions don't match\n"); - else - printf("error in reading render result: NULL result pointer\n"); - IMB_exr_close(exrhandle); - return 0; - } - else { - for(rl= rr->layers.first; rl; rl= rl->next) { - - /* combined */ - if(rl->rectf) { - int a, xstride= 4; - for(a=0; a<xstride; a++) - IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a), - xstride, xstride*rectx, rl->rectf+a); - } - - /* passes are allocated in sync */ - for(rpass= rl->passes.first; rpass; rpass= rpass->next) { - int a, xstride= rpass->channels; - for(a=0; a<xstride; a++) - IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a), - xstride, xstride*rectx, rpass->rect+a); - } - - } - IMB_exr_read_channels(exrhandle); - renderresult_add_names(rr); - } - - IMB_exr_close(exrhandle); - - return 1; -} - -/* only for temp buffer files, makes exact copy of render result */ -static int read_render_result(Render *re, int sample) -{ - char str[FILE_MAX]; - int success; - - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - - RE_FreeRenderResult(re->result); - re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM); - - render_unique_exr_name(re, str, sample); - printf("read exr tmp file: %s\n", str); - - if(read_render_result_from_file(str, re->result)) { - success= TRUE; - } - else { - printf("cannot read: %s\n", str); - success= FALSE; - - } - - BLI_rw_mutex_unlock(&re->resultmutex); - - return success; -} - /* *************************************************** */ Render *RE_GetRender(const char *name) @@ -1096,17 +295,6 @@ Scene *RE_GetScene(Render *re) return NULL; } -RenderLayer *render_get_active_layer(Render *re, RenderResult *rr) -{ - RenderLayer *rl= BLI_findlink(&rr->layers, re->r.actlay); - - if(rl) - return rl; - else - return rr->layers.first; -} - - /* fill provided result struct with what's currently active or done */ void RE_AcquireResultImage(Render *re, RenderResult *rr) { @@ -1153,23 +341,7 @@ void RE_ResultGet32(Render *re, unsigned int *rect) RenderResult rres; RE_AcquireResultImage(re, &rres); - - if(rres.rect32) { - memcpy(rect, rres.rect32, sizeof(int)*rres.rectx*rres.recty); - } - else if(rres.rectf) { - int profile_from= (re->r.color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB; - int predivide= (re->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); - int dither= 0; - - IMB_buffer_byte_from_float((unsigned char*)rect, rres.rectf, - 4, dither, IB_PROFILE_SRGB, profile_from, predivide, - rres.rectx, rres.recty, rres.rectx, rres.rectx); - } - else - /* else fill with black */ - memset(rect, 0, sizeof(int)*re->rectx*re->recty); - + render_result_rect_get_pixels(&rres, &re->r, rect, re->rectx, re->recty); RE_ReleaseResultImage(re); } @@ -1227,8 +399,8 @@ void RE_FreeRender(Render *re) free_renderdata_tables(re); free_sample_tables(re); - RE_FreeRenderResult(re->result); - RE_FreeRenderResult(re->pushedresult); + render_result_free(re->result); + render_result_free(re->pushedresult); BLI_remlink(&RenderGlobal.renderlist, re); MEM_freeN(re); @@ -1328,14 +500,14 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer * if(re->r.scemode & R_PREVIEWBUTS) { if(re->result && re->result->rectx==re->rectx && re->result->recty==re->recty); else { - RE_FreeRenderResult(re->result); + render_result_free(re->result); re->result= NULL; } } else { /* make empty render result, so display callbacks can initialize */ - RE_FreeRenderResult(re->result); + render_result_free(re->result); re->result= MEM_callocN(sizeof(RenderResult), "new render result"); re->result->rectx= re->rectx; re->result->recty= re->recty; @@ -1351,22 +523,6 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer * RE_init_threadcount(re); } -/* part of external api, not called for regular render pipeline */ -void RE_SetDispRect (struct Render *re, rcti *disprect) -{ - re->disprect= *disprect; - re->rectx= disprect->xmax-disprect->xmin; - re->recty= disprect->ymax-disprect->ymin; - - /* initialize render result */ - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - - RE_FreeRenderResult(re->result); - re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM); - - BLI_rw_mutex_unlock(&re->resultmutex); -} - void RE_SetWindow(Render *re, rctf *viewplane, float clipsta, float clipend) { /* re->ok flag? */ @@ -1461,24 +617,6 @@ static int render_display_draw_enabled(Render *re) return 1; } -/* allocate osa new results for samples */ -static RenderResult *new_full_sample_buffers(Render *re, ListBase *lb, rcti *partrct, int crop) -{ - int a; - - if(re->osa==0) - return new_render_result(re, partrct, crop, RR_USEMEM); - - for(a=0; a<re->osa; a++) { - RenderResult *rr= new_render_result(re, partrct, crop, RR_USEMEM); - BLI_addtail(lb, rr); - rr->sample_nr= a; - } - - return lb->first; -} - - /* the main thread call, renders an entire part */ static void *do_part_thread(void *pa_v) { @@ -1488,9 +626,9 @@ static void *do_part_thread(void *pa_v) if(R.test_break(R.tbh)==0) { if(!R.sss_points && (R.r.scemode & R_FULL_SAMPLE)) - pa->result= new_full_sample_buffers(&R, &pa->fullresult, &pa->disprect, pa->crop); + pa->result= render_result_new_full_sample(&R, &pa->fullresult, &pa->disprect, pa->crop, RR_USE_MEM); else - pa->result= new_render_result(&R, &pa->disprect, pa->crop, RR_USEMEM); + pa->result= render_result_new(&R, &pa->disprect, pa->crop, RR_USE_MEM); if(R.sss_points) zbufshade_sss_tile(pa); @@ -1501,16 +639,12 @@ static void *do_part_thread(void *pa_v) /* merge too on break! */ if(R.result->exrhandle) { - RenderResult *rr, *rrpart; - - for(rr= R.result, rrpart= pa->result; rr && rrpart; rr= rr->next, rrpart= rrpart->next) - save_render_result_tile(rr, rrpart); - + render_result_exr_file_merge(R.result, pa->result); } else if(render_display_draw_enabled(&R)) { /* on break, don't merge in result for preview renders, looks nicer */ if(R.test_break(R.tbh) && (R.r.scemode & R_PREVIEWBUTS)); - else merge_render_result(R.result, pa->result); + else render_result_merge(R.result, pa->result); } } @@ -1634,20 +768,6 @@ static void print_part_stats(Render *re, RenderPart *pa) re->i.infostr= NULL; } -/* make osa new results for samples */ -static RenderResult *new_full_sample_buffers_exr(Render *re) -{ - int a; - - for(a=0; a<re->osa; a++) { - RenderResult *rr= new_render_result(re, &re->disprect, 0, 1); - BLI_addtail(&re->fullresult, rr); - rr->sample_nr= a; - } - - return re->fullresult.first; -} - static void threaded_tile_processor(Render *re) { ListBase threads; @@ -1659,14 +779,15 @@ static void threaded_tile_processor(Render *re) /* first step; free the entire render result, make new, and/or prepare exr buffer saving */ if(re->result==NULL || !(re->r.scemode & R_PREVIEWBUTS)) { - RE_FreeRenderResult(re->result); + render_result_free(re->result); if(re->sss_points && render_display_draw_enabled(re)) - re->result= new_render_result(re, &re->disprect, 0, 0); + re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM); else if(re->r.scemode & R_FULL_SAMPLE) - re->result= new_full_sample_buffers_exr(re); + re->result= render_result_new_full_sample(re, &re->fullresult, &re->disprect, 0, RR_USE_EXR); else - re->result= new_render_result(re, &re->disprect, 0, re->r.scemode & (R_EXR_TILE_FILE|R_FULL_SAMPLE)); + re->result= render_result_new(re, &re->disprect, 0, + (re->r.scemode & R_EXR_TILE_FILE)? RR_USE_EXR: RR_USE_MEM); } BLI_rw_mutex_unlock(&re->resultmutex); @@ -1678,17 +799,8 @@ static void threaded_tile_processor(Render *re) initparts(re); - if(re->result->exrhandle) { - RenderResult *rr; - char str[FILE_MAX]; - - for(rr= re->result; rr; rr= rr->next) { - render_unique_exr_name(re, str, rr->sample_nr); - - printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str); - IMB_exrtile_begin_write(rr->exrhandle, str, 0, rr->rectx, rr->recty, re->partx, re->party); - } - } + if(re->result->exrhandle) + render_result_exr_file_begin(re); BLI_init_threads(&threads, do_part_thread, re->r.threads); @@ -1742,7 +854,7 @@ static void threaded_tile_processor(Render *re) re->display_draw(re->ddh, pa->result, NULL); print_part_stats(re, pa); - free_render_result(&pa->fullresult, pa->result); + render_result_free_list(&pa->fullresult, pa->result); pa->result= NULL; re->i.partsdone++; re->progress(re->prh, re->i.partsdone / (float)re->i.totpart); @@ -1768,22 +880,9 @@ static void threaded_tile_processor(Render *re) } if(re->result->exrhandle) { - RenderResult *rr; - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - save_empty_result_tiles(re); - - for(rr= re->result; rr; rr= rr->next) { - IMB_exr_close(rr->exrhandle); - rr->exrhandle= NULL; - } - - free_render_result(&re->fullresult, re->result); - re->result= NULL; - + render_result_exr_file_end(re); BLI_rw_mutex_unlock(&re->resultmutex); - - read_render_result(re, 0); } /* unset threadsafety */ @@ -1940,7 +1039,7 @@ static void do_render_blur_3d(Render *re) int blur= re->r.mblur_samples; /* create accumulation render result */ - rres= new_render_result(re, &re->disprect, 0, RR_USEMEM); + rres= render_result_new(re, &re->disprect, 0, RR_USE_MEM); /* do the blur steps */ while(blur--) { @@ -1958,7 +1057,7 @@ static void do_render_blur_3d(Render *re) /* swap results */ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - RE_FreeRenderResult(re->result); + render_result_free(re->result); re->result= rres; BLI_rw_mutex_unlock(&re->resultmutex); @@ -2065,7 +1164,7 @@ static void do_render_fields_3d(Render *re) re->disprect.ymax *= 2; BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM); + re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM); if(rr2) { if(re->r.mode & R_ODDFIELD) @@ -2073,10 +1172,10 @@ static void do_render_fields_3d(Render *re) else merge_renderresult_fields(re->result, rr1, rr2); - RE_FreeRenderResult(rr2); + render_result_free(rr2); } - RE_FreeRenderResult(rr1); + render_result_free(rr1); re->i.curfield= 0; /* stats */ @@ -2128,10 +1227,10 @@ static void do_render_fields_blur_3d(Render *re) re->rectx= re->winx; re->recty= re->winy; - rres= new_render_result(re, &re->disprect, 0, RR_USEMEM); + rres= render_result_new(re, &re->disprect, 0, RR_USE_MEM); - merge_render_result(rres, re->result); - RE_FreeRenderResult(re->result); + render_result_merge(rres, re->result); + render_result_free(re->result); re->result= rres; /* weak... the display callback wants an active renderlayer pointer... */ @@ -2309,7 +1408,7 @@ static void composite_freestyle_renders(Render *re, int sample) for(srl= (SceneRenderLayer *)re->scene->r.layers.first; srl; srl= srl->next) { if( FRS_is_freestyle_enabled(srl) ) { freestyle_render = (Render *)link->data; - read_render_result(freestyle_render, sample); + render_result_exr_file_read(freestyle_render, sample); FRS_composite_result(re, srl, freestyle_render); RE_FreeRenderResult(freestyle_render->result); freestyle_render->result = NULL; @@ -2375,8 +1474,10 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree) if(re1->scene->id.flag & LIB_DOIT) { if(re1->r.scemode & R_FULL_SAMPLE) { if(sample) { - read_render_result(re1, sample); + BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); + render_result_exr_file_read(re1, sample); composite_freestyle_renders(re1, sample); + BLI_rw_mutex_unlock(&re->resultmutex); } ntreeCompositTagRender(re1->scene); /* ensure node gets exec to put buffers on stack */ } @@ -2506,8 +1607,8 @@ static void do_render_composite_fields_blur_3d(Render *re) /* ensure new result gets added, like for regular renders */ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - RE_FreeRenderResult(re->result); - re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM); + render_result_free(re->result); + re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM); BLI_rw_mutex_unlock(&re->resultmutex); @@ -2516,8 +1617,11 @@ static void do_render_composite_fields_blur_3d(Render *re) } /* swap render result */ - if(re->r.scemode & R_SINGLE_LAYER) - pop_render_result(re); + if(re->r.scemode & R_SINGLE_LAYER) { + BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); + render_result_single_layer_end(re); + BLI_rw_mutex_unlock(&re->resultmutex); + } if(!re->test_break(re->tbh)) { @@ -2614,9 +1718,17 @@ static void do_render_seq(Render * re) recurs_depth++; - context = seq_new_render_data(re->main, re->scene, - re->result->rectx, re->result->recty, - 100); + if((re->r.mode & R_BORDER) && (re->r.mode & R_CROP)==0) { + /* if border rendering is used and cropping is disabled, final buffer should + be as large as the whole frame */ + context = seq_new_render_data(re->main, re->scene, + re->winx, re->winy, + 100); + } else { + context = seq_new_render_data(re->main, re->scene, + re->result->rectx, re->result->recty, + 100); + } ibuf = give_ibuf_seq(context, cfra, 0); @@ -2627,61 +1739,19 @@ static void do_render_seq(Render * re) BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); if(ibuf) { - if(ibuf->rect_float) { - /* color management: when off ensure rectf is non-lin, since thats what the internal - * render engine delivers */ - int profile_to= (re->r.color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB; - int profile_from= (ibuf->profile == IB_PROFILE_LINEAR_RGB)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB; - int predivide= (re->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); - - if (!rr->rectf) - rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf"); - - IMB_buffer_float_from_float(rr->rectf, ibuf->rect_float, - 4, profile_to, profile_from, predivide, - rr->rectx, rr->recty, rr->rectx, rr->rectx); - - /* TSK! Since sequence render doesn't free the *rr render result, the old rect32 - can hang around when sequence render has rendered a 32 bits one before */ - if(rr->rect32) { - MEM_freeN(rr->rect32); - rr->rect32= NULL; - } - } - else if(ibuf->rect) { - if (!rr->rect32) - rr->rect32= MEM_mallocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect"); - - memcpy(rr->rect32, ibuf->rect, 4*rr->rectx*rr->recty); - - /* if (ibuf->zbuf) { */ - /* if (R.rectz) freeN(R.rectz); */ - /* R.rectz = BLI_dupallocN(ibuf->zbuf); */ - /* } */ - - /* Same things as above, old rectf can hang around from previous render. */ - if(rr->rectf) { - MEM_freeN(rr->rectf); - rr->rectf= NULL; - } - } + /* copy ibuf into combined pixel rect */ + render_result_rect_from_ibuf(rr, &re->r, ibuf); if (recurs_depth == 0) { /* with nested scenes, only free on toplevel... */ Editing * ed = re->scene->ed; - if (ed) { + if (ed) free_imbuf_seq(re->scene, &ed->seqbase, TRUE, TRUE); - } } IMB_freeImBuf(ibuf); } else { /* render result is delivered empty in most cases, nevertheless we handle all cases */ - if (rr->rectf) - memset(rr->rectf, 0, 4*sizeof(float)*rr->rectx*rr->recty); - else if (rr->rect32) - memset(rr->rect32, 0, 4*rr->rectx*rr->recty); - else - rr->rect32= MEM_callocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect"); + render_result_rect_fill_zero(rr); } BLI_rw_mutex_unlock(&re->resultmutex); @@ -2723,11 +1793,6 @@ static void do_render_all_options(Render *re) do_render_composite_fields_blur_3d(re); } - /* for UI only */ - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - renderresult_add_names(re->result); - BLI_rw_mutex_unlock(&re->resultmutex); - re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime; re->stats_draw(re->sdh, &re->i); @@ -2811,7 +1876,7 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r if(scene->r.scemode & (R_EXR_TILE_FILE|R_FULL_SAMPLE)) { char str[FILE_MAX]; - scene_unique_exr_name(scene, str, 0); + render_result_exr_file_path(scene, 0, str); if (BLI_file_is_writable(str)==0) { BKE_report(reports, RPT_ERROR, "Can not save render buffers, check the temp default path"); @@ -2973,8 +2038,11 @@ static int render_initialize_from_main(Render *re, Main *bmain, Scene *scene, Sc update_physics_cache(re, scene, anim_init); } - if(srl || scene->r.scemode & R_SINGLE_LAYER) - push_render_result(re); + if(srl || scene->r.scemode & R_SINGLE_LAYER) { + BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); + render_result_single_layer_begin(re); + BLI_rw_mutex_unlock(&re->resultmutex); + } RE_InitState(re, NULL, &scene->r, srl, winx, winy, &disprect); if(!re->ok) /* if an error was printed, abort */ @@ -3080,37 +2148,7 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie } } else { - int flags = (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE)? IB_cm_predivide: 0; - ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.im_format.planes, flags); - - /* if not exists, BKE_write_ibuf makes one */ - ibuf->rect= (unsigned int *)rres.rect32; - ibuf->rect_float= rres.rectf; - ibuf->zbuf_float= rres.rectz; - - /* float factor for random dither, imbuf takes care of it */ - ibuf->dither= scene->r.dither_intensity; - - /* prepare to gamma correct to sRGB color space */ - if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) { - /* sequence editor can generate 8bpc render buffers */ - if (ibuf->rect) { - ibuf->profile = IB_PROFILE_SRGB; - if (BKE_imtype_valid_depths(scene->r.im_format.imtype) & (R_IMF_CHAN_DEPTH_12|R_IMF_CHAN_DEPTH_16|R_IMF_CHAN_DEPTH_24|R_IMF_CHAN_DEPTH_32)) - IMB_float_from_rect(ibuf); - } else { - ibuf->profile = IB_PROFILE_LINEAR_RGB; - } - } - - /* color -> greyscale */ - /* editing directly would alter the render view */ - if(scene->r.im_format.planes == R_IMF_PLANES_BW) { - ImBuf *ibuf_bw= IMB_dupImBuf(ibuf); - IMB_color_to_bw(ibuf_bw); - IMB_freeImBuf(ibuf); - ibuf= ibuf_bw; - } + ImBuf *ibuf= render_result_rect_to_ibuf(&rres, &scene->r); ok= BKE_write_ibuf_stamp(scene, camera, ibuf, name, &scene->r.im_format); @@ -3309,7 +2347,7 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce) int RE_ReadRenderResult(Scene *scene, Scene *scenode) { Render *re; - int winx, winy; + int winx, winy, success; rcti disprect; /* calculate actual render result and display size */ @@ -3340,7 +2378,11 @@ int RE_ReadRenderResult(Scene *scene, Scene *scenode) RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect); re->scene= scene; - return read_render_result(re, 0); + BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); + success= render_result_exr_file_read(re, 0); + BLI_rw_mutex_unlock(&re->resultmutex); + + return success; } void RE_set_max_threads(int threads) @@ -3407,7 +2449,7 @@ void RE_layer_load_from_file(RenderLayer *layer, ReportList *reports, const char void RE_result_load_from_file(RenderResult *result, ReportList *reports, const char *filename) { - if(!read_render_result_from_file(filename, result)) { + if(!render_result_exr_file_read_path(result, filename)) { BKE_reportf(reports, RPT_ERROR, "RE_result_rect_from_file: failed to load '%s'\n", filename); return; } diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 41bfcb55068..f9ffc2532eb 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -53,6 +53,7 @@ #include "PIL_time.h" +#include "render_result.h" #include "render_types.h" #include "renderpipeline.h" #include "rendercore.h" @@ -779,7 +780,10 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, con tracol[3]= col[3]; // we pass on and accumulate alpha if((shi.mat->mode & MA_TRANSP) && (shi.mat->mode & MA_RAYTRANSP)) { - if(traflag & RAY_INSIDE) { + /* don't overwrite traflag, it's value is used in mirror reflection */ + int new_traflag = traflag; + + if(new_traflag & RAY_INSIDE) { /* inside the material, so use inverse normal */ float norm[3]; norm[0]= - shi.vn[0]; @@ -788,7 +792,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, con if (refraction(refract, norm, shi.view, shi.ang)) { /* ray comes out from the material into air */ - traflag &= ~RAY_INSIDE; + new_traflag &= ~RAY_INSIDE; } else { /* total internal reflection (ray stays inside the material) */ @@ -798,14 +802,14 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, con else { if (refraction(refract, shi.vn, shi.view, shi.ang)) { /* ray goes in to the material from air */ - traflag |= RAY_INSIDE; + new_traflag |= RAY_INSIDE; } else { /* total external reflection (ray doesn't enter the material) */ reflection(refract, shi.vn, shi.view, shi.vn); } } - traceray(origshi, origshr, depth-1, shi.co, refract, tracol, shi.obi, shi.vlr, traflag); + traceray(origshi, origshr, depth-1, shi.co, refract, tracol, shi.obi, shi.vlr, new_traflag); } else traceray(origshi, origshr, depth-1, shi.co, shi.view, tracol, shi.obi, shi.vlr, 0); @@ -839,7 +843,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, con float ref[3]; reflection_simple(ref, shi.vn, shi.view); - traceray(origshi, origshr, depth-1, shi.co, ref, mircol, shi.obi, shi.vlr, 0); + traceray(origshi, origshr, depth-1, shi.co, ref, mircol, shi.obi, shi.vlr, traflag); f1= 1.0f-f; diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c new file mode 100644 index 00000000000..a8a74daa47b --- /dev/null +++ b/source/blender/render/intern/source/render_result.c @@ -0,0 +1,1024 @@ +/* + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2006 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/render/intern/source/render_result.c + * \ingroup render + */ + +#include <stdio.h> +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "BKE_image.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_report.h" +#include "BKE_utildefines.h" + +#include "BLI_fileops.h" +#include "BLI_listbase.h" +#include "BLI_path_util.h" +#include "BLI_string.h" +#include "BLI_threads.h" +#include "BLI_utildefines.h" + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +#include "intern/openexr/openexr_multi.h" + +#include "render_result.h" +#include "render_types.h" + +#include "FRS_freestyle_config.h" + +/********************************** Free *************************************/ + +void render_result_free(RenderResult *res) +{ + if(res==NULL) return; + + while(res->layers.first) { + RenderLayer *rl= res->layers.first; + + if(rl->rectf) MEM_freeN(rl->rectf); + /* acolrect and scolrect are optionally allocated in shade_tile, only free here since it can be used for drawing */ + if(rl->acolrect) MEM_freeN(rl->acolrect); + if(rl->scolrect) MEM_freeN(rl->scolrect); + + while(rl->passes.first) { + RenderPass *rpass= rl->passes.first; + if(rpass->rect) MEM_freeN(rpass->rect); + BLI_remlink(&rl->passes, rpass); + MEM_freeN(rpass); + } + BLI_remlink(&res->layers, rl); + MEM_freeN(rl); + } + + if(res->rect32) + MEM_freeN(res->rect32); + if(res->rectz) + MEM_freeN(res->rectz); + if(res->rectf) + MEM_freeN(res->rectf); + if(res->text) + MEM_freeN(res->text); + + MEM_freeN(res); +} + +/* version that's compatible with fullsample buffers */ +void render_result_free_list(ListBase *lb, RenderResult *rr) +{ + RenderResult *rrnext; + + for(; rr; rr= rrnext) { + rrnext= rr->next; + + if(lb && lb->first) + BLI_remlink(lb, rr); + + render_result_free(rr); + } +} + +/********************************* Names *************************************/ + +/* NOTE: OpenEXR only supports 32 chars for layer+pass names + In blender we now use max 10 chars for pass, max 20 for layer */ +static const char *get_pass_name(int passtype, int channel) +{ + + if(passtype == SCE_PASS_COMBINED) { + if(channel==-1) return "Combined"; + if(channel==0) return "Combined.R"; + if(channel==1) return "Combined.G"; + if(channel==2) return "Combined.B"; + return "Combined.A"; + } + if(passtype == SCE_PASS_Z) { + if(channel==-1) return "Depth"; + return "Depth.Z"; + } + if(passtype == SCE_PASS_VECTOR) { + if(channel==-1) return "Vector"; + if(channel==0) return "Vector.X"; + if(channel==1) return "Vector.Y"; + if(channel==2) return "Vector.Z"; + return "Vector.W"; + } + if(passtype == SCE_PASS_NORMAL) { + if(channel==-1) return "Normal"; + if(channel==0) return "Normal.X"; + if(channel==1) return "Normal.Y"; + return "Normal.Z"; + } + if(passtype == SCE_PASS_UV) { + if(channel==-1) return "UV"; + if(channel==0) return "UV.U"; + if(channel==1) return "UV.V"; + return "UV.A"; + } + if(passtype == SCE_PASS_RGBA) { + if(channel==-1) return "Color"; + if(channel==0) return "Color.R"; + if(channel==1) return "Color.G"; + if(channel==2) return "Color.B"; + return "Color.A"; + } + if(passtype == SCE_PASS_EMIT) { + if(channel==-1) return "Emit"; + if(channel==0) return "Emit.R"; + if(channel==1) return "Emit.G"; + return "Emit.B"; + } + if(passtype == SCE_PASS_DIFFUSE) { + if(channel==-1) return "Diffuse"; + if(channel==0) return "Diffuse.R"; + if(channel==1) return "Diffuse.G"; + return "Diffuse.B"; + } + if(passtype == SCE_PASS_SPEC) { + if(channel==-1) return "Spec"; + if(channel==0) return "Spec.R"; + if(channel==1) return "Spec.G"; + return "Spec.B"; + } + if(passtype == SCE_PASS_SHADOW) { + if(channel==-1) return "Shadow"; + if(channel==0) return "Shadow.R"; + if(channel==1) return "Shadow.G"; + return "Shadow.B"; + } + if(passtype == SCE_PASS_AO) { + if(channel==-1) return "AO"; + if(channel==0) return "AO.R"; + if(channel==1) return "AO.G"; + return "AO.B"; + } + if(passtype == SCE_PASS_ENVIRONMENT) { + if(channel==-1) return "Env"; + if(channel==0) return "Env.R"; + if(channel==1) return "Env.G"; + return "Env.B"; + } + if(passtype == SCE_PASS_INDIRECT) { + if(channel==-1) return "Indirect"; + if(channel==0) return "Indirect.R"; + if(channel==1) return "Indirect.G"; + return "Indirect.B"; + } + if(passtype == SCE_PASS_REFLECT) { + if(channel==-1) return "Reflect"; + if(channel==0) return "Reflect.R"; + if(channel==1) return "Reflect.G"; + return "Reflect.B"; + } + if(passtype == SCE_PASS_REFRACT) { + if(channel==-1) return "Refract"; + if(channel==0) return "Refract.R"; + if(channel==1) return "Refract.G"; + return "Refract.B"; + } + if(passtype == SCE_PASS_INDEXOB) { + if(channel==-1) return "IndexOB"; + return "IndexOB.X"; + } + if(passtype == SCE_PASS_INDEXMA) { + if(channel==-1) return "IndexMA"; + return "IndexMA.X"; + } + if(passtype == SCE_PASS_MIST) { + if(channel==-1) return "Mist"; + return "Mist.Z"; + } + if(passtype == SCE_PASS_RAYHITS) + { + if(channel==-1) return "Rayhits"; + if(channel==0) return "Rayhits.R"; + if(channel==1) return "Rayhits.G"; + return "Rayhits.B"; + } + return "Unknown"; +} + +static int passtype_from_name(const char *str) +{ + + if(strcmp(str, "Combined")==0) + return SCE_PASS_COMBINED; + + if(strcmp(str, "Depth")==0) + return SCE_PASS_Z; + + if(strcmp(str, "Vector")==0) + return SCE_PASS_VECTOR; + + if(strcmp(str, "Normal")==0) + return SCE_PASS_NORMAL; + + if(strcmp(str, "UV")==0) + return SCE_PASS_UV; + + if(strcmp(str, "Color")==0) + return SCE_PASS_RGBA; + + if(strcmp(str, "Emit")==0) + return SCE_PASS_EMIT; + + if(strcmp(str, "Diffuse")==0) + return SCE_PASS_DIFFUSE; + + if(strcmp(str, "Spec")==0) + return SCE_PASS_SPEC; + + if(strcmp(str, "Shadow")==0) + return SCE_PASS_SHADOW; + + if(strcmp(str, "AO")==0) + return SCE_PASS_AO; + + if(strcmp(str, "Env")==0) + return SCE_PASS_ENVIRONMENT; + + if(strcmp(str, "Indirect")==0) + return SCE_PASS_INDIRECT; + + if(strcmp(str, "Reflect")==0) + return SCE_PASS_REFLECT; + + if(strcmp(str, "Refract")==0) + return SCE_PASS_REFRACT; + + if(strcmp(str, "IndexOB")==0) + return SCE_PASS_INDEXOB; + + if(strcmp(str, "IndexMA")==0) + return SCE_PASS_INDEXMA; + + if(strcmp(str, "Mist")==0) + return SCE_PASS_MIST; + + if(strcmp(str, "RayHits")==0) + return SCE_PASS_RAYHITS; + return 0; +} + +/********************************** New **************************************/ + +static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype) +{ + const char *typestr= get_pass_name(passtype, 0); + RenderPass *rpass= MEM_callocN(sizeof(RenderPass), typestr); + int rectsize= rr->rectx*rr->recty*channels; + + BLI_addtail(&rl->passes, rpass); + rpass->passtype= passtype; + rpass->channels= channels; + rpass->rectx= rl->rectx; + rpass->recty= rl->recty; + BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name)); + + if(rr->exrhandle) { + int a; + for(a=0; a<channels; a++) + IMB_exr_add_channel(rr->exrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL); + } + else { + float *rect; + int x; + + rpass->rect= MEM_mapallocN(sizeof(float)*rectsize, typestr); + + if(passtype==SCE_PASS_VECTOR) { + /* initialize to max speed */ + rect= rpass->rect; + for(x= rectsize-1; x>=0; x--) + rect[x]= PASS_VECTOR_MAX; + } + else if(passtype==SCE_PASS_Z) { + rect= rpass->rect; + for(x= rectsize-1; x>=0; x--) + rect[x]= 10e10; + } + } +} + +/* called by main render as well for parts */ +/* will read info from Render *re to define layers */ +/* called in threads */ +/* re->winx,winy is coordinate space of entire image, partrct the part within */ +RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuffers) +{ + RenderResult *rr; + RenderLayer *rl; + SceneRenderLayer *srl; + int rectx, recty, nr; + + rectx= partrct->xmax - partrct->xmin; + recty= partrct->ymax - partrct->ymin; + + if(rectx<=0 || recty<=0) + return NULL; + + rr= MEM_callocN(sizeof(RenderResult), "new render result"); + rr->rectx= rectx; + rr->recty= recty; + rr->renrect.xmin= 0; rr->renrect.xmax= rectx-2*crop; + /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */ + rr->crop= crop; + + /* tilerect is relative coordinates within render disprect. do not subtract crop yet */ + rr->tilerect.xmin= partrct->xmin - re->disprect.xmin; + rr->tilerect.xmax= partrct->xmax - re->disprect.xmax; + rr->tilerect.ymin= partrct->ymin - re->disprect.ymin; + rr->tilerect.ymax= partrct->ymax - re->disprect.ymax; + + if(savebuffers) { + rr->exrhandle= IMB_exr_get_handle(); + } + + /* check renderdata for amount of layers */ + for(nr=0, srl= re->r.layers.first; srl; srl= srl->next, nr++) { + + if((re->r.scemode & R_SINGLE_LAYER) && nr!=re->r.actlay) + continue; + if(srl->layflag & SCE_LAY_DISABLE) + continue; + + rl= MEM_callocN(sizeof(RenderLayer), "new render layer"); + BLI_addtail(&rr->layers, rl); + + BLI_strncpy(rl->name, srl->name, sizeof(rl->name)); + rl->lay= srl->lay; + rl->lay_zmask= srl->lay_zmask; + rl->layflag= srl->layflag; + rl->passflag= srl->passflag; // for debugging: srl->passflag|SCE_PASS_RAYHITS; + rl->pass_xor= srl->pass_xor; + rl->light_override= srl->light_override; + rl->mat_override= srl->mat_override; + rl->rectx= rectx; + rl->recty= recty; + + if(rr->exrhandle) { + IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL); + IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL); + IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL); + IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL); + } + else + rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba"); + + if(srl->passflag & SCE_PASS_Z) + render_layer_add_pass(rr, rl, 1, SCE_PASS_Z); + if(srl->passflag & SCE_PASS_VECTOR) + render_layer_add_pass(rr, rl, 4, SCE_PASS_VECTOR); + if(srl->passflag & SCE_PASS_NORMAL) + render_layer_add_pass(rr, rl, 3, SCE_PASS_NORMAL); + if(srl->passflag & SCE_PASS_UV) + render_layer_add_pass(rr, rl, 3, SCE_PASS_UV); + if(srl->passflag & SCE_PASS_RGBA) + render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA); + if(srl->passflag & SCE_PASS_EMIT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_EMIT); + if(srl->passflag & SCE_PASS_DIFFUSE) + render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE); + if(srl->passflag & SCE_PASS_SPEC) + render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC); + if(srl->passflag & SCE_PASS_AO) + render_layer_add_pass(rr, rl, 3, SCE_PASS_AO); + if(srl->passflag & SCE_PASS_ENVIRONMENT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_ENVIRONMENT); + if(srl->passflag & SCE_PASS_INDIRECT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_INDIRECT); + if(srl->passflag & SCE_PASS_SHADOW) + render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW); + if(srl->passflag & SCE_PASS_REFLECT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_REFLECT); + if(srl->passflag & SCE_PASS_REFRACT) + render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT); + if(srl->passflag & SCE_PASS_INDEXOB) + render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB); + if(srl->passflag & SCE_PASS_INDEXMA) + render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXMA); + if(srl->passflag & SCE_PASS_MIST) + render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST); + if(rl->passflag & SCE_PASS_RAYHITS) + render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS); + + } + /* sss, previewrender and envmap don't do layers, so we make a default one */ + if(rr->layers.first==NULL) { + rl= MEM_callocN(sizeof(RenderLayer), "new render layer"); + BLI_addtail(&rr->layers, rl); + + rl->rectx= rectx; + rl->recty= recty; + + /* duplicate code... */ + if(rr->exrhandle) { + IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL); + IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL); + IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL); + IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL); + } + else + rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba"); + + /* note, this has to be in sync with scene.c */ + rl->lay= (1<<20) -1; + rl->layflag= 0x7FFF; /* solid ztra halo strand */ + rl->passflag= SCE_PASS_COMBINED; + FRS_add_freestyle_config( srl ); + + re->r.actlay= 0; + } + + /* border render; calculate offset for use in compositor. compo is centralized coords */ + rr->xof= re->disprect.xmin + (re->disprect.xmax - re->disprect.xmin)/2 - re->winx/2; + rr->yof= re->disprect.ymin + (re->disprect.ymax - re->disprect.ymin)/2 - re->winy/2; + + return rr; +} + +/* allocate osa new results for samples */ +RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *partrct, int crop, int savebuffers) +{ + int a; + + if(re->osa==0) + return render_result_new(re, partrct, crop, savebuffers); + + for(a=0; a<re->osa; a++) { + RenderResult *rr= render_result_new(re, partrct, crop, savebuffers); + BLI_addtail(lb, rr); + rr->sample_nr= a; + } + + return lb->first; +} + +/* callbacks for render_result_new_from_exr */ +static void *ml_addlayer_cb(void *base, char *str) +{ + RenderResult *rr= base; + RenderLayer *rl; + + rl= MEM_callocN(sizeof(RenderLayer), "new render layer"); + BLI_addtail(&rr->layers, rl); + + BLI_strncpy(rl->name, str, EXR_LAY_MAXNAME); + return rl; +} + +static void ml_addpass_cb(void *UNUSED(base), void *lay, char *str, float *rect, int totchan, char *chan_id) +{ + RenderLayer *rl= lay; + RenderPass *rpass= MEM_callocN(sizeof(RenderPass), "loaded pass"); + int a; + + BLI_addtail(&rl->passes, rpass); + rpass->channels= totchan; + + rpass->passtype= passtype_from_name(str); + if(rpass->passtype==0) printf("unknown pass %s\n", str); + rl->passflag |= rpass->passtype; + + BLI_strncpy(rpass->name, str, EXR_PASS_MAXNAME); + /* channel id chars */ + for(a=0; a<totchan; a++) + rpass->chan_id[a]= chan_id[a]; + + rpass->rect= rect; +} + +/* from imbuf, if a handle was returned we convert this to render result */ +RenderResult *render_result_new_from_exr(void *exrhandle, int rectx, int recty) +{ + RenderResult *rr= MEM_callocN(sizeof(RenderResult), "loaded render result"); + RenderLayer *rl; + RenderPass *rpass; + + rr->rectx= rectx; + rr->recty= recty; + + IMB_exr_multilayer_convert(exrhandle, rr, ml_addlayer_cb, ml_addpass_cb); + + for(rl=rr->layers.first; rl; rl=rl->next) { + rl->rectx= rectx; + rl->recty= recty; + + for(rpass=rl->passes.first; rpass; rpass=rpass->next) { + rpass->rectx= rectx; + rpass->recty= recty; + } + } + + return rr; +} + +/*********************************** Merge ***********************************/ + +static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize) +{ + int y, ofs, copylen, tilex, tiley; + + copylen= tilex= rrpart->rectx; + tiley= rrpart->recty; + + if(rrpart->crop) { /* filters add pixel extra */ + tile+= pixsize*(rrpart->crop + rrpart->crop*tilex); + + copylen= tilex - 2*rrpart->crop; + tiley -= 2*rrpart->crop; + + ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop); + target+= pixsize*ofs; + } + else { + ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin); + target+= pixsize*ofs; + } + + copylen *= sizeof(float)*pixsize; + tilex *= pixsize; + ofs= pixsize*rr->rectx; + + for(y=0; y<tiley; y++) { + memcpy(target, tile, copylen); + target+= ofs; + tile+= tilex; + } +} + +/* used when rendering to a full buffer, or when reading the exr part-layer-pass file */ +/* no test happens here if it fits... we also assume layers are in sync */ +/* is used within threads */ +void render_result_merge(RenderResult *rr, RenderResult *rrpart) +{ + RenderLayer *rl, *rlp; + RenderPass *rpass, *rpassp; + + for(rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) { + + /* combined */ + if(rl->rectf && rlp->rectf) + do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4); + + /* passes are allocated in sync */ + for(rpass= rl->passes.first, rpassp= rlp->passes.first; rpass && rpassp; rpass= rpass->next, rpassp= rpassp->next) { + do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels); + } + } +} + +/* for passes read from files, these have names stored */ +static char *make_pass_name(RenderPass *rpass, int chan) +{ + static char name[16]; + int len; + + BLI_strncpy(name, rpass->name, EXR_PASS_MAXNAME); + len= strlen(name); + name[len]= '.'; + name[len+1]= rpass->chan_id[chan]; + name[len+2]= 0; + + return name; +} + +/* filename already made absolute */ +/* called from within UI, saves both rendered result as a file-read result */ +int RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *filename, int compress) +{ + RenderLayer *rl; + RenderPass *rpass; + void *exrhandle= IMB_exr_get_handle(); + int success; + + BLI_make_existing_file(filename); + + /* composite result */ + if(rr->rectf) { + IMB_exr_add_channel(exrhandle, "Composite", "Combined.R", 4, 4*rr->rectx, rr->rectf); + IMB_exr_add_channel(exrhandle, "Composite", "Combined.G", 4, 4*rr->rectx, rr->rectf+1); + IMB_exr_add_channel(exrhandle, "Composite", "Combined.B", 4, 4*rr->rectx, rr->rectf+2); + IMB_exr_add_channel(exrhandle, "Composite", "Combined.A", 4, 4*rr->rectx, rr->rectf+3); + } + + /* add layers/passes and assign channels */ + for(rl= rr->layers.first; rl; rl= rl->next) { + + /* combined */ + if(rl->rectf) { + int a, xstride= 4; + for(a=0; a<xstride; a++) + IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a), + xstride, xstride*rr->rectx, rl->rectf+a); + } + + /* passes are allocated in sync */ + for(rpass= rl->passes.first; rpass; rpass= rpass->next) { + int a, xstride= rpass->channels; + for(a=0; a<xstride; a++) { + if(rpass->passtype) + IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a), + xstride, xstride*rr->rectx, rpass->rect+a); + else + IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a), + xstride, xstride*rr->rectx, rpass->rect+a); + } + } + } + + /* when the filename has no permissions, this can fail */ + if(IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty, compress)) { + IMB_exr_write_channels(exrhandle); + success= TRUE; + } + else { + /* TODO, get the error from openexr's exception */ + BKE_report(reports, RPT_ERROR, "Error Writing Render Result, see console"); + success= FALSE; + } + IMB_exr_close(exrhandle); + + return success; +} + +/**************************** Single Layer Rendering *************************/ + +void render_result_single_layer_begin(Render *re) +{ + /* all layers except the active one get temporally pushed away */ + + /* officially pushed result should be NULL... error can happen with do_seq */ + RE_FreeRenderResult(re->pushedresult); + + re->pushedresult= re->result; + re->result= NULL; +} + +/* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */ +void render_result_single_layer_end(Render *re) +{ + SceneRenderLayer *srl; + RenderLayer *rlpush; + RenderLayer *rl; + int nr; + + if(re->result==NULL) { + printf("pop render result error; no current result!\n"); + return; + } + + if(!re->pushedresult) + return; + + if(re->pushedresult->rectx==re->result->rectx && re->pushedresult->recty==re->result->recty) { + /* find which layer in re->pushedresult should be replaced */ + rl= re->result->layers.first; + + /* render result should be empty after this */ + BLI_remlink(&re->result->layers, rl); + + /* reconstruct render result layers */ + for(nr=0, srl= re->scene->r.layers.first; srl; srl= srl->next, nr++) { + if(nr==re->r.actlay) + BLI_addtail(&re->result->layers, rl); + else { + rlpush= RE_GetRenderLayer(re->pushedresult, srl->name); + if(rlpush) { + BLI_remlink(&re->pushedresult->layers, rlpush); + BLI_addtail(&re->result->layers, rlpush); + } + } + } + } + + RE_FreeRenderResult(re->pushedresult); + re->pushedresult= NULL; +} + +/************************* EXR Tile File Rendering ***************************/ + +static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart) +{ + RenderLayer *rlp; + RenderPass *rpassp; + int offs, partx, party; + + BLI_lock_thread(LOCK_IMAGE); + + for(rlp= rrpart->layers.first; rlp; rlp= rlp->next) { + + if(rrpart->crop) { /* filters add pixel extra */ + offs= (rrpart->crop + rrpart->crop*rrpart->rectx); + } + else { + offs= 0; + } + + /* combined */ + if(rlp->rectf) { + int a, xstride= 4; + for(a=0; a<xstride; a++) + IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a), + xstride, xstride*rrpart->rectx, rlp->rectf+a + xstride*offs); + } + + /* passes are allocated in sync */ + for(rpassp= rlp->passes.first; rpassp; rpassp= rpassp->next) { + int a, xstride= rpassp->channels; + for(a=0; a<xstride; a++) + IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a), + xstride, xstride*rrpart->rectx, rpassp->rect+a + xstride*offs); + } + + } + + party= rrpart->tilerect.ymin + rrpart->crop; + partx= rrpart->tilerect.xmin + rrpart->crop; + IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0); + + BLI_unlock_thread(LOCK_IMAGE); +} + +static void save_empty_result_tiles(Render *re) +{ + RenderPart *pa; + RenderResult *rr; + + for(rr= re->result; rr; rr= rr->next) { + IMB_exrtile_clear_channels(rr->exrhandle); + + for(pa= re->parts.first; pa; pa= pa->next) { + if(pa->ready==0) { + int party= pa->disprect.ymin - re->disprect.ymin + pa->crop; + int partx= pa->disprect.xmin - re->disprect.xmin + pa->crop; + IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0); + } + } + } +} + +/* begin write of exr tile file */ +void render_result_exr_file_begin(Render *re) +{ + RenderResult *rr; + char str[FILE_MAX]; + + for(rr= re->result; rr; rr= rr->next) { + render_result_exr_file_path(re->scene, rr->sample_nr, str); + + printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str); + IMB_exrtile_begin_write(rr->exrhandle, str, 0, rr->rectx, rr->recty, re->partx, re->party); + } +} + +/* end write of exr tile file, read back first sample */ +void render_result_exr_file_end(Render *re) +{ + RenderResult *rr; + + save_empty_result_tiles(re); + + for(rr= re->result; rr; rr= rr->next) { + IMB_exr_close(rr->exrhandle); + rr->exrhandle= NULL; + } + + render_result_free_list(&re->fullresult, re->result); + re->result= NULL; + + render_result_exr_file_read(re, 0); +} + +/* save part into exr file */ +void render_result_exr_file_merge(RenderResult *rr, RenderResult *rrpart) +{ + for(; rr && rrpart; rr= rr->next, rrpart= rrpart->next) + save_render_result_tile(rr, rrpart); +} + +/* path to temporary exr file */ +void render_result_exr_file_path(Scene *scene, int sample, char *filepath) +{ + char di[FILE_MAX], name[FILE_MAXFILE+MAX_ID_NAME+100], fi[FILE_MAXFILE]; + + BLI_strncpy(di, G.main->name, FILE_MAX); + BLI_splitdirstring(di, fi); + + if(sample==0) + BLI_snprintf(name, sizeof(name), "%s_%s.exr", fi, scene->id.name+2); + else + BLI_snprintf(name, sizeof(name), "%s_%s%d.exr", fi, scene->id.name+2, sample); + + BLI_make_file_string("/", filepath, BLI_temporary_dir(), name); +} + +/* only for temp buffer files, makes exact copy of render result */ +int render_result_exr_file_read(Render *re, int sample) +{ + char str[FILE_MAX]; + int success; + + RE_FreeRenderResult(re->result); + re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM); + + render_result_exr_file_path(re->scene, sample, str); + printf("read exr tmp file: %s\n", str); + + if(render_result_exr_file_read_path(re->result, str)) { + success= TRUE; + } + else { + printf("cannot read: %s\n", str); + success= FALSE; + + } + + return success; +} + +/* called for reading temp files, and for external engines */ +int render_result_exr_file_read_path(RenderResult *rr, const char *filepath) +{ + RenderLayer *rl; + RenderPass *rpass; + void *exrhandle= IMB_exr_get_handle(); + int rectx, recty; + + if(IMB_exr_begin_read(exrhandle, filepath, &rectx, &recty)==0) { + printf("failed being read %s\n", filepath); + IMB_exr_close(exrhandle); + return 0; + } + + if(rr == NULL || rectx!=rr->rectx || recty!=rr->recty) { + if(rr) + printf("error in reading render result: dimensions don't match\n"); + else + printf("error in reading render result: NULL result pointer\n"); + IMB_exr_close(exrhandle); + return 0; + } + + for(rl= rr->layers.first; rl; rl= rl->next) { + /* combined */ + if(rl->rectf) { + int a, xstride= 4; + for(a=0; a<xstride; a++) + IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a), + xstride, xstride*rectx, rl->rectf+a); + } + + /* passes are allocated in sync */ + for(rpass= rl->passes.first; rpass; rpass= rpass->next) { + int a, xstride= rpass->channels; + for(a=0; a<xstride; a++) + IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a), + xstride, xstride*rectx, rpass->rect+a); + + BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name)); + } + } + + IMB_exr_read_channels(exrhandle); + IMB_exr_close(exrhandle); + + return 1; +} + +/*************************** Combined Pixel Rect *****************************/ + +ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd) +{ + int flags = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE)? IB_cm_predivide: 0; + ImBuf *ibuf= IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, flags); + + /* if not exists, BKE_write_ibuf makes one */ + ibuf->rect= (unsigned int *)rr->rect32; + ibuf->rect_float= rr->rectf; + ibuf->zbuf_float= rr->rectz; + + /* float factor for random dither, imbuf takes care of it */ + ibuf->dither= rd->dither_intensity; + + /* prepare to gamma correct to sRGB color space */ + if (rd->color_mgt_flag & R_COLOR_MANAGEMENT) { + /* sequence editor can generate 8bpc render buffers */ + if (ibuf->rect) { + ibuf->profile = IB_PROFILE_SRGB; + if (BKE_imtype_valid_depths(rd->im_format.imtype) & (R_IMF_CHAN_DEPTH_12|R_IMF_CHAN_DEPTH_16|R_IMF_CHAN_DEPTH_24|R_IMF_CHAN_DEPTH_32)) + IMB_float_from_rect(ibuf); + } else { + ibuf->profile = IB_PROFILE_LINEAR_RGB; + } + } + + /* color -> greyscale */ + /* editing directly would alter the render view */ + if(rd->im_format.planes == R_IMF_PLANES_BW) { + ImBuf *ibuf_bw= IMB_dupImBuf(ibuf); + IMB_color_to_bw(ibuf_bw); + IMB_freeImBuf(ibuf); + ibuf= ibuf_bw; + } + + return ibuf; +} + +void render_result_rect_from_ibuf(RenderResult *rr, RenderData *rd, ImBuf *ibuf) +{ + if(ibuf->rect_float) { + /* color management: when off ensure rectf is non-lin, since thats what the internal + * render engine delivers */ + int profile_to= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB; + int profile_from= (ibuf->profile == IB_PROFILE_LINEAR_RGB)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB; + int predivide= (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); + + if (!rr->rectf) + rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf"); + + IMB_buffer_float_from_float(rr->rectf, ibuf->rect_float, + 4, profile_to, profile_from, predivide, + rr->rectx, rr->recty, rr->rectx, rr->rectx); + + /* TSK! Since sequence render doesn't free the *rr render result, the old rect32 + can hang around when sequence render has rendered a 32 bits one before */ + if(rr->rect32) { + MEM_freeN(rr->rect32); + rr->rect32= NULL; + } + } + else if(ibuf->rect) { + if (!rr->rect32) + rr->rect32= MEM_mallocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect"); + + memcpy(rr->rect32, ibuf->rect, 4*rr->rectx*rr->recty); + + /* Same things as above, old rectf can hang around from previous render. */ + if(rr->rectf) { + MEM_freeN(rr->rectf); + rr->rectf= NULL; + } + } +} + +void render_result_rect_fill_zero(RenderResult *rr) +{ + if (rr->rectf) + memset(rr->rectf, 0, 4*sizeof(float)*rr->rectx*rr->recty); + else if (rr->rect32) + memset(rr->rect32, 0, 4*rr->rectx*rr->recty); + else + rr->rect32= MEM_callocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect"); +} + +void render_result_rect_get_pixels(RenderResult *rr, RenderData *rd, unsigned int *rect, int rectx, int recty) +{ + if(rr->rect32) { + memcpy(rect, rr->rect32, sizeof(int)*rr->rectx*rr->recty); + } + else if(rr->rectf) { + int profile_from= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB; + int predivide= (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); + int dither= 0; + + IMB_buffer_byte_from_float((unsigned char*)rect, rr->rectf, + 4, dither, IB_PROFILE_SRGB, profile_from, predivide, + rr->rectx, rr->recty, rr->rectx, rr->rectx); + } + else + /* else fill with black */ + memset(rect, 0, sizeof(int)*rectx*recty); +} + diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index f9992050052..5fba0bba48c 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -1969,7 +1969,10 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T { auto_bump = shi->obr->ob->derivedFinal->auto_bump_scale; } - auto_bump /= sqrtf((float) (dimx*dimy)); + { + float fVirtDim = sqrtf(fabsf((float) (dimx*dimy)*mtex->size[0]*mtex->size[1])); + auto_bump /= MAX2(fVirtDim, FLT_EPSILON); + } // this variant using a derivative map is described here // http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 96f9918891a..630acf3d88a 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -67,6 +67,7 @@ #include "rayintersection.h" #include "rayobject.h" #include "renderpipeline.h" +#include "render_result.h" #include "render_types.h" #include "renderdatabase.h" #include "occlusion.h" diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 8efe23c38f9..c77a1309743 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -63,6 +63,7 @@ /* local includes */ #include "gammaCorrectionTables.h" #include "pixelblending.h" +#include "render_result.h" #include "render_types.h" #include "renderpipeline.h" #include "renderdatabase.h" diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 43a691770c9..43ed2b3b2b9 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -225,20 +225,8 @@ void wm_event_do_notifiers(bContext *C) if(note->window==win || (note->window == NULL && (note->reference == NULL || note->reference == CTX_data_scene(C)))) { if(note->category==NC_SCENE) { - if(note->data==ND_SCENEBROWSE) { - ED_screen_set_scene(C, note->reference); // XXX hrms, think this over! - if(G.f & G_DEBUG) - printf("scene set %p\n", note->reference); - } - else if(note->data==ND_FRAME) + if(note->data==ND_FRAME) do_anim= 1; - - if(note->action == NA_REMOVED) { - ED_screen_delete_scene(C, note->reference); // XXX hrms, think this over! - if(G.f & G_DEBUG) - printf("scene delete %p\n", note->reference); - } - } } if(ELEM5(note->category, NC_SCENE, NC_OBJECT, NC_GEOM, NC_SCENE, NC_WM)) { |