diff options
author | Julian Eisel <eiseljulian@gmail.com> | 2019-06-21 23:31:01 +0300 |
---|---|---|
committer | Julian Eisel <eiseljulian@gmail.com> | 2019-06-21 23:31:01 +0300 |
commit | 28428b346243bc72ba4c7bc842362cb1cbec38e8 (patch) | |
tree | 3f662976c6e5ccf2e5a991416328215ee1155e0c /source/blender | |
parent | 24146563a01665dca292f16cc1385c23fcb53c82 (diff) | |
parent | ad4f5092ecaf919e415fec4ca62b0172293a2075 (diff) |
Merge branch 'master' into soc-2019-openxr
Diffstat (limited to 'source/blender')
84 files changed, 1597 insertions, 1427 deletions
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc index 9a00140b0fc..de227be0044 100644 --- a/source/blender/alembic/intern/abc_mesh.cc +++ b/source/blender/alembic/intern/abc_mesh.cc @@ -830,7 +830,7 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data) const Int32ArraySamplePtr &face_indices = mesh_data.face_indices; const Int32ArraySamplePtr &face_counts = mesh_data.face_counts; const V2fArraySamplePtr &uvs = mesh_data.uvs; - const size_t uvs_size = uvs->size(); + const size_t uvs_size = uvs == nullptr ? 0 : uvs->size(); const UInt32ArraySamplePtr &uvs_indices = mesh_data.uvs_indices; const N3fArraySamplePtr &normals = mesh_data.face_normals; diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h index 502c949be9a..c1e36f5dd83 100644 --- a/source/blender/blenkernel/BKE_collection.h +++ b/source/blender/blenkernel/BKE_collection.h @@ -176,11 +176,13 @@ typedef void (*BKE_scene_collections_Cb)(struct Collection *ob, void *data); #define FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN(_collection, _object, _mode) \ { \ int _base_flag = (_mode == DAG_EVAL_VIEWPORT) ? BASE_ENABLED_VIEWPORT : BASE_ENABLED_RENDER; \ + int _object_restrict_flag = (_mode == DAG_EVAL_VIEWPORT) ? OB_RESTRICT_VIEWPORT : \ + OB_RESTRICT_RENDER; \ int _base_id = 0; \ for (Base *_base = (Base *)BKE_collection_object_cache_get(_collection).first; _base; \ _base = _base->next, _base_id++) { \ - if (_base->flag & _base_flag) { \ - Object *_object = _base->object; + Object *_object = _base->object; \ + if ((_base->flag & _base_flag) && (_object->restrictflag & _object_restrict_flag) == 0) { #define FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END \ } \ diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 00fd291d7cb..d6683509729 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -320,6 +320,8 @@ float *BKE_image_get_float_pixels_for_frame(struct Image *image, int frame); /* Image modifications */ bool BKE_image_is_dirty(struct Image *image); void BKE_image_mark_dirty(struct Image *image, struct ImBuf *ibuf); +bool BKE_image_buffer_format_writable(struct ImBuf *ibuf); +bool BKE_image_is_dirty_writable(struct Image *image, bool *is_format_writable); /* Guess offset for the first frame in the sequence */ int BKE_image_sequence_guess_offset(struct Image *image); diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index ca3a560286f..164dbbbf482 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -38,7 +38,6 @@ struct ParticleKey; struct ParticleSettings; struct ParticleSystem; struct ParticleSystemModifierData; -struct ParticleSystemModifierDataRuntime; struct BVHTreeRay; struct BVHTreeRayHit; @@ -609,13 +608,6 @@ float psys_get_current_display_percentage(struct ParticleSystem *psys, #define DMCACHE_NOTFOUND -1 #define DMCACHE_ISCHILD -2 -/* **** Particle system modifier helpers. **** */ - -struct Mesh *BKE_particle_modifier_mesh_final_get(struct ParticleSystemModifierData *psmd); -struct Mesh *BKE_particle_modifier_mesh_original_get(struct ParticleSystemModifierData *psmd); -struct ParticleSystemModifierDataRuntime *BKE_particle_modifier_runtime_ensure( - struct ParticleSystemModifierData *psmd); - /* **** Depsgraph evaluation **** */ struct Depsgraph; diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 5b718909601..ac55846714b 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -443,15 +443,13 @@ static void collection_object_cache_fill(ListBase *lb, Collection *collection, i BLI_addtail(lb, base); } - int object_restrict = base->object->restrictflag; - - if (((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0) && - ((object_restrict & OB_RESTRICT_VIEWPORT) == 0)) { + /* Only collection flags are checked here currently, object restrict flag is checked + * in FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN since it can be animated + * without updating the cache. */ + if (((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0)) { base->flag |= BASE_ENABLED_VIEWPORT; } - - if (((child_restrict & COLLECTION_RESTRICT_RENDER) == 0) && - ((object_restrict & OB_RESTRICT_RENDER) == 0)) { + if (((child_restrict & COLLECTION_RESTRICT_RENDER) == 0)) { base->flag |= BASE_ENABLED_RENDER; } } diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 9b7a6002035..76098db5fd1 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -1888,7 +1888,7 @@ bool CustomData_merge(const struct CustomData *source, else if ((maxnumber != -1) && (number >= maxnumber)) { continue; } - else if (CustomData_get_layer_named(dest, type, layer->name)) { + else if (CustomData_get_named_layer_index(dest, type, layer->name) != -1) { continue; } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index f3ef48cafa8..5c23987a8d9 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -4812,7 +4812,7 @@ void BKE_image_user_frame_calc(Image *ima, ImageUser *iuser, int cfra) iuser->framenr = framenr; - if (ima && ima->gpuframenr != framenr) { + if (ima && BKE_image_is_animated(ima) && ima->gpuframenr != framenr) { /* Note: a single texture and refresh doesn't really work when * multiple image users may use different frames, this is to * be improved with perhaps a GPU texture cache. */ @@ -5075,9 +5075,10 @@ bool BKE_image_is_animated(Image *image) } /* Image modifications */ -bool BKE_image_is_dirty(Image *image) +bool BKE_image_is_dirty_writable(Image *image, bool *r_is_writable) { bool is_dirty = false; + bool is_writable = false; BLI_spin_lock(&image_spin); if (image->cache != NULL) { @@ -5086,6 +5087,7 @@ bool BKE_image_is_dirty(Image *image) while (!IMB_moviecacheIter_done(iter)) { ImBuf *ibuf = IMB_moviecacheIter_getImBuf(iter); if (ibuf->userflags & IB_BITMAPDIRTY) { + is_writable = BKE_image_buffer_format_writable(ibuf); is_dirty = true; break; } @@ -5095,14 +5097,31 @@ bool BKE_image_is_dirty(Image *image) } BLI_spin_unlock(&image_spin); + if (r_is_writable) { + *r_is_writable = is_writable; + } + return is_dirty; } +bool BKE_image_is_dirty(Image *image) +{ + return BKE_image_is_dirty_writable(image, NULL); +} + void BKE_image_mark_dirty(Image *UNUSED(image), ImBuf *ibuf) { ibuf->userflags |= IB_BITMAPDIRTY; } +bool BKE_image_buffer_format_writable(ImBuf *ibuf) +{ + ImageFormatData im_format; + ImbFormatOptions options_dummy; + BKE_imbuf_to_image_format(&im_format, ibuf); + return (BKE_image_imtype_to_ftype(im_format.imtype, &options_dummy) == ibuf->ftype); +} + void BKE_image_file_format_set(Image *image, int ftype, const ImbFormatOptions *options) { BLI_spin_lock(&image_spin); diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index c377223d14b..6bc83f8dd09 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -67,6 +67,8 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" +#include "GPU_texture.h" + #ifdef WITH_OPENEXR # include "intern/openexr/openexr_multi.h" #endif @@ -1353,6 +1355,17 @@ static void free_buffers(MovieClip *clip) IMB_free_anim(clip->anim); clip->anim = NULL; } + + MovieClip_RuntimeGPUTexture *tex; + for (tex = clip->runtime.gputextures.first; tex; tex = tex->next) { + for (int i = 0; i < TEXTARGET_COUNT; i++) { + if (tex->gputexture[i] != NULL) { + GPU_texture_free(tex->gputexture[i]); + tex->gputexture[i] = NULL; + } + } + } + BLI_freelistN(&clip->runtime.gputextures); } void BKE_movieclip_clear_cache(MovieClip *clip) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index e74b2b0f671..2a66edc8d42 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -497,13 +497,12 @@ void BKE_object_free_caches(Object *object) for (md = object->modifiers.first; md != NULL; md = md->next) { if (md->type == eModifierType_ParticleSystem) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; - ParticleSystemModifierDataRuntime *psmd_runtime = BKE_particle_modifier_runtime_ensure(psmd); - if (psmd_runtime->mesh_final) { - BKE_id_free(NULL, psmd_runtime->mesh_final); - psmd_runtime->mesh_final = NULL; - if (psmd_runtime->mesh_original) { - BKE_id_free(NULL, psmd_runtime->mesh_original); - psmd_runtime->mesh_original = NULL; + if (psmd->mesh_final) { + BKE_id_free(NULL, psmd->mesh_final); + psmd->mesh_final = NULL; + if (psmd->mesh_original) { + BKE_id_free(NULL, psmd->mesh_original); + psmd->mesh_original = NULL; } psmd->flag |= eParticleSystemFlag_file_loaded; update_flag |= ID_RECALC_GEOMETRY; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 61ee5685451..13649eaf096 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1889,8 +1889,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, float vtan[3], float orco[3]) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - if (psmd && mesh_final) { + if (psmd && psmd->mesh_final) { if (psmd->psys->part->distr == PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT) { if (vec) { copy_v3_v3(vec, fuv); @@ -1903,7 +1902,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, } /* we cant use the num_dmcache */ psys_particle_on_dm( - mesh_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco); + psmd->mesh_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco); } else { psys_particle_on_shape(from, index, fuv, vec, nor, utan, vtan, orco); @@ -2254,15 +2253,13 @@ void psys_find_parents(ParticleSimulationData *sim, const bool use_render_params tree = BLI_kdtree_3d_new(totparent); - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); - for (p = 0, cpa = sim->psys->child; p < totparent; p++, cpa++) { psys_particle_on_emitter( sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco); /* Check if particle doesn't exist because of texture influence. * Insert only existing particles into kdtree. */ - get_cpa_texture(mesh_final, + get_cpa_texture(sim->psmd->mesh_final, psys, part, psys->particles + cpa->pa[0], @@ -2430,8 +2427,6 @@ static void psys_thread_create_path(ParticleTask *task, return; } - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(ctx->sim.psmd); - if (ctx->between) { ParticleData *pa = psys->particles + cpa->pa[0]; int w, needupdate; @@ -2536,7 +2531,7 @@ static void psys_thread_create_path(ParticleTask *task, sub_v3_v3v3(off1[w], co, key[w]->co); } - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, ctx->sim.psmd->mesh_final, psys->part->from, pa, hairmat); } else { ParticleData *pa = psys->particles + cpa->parent; @@ -2567,7 +2562,7 @@ static void psys_thread_create_path(ParticleTask *task, pa->num_dmcache; /* XXX hack to avoid messed up particle num and subsequent crash (#40733) */ - if (cpa_num > mesh_final->totface) { + if (cpa_num > ctx->sim.psmd->mesh_final->totface) { cpa_num = 0; } cpa_fuv = pa->fuv; @@ -2584,7 +2579,7 @@ static void psys_thread_create_path(ParticleTask *task, 0, orco); - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, ctx->sim.psmd->mesh_final, psys->part->from, pa, hairmat); } child_keys->segments = ctx->segments; @@ -2930,21 +2925,19 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re copy_v3_v3(col, &ma->r); } - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - if ((psys->flag & PSYS_GLOBAL_HAIR) == 0) { if ((psys->part->flag & PART_CHILD_EFFECT) == 0) { - vg_effector = psys_cache_vgroup(mesh_final, psys, PSYS_VG_EFFECTOR); + vg_effector = psys_cache_vgroup(psmd->mesh_final, psys, PSYS_VG_EFFECTOR); } if (!psys->totchild) { - vg_length = psys_cache_vgroup(mesh_final, psys, PSYS_VG_LENGTH); + vg_length = psys_cache_vgroup(psmd->mesh_final, psys, PSYS_VG_LENGTH); } } /* ensure we have tessfaces to be used for mapping */ if (part->from != PART_FROM_VERT) { - BKE_mesh_tessface_ensure(mesh_final); + BKE_mesh_tessface_ensure(psmd->mesh_final); } /*---first main loop: create all actual particles' paths---*/ @@ -2954,7 +2947,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.f); pa_length = ptex.length * (1.0f - part->randlength * psys_frand(psys, psys->seed + p)); if (vg_length) { - pa_length *= psys_particle_value_from_verts(mesh_final, part->from, pa, vg_length); + pa_length *= psys_particle_value_from_verts(psmd->mesh_final, part->from, pa, vg_length); } } @@ -2972,7 +2965,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re init_particle_interpolation(sim->ob, sim->psys, pa, &pind); /* hairmat is needed for for non-hair particle too so we get proper rotations */ - psys_mat_hair_to_global(sim->ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, psmd->mesh_final, psys->part->from, pa, hairmat); copy_v3_v3(rotmat[0], hairmat[2]); copy_v3_v3(rotmat[1], hairmat[1]); copy_v3_v3(rotmat[2], hairmat[0]); @@ -3030,7 +3023,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re float effector = 1.0f; if (vg_effector) { effector *= psys_particle_value_from_verts( - mesh_final, psys->part->from, pa, vg_effector); + psmd->mesh_final, psys->part->from, pa, vg_effector); } sub_v3_v3v3(vec, (cache[p] + 1)->co, cache[p]->co); @@ -3165,8 +3158,7 @@ static void psys_cache_edit_paths_iter(void *__restrict iter_data_v, init_particle_interpolation(ob, psys, pa, &pind); if (psys) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, pa, hairmat); copy_v3_v3(rotmat[0], hairmat[2]); copy_v3_v3(rotmat[1], hairmat[1]); copy_v3_v3(rotmat[2], hairmat[0]); @@ -4046,9 +4038,8 @@ void psys_get_texture( mul_m4_v3(mtex->object->imat, texvec); } break; - case TEXCO_UV: { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); - if (get_particle_uv(mesh_final, + case TEXCO_UV: + if (get_particle_uv(sim->psmd->mesh_final, pa, 0, pa->fuv, @@ -4059,7 +4050,6 @@ void psys_get_texture( } /* no break, failed to get uv's, so let's try orco's */ ATTR_FALLTHROUGH; - } case TEXCO_ORCO: psys_particle_on_emitter(sim->psmd, sim->psys->part->from, @@ -4333,8 +4323,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, } else if (!keyed && !cached && !(psys->flag & PSYS_GLOBAL_HAIR)) { if ((pa->flag & PARS_REKEY) == 0) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); - psys_mat_hair_to_global(sim->ob, mesh_final, part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, part->from, pa, hairmat); mul_m4_v3(hairmat, state->co); mul_mat3_m4_v3(hairmat, state->vel); @@ -4416,8 +4405,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, 0, par_orco); if (part->type == PART_HAIR) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - psys_mat_hair_to_global(sim->ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat); } else { unit_m4(hairmat); @@ -4449,10 +4437,9 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, 0, par_orco); if (part->type == PART_HAIR) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); psys_particle_on_emitter( psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, 0, 0, 0, orco); - psys_mat_hair_to_global(sim->ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat); } else { copy_v3_v3(orco, cpa->fuv); @@ -4463,7 +4450,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, /* get different child parameters from textures & vgroups */ memset(&ctx, 0, sizeof(ParticleThreadContext)); ctx.sim = *sim; - ctx.mesh = BKE_particle_modifier_mesh_final_get(psmd); + ctx.mesh = psmd->mesh_final; ctx.ma = ma; /* TODO: assign vertex groups */ get_child_modifier_parameters(part, &ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex); @@ -4728,16 +4715,14 @@ void psys_get_dupli_texture(ParticleSystem *psys, /* Grid distribution doesn't support UV or emit from vertex mode */ bool is_grid = (part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT); - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - if (cpa) { - if ((part->childtype == PART_CHILD_FACES) && (mesh_final != NULL)) { - CustomData *mtf_data = &mesh_final->fdata; + if ((part->childtype == PART_CHILD_FACES) && (psmd->mesh_final != NULL)) { + CustomData *mtf_data = &psmd->mesh_final->fdata; const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE); mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx); if (mtface && !is_grid) { - mface = CustomData_get(&mesh_final->fdata, cpa->num, CD_MFACE); + mface = CustomData_get(&psmd->mesh_final->fdata, cpa->num, CD_MFACE); mtface += cpa->num; psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv); } @@ -4760,8 +4745,8 @@ void psys_get_dupli_texture(ParticleSystem *psys, } } - if ((part->from == PART_FROM_FACE) && (mesh_final != NULL) && !is_grid) { - CustomData *mtf_data = &mesh_final->fdata; + if ((part->from == PART_FROM_FACE) && (psmd->mesh_final != NULL) && !is_grid) { + CustomData *mtf_data = &psmd->mesh_final->fdata; const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE); mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx); @@ -4771,14 +4756,14 @@ void psys_get_dupli_texture(ParticleSystem *psys, num = pa->num; } - if (num >= mesh_final->totface) { + if (num >= psmd->mesh_final->totface) { /* happens when simplify is enabled * gives invalid coords but would crash otherwise */ num = DMCACHE_NOTFOUND; } if (mtface && !ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { - mface = CustomData_get(&mesh_final->fdata, num, CD_MFACE); + mface = CustomData_get(&psmd->mesh_final->fdata, num, CD_MFACE); mtface += num; psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv); } @@ -4899,10 +4884,8 @@ void psys_apply_hair_lattice(Depsgraph *depsgraph, Scene *scene, Object *ob, Par int p, h; float hairmat[4][4], imat[4][4]; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim.psmd); - for (p = 0; p < psys->totpart; p++, pa++) { - psys_mat_hair_to_global(sim.ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, psys->part->from, pa, hairmat); invert_m4_m4(imat, hairmat); hkey = pa->hair; @@ -4937,40 +4920,3 @@ void BKE_particle_batch_cache_free(ParticleSystem *psys) BKE_particle_batch_cache_free_cb(psys); } } - -/* **** Particle system modifier helpers. **** */ - -Mesh *BKE_particle_modifier_mesh_final_get(ParticleSystemModifierData *psmd) -{ - if (psmd == NULL) { - return NULL; - } - ParticleSystemModifierDataRuntime *runtime = psmd->modifier.runtime; - if (runtime == NULL) { - return NULL; - } - return runtime->mesh_final; -} - -Mesh *BKE_particle_modifier_mesh_original_get(ParticleSystemModifierData *psmd) -{ - if (psmd == NULL) { - return NULL; - } - ParticleSystemModifierDataRuntime *runtime = psmd->modifier.runtime; - if (runtime == NULL) { - return NULL; - } - return runtime->mesh_original; -} - -ParticleSystemModifierDataRuntime *BKE_particle_modifier_runtime_ensure( - ParticleSystemModifierData *psmd) -{ - BLI_assert(psmd != NULL); - if (psmd->modifier.runtime == NULL) { - psmd->modifier.runtime = MEM_callocN(sizeof(ParticleSystemModifierDataRuntime), - "psmd runtime"); - } - return psmd->modifier.runtime; -} diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index 7bb2daeab23..070c3c7a566 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -878,7 +878,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, int from) { Scene *scene = sim->scene; - Mesh *final_mesh = BKE_particle_modifier_mesh_final_get(sim->psmd); + Mesh *final_mesh = sim->psmd->mesh_final; Object *ob = sim->ob; ParticleSystem *psys = sim->psys; ParticleData *pa = 0, *tpars = 0; @@ -926,8 +926,8 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, if (from == PART_FROM_CHILD) { /* Simple children */ if (part->childtype != PART_CHILD_FACES) { - Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(sim->psmd); - distribute_simple_children(scene, ob, final_mesh, mesh_original, psys, use_render_params); + distribute_simple_children( + scene, ob, final_mesh, sim->psmd->mesh_original, psys, use_render_params); return 0; } } @@ -1318,7 +1318,7 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from) TaskPool *task_pool; ParticleThreadContext ctx; ParticleTask *tasks; - Mesh *final_mesh = BKE_particle_modifier_mesh_final_get(sim->psmd); + Mesh *final_mesh = sim->psmd->mesh_final; int i, totpart, numtasks; /* create a task pool for distribution tasks */ @@ -1346,8 +1346,7 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from) BLI_task_pool_free(task_pool); - Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(sim->psmd); - psys_calc_dmcache(sim->ob, final_mesh, mesh_original, sim->psys); + psys_calc_dmcache(sim->ob, final_mesh, sim->psmd->mesh_original, sim->psys); if (ctx.mesh != final_mesh) { BKE_id_free(NULL, ctx.mesh); @@ -1372,8 +1371,7 @@ void distribute_particles(ParticleSimulationData *sim, int from) int distr_error = 0; if (psmd) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - if (mesh_final) { + if (psmd->mesh_final) { distribute_particles_on_dm(sim, from); } else { diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 1b0655c6734..27722aab2d9 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -467,7 +467,7 @@ void psys_thread_context_init(ParticleThreadContext *ctx, ParticleSimulationData { memset(ctx, 0, sizeof(ParticleThreadContext)); ctx->sim = *sim; - ctx->mesh = BKE_particle_modifier_mesh_final_get(ctx->sim.psmd); + ctx->mesh = ctx->sim.psmd->mesh_final; ctx->ma = give_current_material(sim->ob, sim->psys->part->omat); } @@ -3348,7 +3348,6 @@ static void hair_create_input_mesh(ParticleSimulationData *sim, /* make vgroup for pin roots etc.. */ hair_index = 1; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); LOOP_PARTICLES { if (!(pa->flag & PARS_UNEXIST)) { @@ -3359,7 +3358,7 @@ static void hair_create_input_mesh(ParticleSimulationData *sim, pa->hair_index = hair_index; use_hair = psys_hair_use_simulation(pa, max_length); - psys_mat_hair_to_object(sim->ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_object(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat); mul_m4_m4m4(root_mat, sim->ob->obmat, hairmat); normalize_m4(root_mat); @@ -3525,9 +3524,7 @@ static void hair_step(ParticleSimulationData *sim, float cfra, const bool use_re if (psys->recalc & ID_RECALC_PSYS_RESET) { /* need this for changing subsurf levels */ - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); - Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(sim->psmd); - psys_calc_dmcache(sim->ob, mesh_final, mesh_original, psys); + psys_calc_dmcache(sim->ob, sim->psmd->mesh_final, sim->psmd->mesh_original, psys); if (psys->clmd) { cloth_free_modifier(psys->clmd); @@ -3579,8 +3576,7 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)) if (pa->totkey) { sub_v3_v3(key->co, root->co); - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); - psys_vec_rot_to_face(mesh_final, pa, key->co); + psys_vec_rot_to_face(sim->psmd->mesh_final, pa, key->co); } key->time = pa->state.time; @@ -4614,13 +4610,12 @@ void particle_system_update(struct Depsgraph *depsgraph, } } - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim.psmd); - if (!mesh_final) { + if (!sim.psmd->mesh_final) { return; } if (part->from != PART_FROM_VERT) { - BKE_mesh_tessface_ensure(mesh_final); + BKE_mesh_tessface_ensure(sim.psmd->mesh_final); } /* to verify if we need to restore object afterwards */ diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 2514bad5709..971ca77ff3d 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -3578,7 +3578,8 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, re = RE_NewSceneRender(scene); } - RE_RenderFrame(re, context->bmain, scene, view_layer, camera, frame, false); + RE_RenderFrame( + re, context->bmain, scene, have_comp ? NULL : view_layer, camera, frame, false); /* restore previous state after it was toggled on & off by RE_RenderFrame */ G.is_rendering = is_rendering; diff --git a/source/blender/blenlib/intern/timecode.c b/source/blender/blenlib/intern/timecode.c index 9b6ed00c704..228f656949c 100644 --- a/source/blender/blenlib/intern/timecode.c +++ b/source/blender/blenlib/intern/timecode.c @@ -213,7 +213,7 @@ size_t BLI_timecode_string_from_time_simple(char *str, const int hr = ((int)time_seconds) / (60 * 60); const int min = (((int)time_seconds) / 60) % 60; const int sec = ((int)time_seconds) % 60; - const int hun = ((int)(time_seconds * 100.0)) % 100; + const int hun = ((int)(fmod(time_seconds, 1.0) * 100)); if (hr) { rlen = BLI_snprintf(str, maxncpy, "%.2d:%.2d:%.2d.%.2d", hr, min, sec, hun); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index edc3c7fe555..cdd174d5e0b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2038,6 +2038,7 @@ void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain) for (; clip; clip = clip->id.next) { clip->cache = newmclipadr(fd, clip->cache); clip->tracking.camera.intrinsics = newmclipadr(fd, clip->tracking.camera.intrinsics); + BLI_freelistN(&clip->runtime.gputextures); } for (; sce; sce = sce->id.next) { @@ -5668,6 +5669,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) else if (md->type == eModifierType_ParticleSystem) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; + psmd->mesh_final = NULL; + psmd->mesh_original = NULL; psmd->psys = newdataadr(fd, psmd->psys); psmd->flag &= ~eParticleSystemFlag_psys_updated; psmd->flag |= eParticleSystemFlag_file_loaded; diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h index 00bb02d7205..4148529d3f8 100644 --- a/source/blender/depsgraph/DEG_depsgraph_query.h +++ b/source/blender/depsgraph/DEG_depsgraph_query.h @@ -85,16 +85,6 @@ void DEG_get_customdata_mask_for_object(const struct Depsgraph *graph, * one. Assert will happen if it's not. */ struct Scene *DEG_get_evaluated_scene(const struct Depsgraph *graph); -/* Similar to DEG_get_evaluated_scene(), but allows to access non-fully evaluated pointer without - * causing asserts or crashes. Works the following way: - * - If the scene was never evaluated NULL returned. - * - Otherwise the last known state of the scene is returned. - * - * Use in exceptional case if it's absolutely must to. - * - * Allows to pass depsgraph == NULL, will return NULL in that case. */ -struct Scene *DEG_get_evaluated_scene_if_exists(const struct Depsgraph *graph); - /* Get view layer at its evaluated state. * This is a shortcut for accessing active view layer from evaluated scene. */ struct ViewLayer *DEG_get_evaluated_view_layer(const struct Depsgraph *graph); diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc index 48dbd4b0945..f821af8cdc7 100644 --- a/source/blender/depsgraph/intern/depsgraph_query.cc +++ b/source/blender/depsgraph/intern/depsgraph_query.cc @@ -160,19 +160,6 @@ Scene *DEG_get_evaluated_scene(const Depsgraph *graph) return scene_cow; } -Scene *DEG_get_evaluated_scene_if_exists(const Depsgraph *graph) -{ - if (graph == NULL) { - return NULL; - } - const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph); - Scene *scene_cow = deg_graph->scene_cow; - if (scene_cow == NULL || !DEG::deg_copy_on_write_is_expanded(&scene_cow->id)) { - return NULL; - } - return scene_cow; -} - ViewLayer *DEG_get_evaluated_view_layer(const Depsgraph *graph) { const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph); diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 44551a4e04b..8631a9f556b 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -249,6 +249,7 @@ data_to_c_simple(engines/workbench/shaders/workbench_volume_vert.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_volume_frag.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_world_light_lib.glsl SRC) +data_to_c_simple(modes/shaders/common_colormanagement_lib.glsl SRC) data_to_c_simple(modes/shaders/common_globals_lib.glsl SRC) data_to_c_simple(modes/shaders/common_hair_lib.glsl SRC) data_to_c_simple(modes/shaders/common_hair_refine_vert.glsl SRC) @@ -295,6 +296,8 @@ data_to_c_simple(modes/shaders/overlay_face_orientation_vert.glsl SRC) data_to_c_simple(modes/shaders/overlay_face_wireframe_vert.glsl SRC) data_to_c_simple(modes/shaders/overlay_face_wireframe_geom.glsl SRC) data_to_c_simple(modes/shaders/overlay_face_wireframe_frag.glsl SRC) +data_to_c_simple(modes/shaders/object_camera_image_frag.glsl SRC) +data_to_c_simple(modes/shaders/object_camera_image_vert.glsl SRC) data_to_c_simple(modes/shaders/object_empty_axes_vert.glsl SRC) data_to_c_simple(modes/shaders/object_empty_image_frag.glsl SRC) data_to_c_simple(modes/shaders/object_empty_image_vert.glsl SRC) @@ -325,6 +328,7 @@ data_to_c_simple(modes/shaders/paint_wire_vert.glsl SRC) data_to_c_simple(modes/shaders/paint_vert_frag.glsl SRC) data_to_c_simple(modes/shaders/particle_strand_frag.glsl SRC) data_to_c_simple(modes/shaders/particle_strand_vert.glsl SRC) +data_to_c_simple(modes/shaders/pose_selection_vert.glsl SRC) data_to_c_simple(modes/shaders/sculpt_mask_vert.glsl SRC) data_to_c_simple(modes/shaders/volume_velocity_vert.glsl SRC) diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index 6d1227bb0a8..ae3bf8cead6 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -61,6 +61,7 @@ extern char datatoc_gpencil_edit_point_geom_glsl[]; extern char datatoc_gpencil_edit_point_frag_glsl[]; extern char datatoc_gpencil_blend_frag_glsl[]; +extern char datatoc_common_colormanagement_lib_glsl[]; extern char datatoc_common_view_lib_glsl[]; /* *********** STATIC *********** */ @@ -169,29 +170,37 @@ static void GPENCIL_create_shaders(void) { /* normal fill shader */ if (!e_data.gpencil_fill_sh) { - e_data.gpencil_fill_sh = DRW_shader_create_with_lib(datatoc_gpencil_fill_vert_glsl, - NULL, - datatoc_gpencil_fill_frag_glsl, - datatoc_common_view_lib_glsl, - NULL); + e_data.gpencil_fill_sh = GPU_shader_create_from_arrays({ + .vert = + (const char *[]){datatoc_common_view_lib_glsl, datatoc_gpencil_fill_vert_glsl, NULL}, + .frag = (const char *[]){datatoc_common_colormanagement_lib_glsl, + datatoc_gpencil_fill_frag_glsl, + NULL}, + }); } /* normal stroke shader using geometry to display lines (line mode) */ if (!e_data.gpencil_stroke_sh) { - e_data.gpencil_stroke_sh = DRW_shader_create_with_lib(datatoc_gpencil_stroke_vert_glsl, - datatoc_gpencil_stroke_geom_glsl, - datatoc_gpencil_stroke_frag_glsl, - datatoc_common_view_lib_glsl, - NULL); + e_data.gpencil_stroke_sh = GPU_shader_create_from_arrays({ + .vert = + (const char *[]){datatoc_common_view_lib_glsl, datatoc_gpencil_stroke_vert_glsl, NULL}, + .geom = (const char *[]){datatoc_gpencil_stroke_geom_glsl, NULL}, + .frag = (const char *[]){datatoc_common_colormanagement_lib_glsl, + datatoc_gpencil_stroke_frag_glsl, + NULL}, + }); } /* dot/rectangle mode for normal strokes using geometry */ if (!e_data.gpencil_point_sh) { - e_data.gpencil_point_sh = DRW_shader_create_with_lib(datatoc_gpencil_point_vert_glsl, - datatoc_gpencil_point_geom_glsl, - datatoc_gpencil_point_frag_glsl, - datatoc_common_view_lib_glsl, - NULL); + e_data.gpencil_point_sh = GPU_shader_create_from_arrays({ + .vert = + (const char *[]){datatoc_common_view_lib_glsl, datatoc_gpencil_point_vert_glsl, NULL}, + .geom = (const char *[]){datatoc_gpencil_point_geom_glsl, NULL}, + .frag = (const char *[]){datatoc_common_colormanagement_lib_glsl, + datatoc_gpencil_point_frag_glsl, + NULL}, + }); } /* used for edit points or strokes with one point only */ if (!e_data.gpencil_edit_point_sh) { diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl index 1fdfd05332e..87bf116ff89 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl @@ -90,31 +90,6 @@ void set_color(in vec4 color, ocolor.a *= layer_opacity; } -float linearrgb_to_srgb(float c) -{ - if (c < 0.0031308) { - return (c < 0.0) ? 0.0 : c * 12.92; - } - else { - return 1.055 * pow(c, 1.0 / 2.4) - 0.055; - } -} - -vec4 texture_read_as_srgb(sampler2D tex, bool premultiplied, vec2 co) -{ - /* By convention image textures return scene linear colors, but - * grease pencil still works in srgb. */ - vec4 color = texture(tex, co); - /* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */ - if (premultiplied && !(color.a == 0.0 || color.a == 1.0)) { - color.rgb = color.rgb / color.a; - } - color.r = linearrgb_to_srgb(color.r); - color.g = linearrgb_to_srgb(color.g); - color.b = linearrgb_to_srgb(color.b); - return color; -} - void main() { vec2 t_center = vec2(0.5, 0.5); diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl index 7fed42aca0d..34777018a73 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl @@ -48,31 +48,6 @@ vec2 check_box_point(vec2 pt, vec2 radius) return rtn; } -float linearrgb_to_srgb(float c) -{ - if (c < 0.0031308) { - return (c < 0.0) ? 0.0 : c * 12.92; - } - else { - return 1.055 * pow(c, 1.0 / 2.4) - 0.055; - } -} - -vec4 texture_read_as_srgb(sampler2D tex, bool premultiplied, vec2 co) -{ - /* By convention image textures return scene linear colors, but - * grease pencil still works in srgb. */ - vec4 color = texture(tex, co); - /* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */ - if (premultiplied && !(color.a == 0.0 || color.a == 1.0)) { - color.rgb = color.rgb / color.a; - } - color.r = linearrgb_to_srgb(color.r); - color.g = linearrgb_to_srgb(color.g); - color.b = linearrgb_to_srgb(color.b); - return color; -} - void main() { vec2 centered = mTexCoord - vec2(0.5); diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl index bc703d2a078..73baacb35d4 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl @@ -28,31 +28,6 @@ out vec4 fragColor; bool no_texture = (shading_type[0] == OB_SOLID) && (shading_type[1] != V3D_SHADING_TEXTURE_COLOR); -float linearrgb_to_srgb(float c) -{ - if (c < 0.0031308) { - return (c < 0.0) ? 0.0 : c * 12.92; - } - else { - return 1.055 * pow(c, 1.0 / 2.4) - 0.055; - } -} - -vec4 texture_read_as_srgb(sampler2D tex, bool premultiplied, vec2 co) -{ - /* By convention image textures return scene linear colors, but - * grease pencil still works in srgb. */ - vec4 color = texture(tex, co); - /* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */ - if (premultiplied && !(color.a == 0.0 || color.a == 1.0)) { - color.rgb = color.rgb / color.a; - } - color.r = linearrgb_to_srgb(color.r); - color.g = linearrgb_to_srgb(color.g); - color.b = linearrgb_to_srgb(color.b); - return color; -} - void main() { diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index 467626bf2c8..c66a737d684 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -301,15 +301,14 @@ static void particle_calculate_parent_uvs(ParticleSystem *psys, return; } ParticleData *particle = &psys->particles[parent_index]; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); int num = particle->num_dmcache; if (num == DMCACHE_NOTFOUND || num == DMCACHE_ISCHILD) { - if (particle->num < mesh_final->totface) { + if (particle->num < psmd->mesh_final->totface) { num = particle->num; } } if (num != DMCACHE_NOTFOUND && num != DMCACHE_ISCHILD) { - MFace *mface = &mesh_final->mface[num]; + MFace *mface = &psmd->mesh_final->mface[num]; for (int j = 0; j < num_uv_layers; j++) { psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]); } @@ -331,17 +330,16 @@ static void particle_calculate_parent_mcol(ParticleSystem *psys, return; } ParticleData *particle = &psys->particles[parent_index]; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); int num = particle->num_dmcache; if (num == DMCACHE_NOTFOUND || num == DMCACHE_ISCHILD) { - if (particle->num < mesh_final->totface) { + if (particle->num < psmd->mesh_final->totface) { num = particle->num; } } if (num != DMCACHE_NOTFOUND && num != DMCACHE_ISCHILD) { - MFace *mface = &mesh_final->mface[num]; + MFace *mface = &psmd->mesh_final->mface[num]; for (int j = 0; j < num_col_layers; j++) { - psys_interpolate_mcol(mcols[j] + num * 4, mface->v4, particle->fuv, &r_mcol[j]); + psys_interpolate_mcol(mcols[j] + num, mface->v4, particle->fuv, &r_mcol[j]); } } } @@ -363,9 +361,8 @@ static void particle_interpolate_children_uvs(ParticleSystem *psys, } ChildParticle *particle = &psys->child[child_index]; int num = particle->num; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); if (num != DMCACHE_NOTFOUND) { - MFace *mface = &mesh_final->mface[num]; + MFace *mface = &psmd->mesh_final->mface[num]; for (int j = 0; j < num_uv_layers; j++) { psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]); } @@ -387,10 +384,9 @@ static void particle_interpolate_children_mcol(ParticleSystem *psys, return; } ChildParticle *particle = &psys->child[child_index]; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); int num = particle->num; if (num != DMCACHE_NOTFOUND) { - MFace *mface = &mesh_final->mface[num]; + MFace *mface = &psmd->mesh_final->mface[num]; for (int j = 0; j < num_col_layers; j++) { psys_interpolate_mcol(mcols[j] + num * 4, mface->v4, particle->fuv, &r_mcol[j]); } @@ -842,16 +838,15 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit int active_col = 0; ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - if (psmd != NULL && mesh_final != NULL) { - if (CustomData_has_layer(&mesh_final->ldata, CD_MLOOPUV)) { - cache->num_uv_layers = CustomData_number_of_layers(&mesh_final->ldata, CD_MLOOPUV); - active_uv = CustomData_get_active_layer(&mesh_final->ldata, CD_MLOOPUV); + if (psmd != NULL && psmd->mesh_final != NULL) { + if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPUV)) { + cache->num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPUV); + active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPUV); } - if (CustomData_has_layer(&mesh_final->ldata, CD_MLOOPCOL)) { - cache->num_col_layers = CustomData_number_of_layers(&mesh_final->ldata, CD_MLOOPCOL); - active_col = CustomData_get_active_layer(&mesh_final->ldata, CD_MLOOPCOL); + if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL)) { + cache->num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPCOL); + active_col = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL); } } @@ -895,7 +890,7 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit GPU_vertbuf_data_alloc(cache->proc_uv_buf[i], cache->strands_len); GPU_vertbuf_attr_get_raw_data(cache->proc_uv_buf[i], uv_id, &uv_step[i]); - const char *name = CustomData_get_layer_name(&mesh_final->ldata, CD_MLOOPUV, i); + const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i); uint hash = BLI_ghashutil_strhash_p(name); int n = 0; BLI_snprintf(cache->uv_layer_names[i][n++], MAX_LAYER_NAME_LEN, "u%u", hash); @@ -911,13 +906,13 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit GPU_vertbuf_data_alloc(cache->proc_col_buf[i], cache->strands_len); GPU_vertbuf_attr_get_raw_data(cache->proc_col_buf[i], col_id, &col_step[i]); - const char *name = CustomData_get_layer_name(&mesh_final->ldata, CD_MLOOPCOL, i); + const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPCOL, i); uint hash = BLI_ghashutil_strhash_p(name); int n = 0; BLI_snprintf(cache->col_layer_names[i][n++], MAX_LAYER_NAME_LEN, "c%u", hash); /* We only do vcols auto name that are not overridden by uvs */ - if (CustomData_get_named_layer_index(&mesh_final->ldata, CD_MLOOPUV, name) == -1) { + if (CustomData_get_named_layer_index(&psmd->mesh_final->ldata, CD_MLOOPUV, name) == -1) { BLI_snprintf(cache->col_layer_names[i][n++], MAX_LAYER_NAME_LEN, "a%u", hash); } @@ -927,15 +922,15 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit } if (cache->num_uv_layers || cache->num_col_layers) { - BKE_mesh_tessface_ensure(mesh_final); + BKE_mesh_tessface_ensure(psmd->mesh_final); if (cache->num_uv_layers) { for (int j = 0; j < cache->num_uv_layers; j++) { - mtfaces[j] = (MTFace *)CustomData_get_layer_n(&mesh_final->fdata, CD_MTFACE, j); + mtfaces[j] = (MTFace *)CustomData_get_layer_n(&psmd->mesh_final->fdata, CD_MTFACE, j); } } if (cache->num_col_layers) { for (int j = 0; j < cache->num_col_layers; j++) { - mcols[j] = (MCol *)CustomData_get_layer_n(&mesh_final->fdata, CD_MCOL, j); + mcols[j] = (MCol *)CustomData_get_layer_n(&psmd->mesh_final->fdata, CD_MCOL, j); } } } @@ -1148,16 +1143,14 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, float(**parent_uvs)[2] = NULL; MCol **parent_mcol = NULL; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - if (psmd != NULL) { - if (CustomData_has_layer(&mesh_final->ldata, CD_MLOOPUV)) { - num_uv_layers = CustomData_number_of_layers(&mesh_final->ldata, CD_MLOOPUV); - active_uv = CustomData_get_active_layer(&mesh_final->ldata, CD_MLOOPUV); + if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPUV)) { + num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPUV); + active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPUV); } - if (CustomData_has_layer(&mesh_final->ldata, CD_MLOOPCOL)) { - num_col_layers = CustomData_number_of_layers(&mesh_final->ldata, CD_MLOOPCOL); - active_col = CustomData_get_active_layer(&mesh_final->ldata, CD_MLOOPCOL); + if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL)) { + num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPCOL); + active_col = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL); } } @@ -1173,7 +1166,7 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, col_id = MEM_mallocN(sizeof(*col_id) * num_col_layers, "Col attr format"); for (int i = 0; i < num_uv_layers; i++) { - const char *name = CustomData_get_layer_name(&mesh_final->ldata, CD_MLOOPUV, i); + const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i); char uuid[32]; BLI_snprintf(uuid, sizeof(uuid), "u%u", BLI_ghashutil_strhash_p(name)); @@ -1185,7 +1178,7 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, } for (int i = 0; i < num_uv_layers; i++) { - const char *name = CustomData_get_layer_name(&mesh_final->ldata, CD_MLOOPUV, i); + const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i); char uuid[32]; BLI_snprintf(uuid, sizeof(uuid), "c%u", BLI_ghashutil_strhash_p(name)); @@ -1204,17 +1197,17 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_STRIP, hair_cache->elems_len, hair_cache->point_len); if (num_uv_layers || num_col_layers) { - BKE_mesh_tessface_ensure(mesh_final); + BKE_mesh_tessface_ensure(psmd->mesh_final); if (num_uv_layers) { mtfaces = MEM_mallocN(sizeof(*mtfaces) * num_uv_layers, "Faces UV layers"); for (int i = 0; i < num_uv_layers; i++) { - mtfaces[i] = (MTFace *)CustomData_get_layer_n(&mesh_final->fdata, CD_MTFACE, i); + mtfaces[i] = (MTFace *)CustomData_get_layer_n(&psmd->mesh_final->fdata, CD_MTFACE, i); } } if (num_col_layers) { mcols = MEM_mallocN(sizeof(*mcols) * num_col_layers, "Color layers"); for (int i = 0; i < num_col_layers; i++) { - mcols[i] = (MCol *)CustomData_get_layer_n(&mesh_final->fdata, CD_MCOL, i); + mcols[i] = (MCol *)CustomData_get_layer_n(&psmd->mesh_final->fdata, CD_MCOL, i); } } } diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 70fe13eeaa2..7606fa914d1 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1558,7 +1558,6 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, RegionView3D *rv3d = ar->regiondata; const bool do_annotations = (((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) && ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0)); - const bool do_camera_frame = !DST.options.is_image_render; DST.draw_ctx.evil_C = evil_C; DST.viewport = viewport; @@ -1650,24 +1649,8 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, drw_engines_draw_background(); - /* WIP, single image drawn over the camera view (replace) */ - bool do_bg_image = false; - if (rv3d->persp == RV3D_CAMOB) { - Object *cam_ob = v3d->camera; - if (cam_ob && cam_ob->type == OB_CAMERA) { - Camera *cam = cam_ob->data; - if (!BLI_listbase_is_empty(&cam->bg_images)) { - do_bg_image = true; - } - } - } - GPU_framebuffer_bind(DST.default_framebuffer); - if (do_bg_image) { - ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, false, do_camera_frame); - } - DRW_draw_callbacks_pre_scene(); if (DST.draw_ctx.evil_C) { ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_PRE_VIEW); @@ -1734,10 +1717,6 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, DRW_stats_reset(); - if (do_bg_image) { - ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, true, do_camera_frame); - } - if (G.debug_value > 20 && G.debug_value < 30) { GPU_depth_test(false); rcti rect; /* local coordinate visible rect inside region, to accommodate overlapping ui */ @@ -2001,10 +1980,10 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) BLI_rcti_init(&render_rect, 0, size[0], 0, size[1]); } - /* Reset state before drawing */ - DRW_state_reset(); /* Set the default Blender draw state */ GPU_state_init(); + /* Reset state before drawing */ + DRW_state_reset(); /* Init render result. */ RenderResult *render_result = RE_engine_begin_result(engine, diff --git a/source/blender/draw/modes/edit_curve_mode.c b/source/blender/draw/modes/edit_curve_mode.c index 068af2e2012..e3c120e80cb 100644 --- a/source/blender/draw/modes/edit_curve_mode.c +++ b/source/blender/draw/modes/edit_curve_mode.c @@ -269,7 +269,9 @@ static void EDIT_CURVE_cache_populate(void *vedata, Object *ob) } geom = DRW_cache_curve_edge_wire_get(ob); - DRW_shgroup_call(wire_shgrp, geom, ob); + if (geom) { + DRW_shgroup_call(wire_shgrp, geom, ob); + } if ((cu->flag & CU_3D) && (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_NORMALS) != 0) { geom = DRW_cache_curve_edge_normal_get(ob); @@ -282,17 +284,23 @@ static void EDIT_CURVE_cache_populate(void *vedata, Object *ob) } geom = DRW_cache_curve_vert_overlay_get(ob, stl->g_data->show_handles); - DRW_shgroup_call(stl->g_data->overlay_vert_shgrp, geom, ob); + if (geom) { + DRW_shgroup_call(stl->g_data->overlay_vert_shgrp, geom, ob); + } } } if (ob->type == OB_SURF) { if (BKE_object_is_in_editmode(ob)) { struct GPUBatch *geom = DRW_cache_curve_edge_overlay_get(ob); - DRW_shgroup_call(stl->g_data->overlay_edge_shgrp, geom, ob); + if (geom) { + DRW_shgroup_call(stl->g_data->overlay_edge_shgrp, geom, ob); + } geom = DRW_cache_curve_vert_overlay_get(ob, false); - DRW_shgroup_call(stl->g_data->overlay_vert_shgrp, geom, ob); + if (geom) { + DRW_shgroup_call(stl->g_data->overlay_vert_shgrp, geom, ob); + } } } } diff --git a/source/blender/draw/modes/edit_text_mode.c b/source/blender/draw/modes/edit_text_mode.c index d1d17f2dc2d..03f26e8ce63 100644 --- a/source/blender/draw/modes/edit_text_mode.c +++ b/source/blender/draw/modes/edit_text_mode.c @@ -166,18 +166,17 @@ static void EDIT_TEXT_cache_init(void *vedata) "Font Wire", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL); stl->g_data->wire_shgrp = DRW_shgroup_create(e_data.wire_sh, psl->wire_pass); - psl->overlay_select_pass = DRW_pass_create("Font Select", - DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH); + /* Show selection & cursor on-top of everything (x-ray). */ + + psl->overlay_select_pass = DRW_pass_create("Font Select", DRW_STATE_WRITE_COLOR); stl->g_data->overlay_select_shgrp = DRW_shgroup_create(e_data.overlay_select_sh, psl->overlay_select_pass); - psl->overlay_cursor_pass = DRW_pass_create("Font Cursor", - DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH); + psl->overlay_cursor_pass = DRW_pass_create("Font Cursor", DRW_STATE_WRITE_COLOR); stl->g_data->overlay_cursor_shgrp = DRW_shgroup_create(e_data.overlay_cursor_sh, psl->overlay_cursor_pass); - psl->text_box_pass = DRW_pass_create("Font Text Boxes", - DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH); + psl->text_box_pass = DRW_pass_create("Font Text Boxes", DRW_STATE_WRITE_COLOR); stl->g_data->box_shgrp = buffer_dynlines_dashed_uniform_color( psl->text_box_pass, G_draw.block.colorWire, draw_ctx->sh_cfg); stl->g_data->box_active_shgrp = buffer_dynlines_dashed_uniform_color( diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index bbf364960c9..1c60fc09057 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -38,6 +38,7 @@ #include "DNA_rigidbody_types.h" #include "DNA_smoke_types.h" #include "DNA_view3d_types.h" +#include "DNA_screen_types.h" #include "DNA_world_types.h" #include "BKE_anim.h" @@ -45,6 +46,7 @@ #include "BKE_constraint.h" #include "BKE_curve.h" #include "BKE_editmesh.h" +#include "BKE_image.h" #include "BKE_mball.h" #include "BKE_mesh.h" #include "BKE_modifier.h" @@ -55,6 +57,8 @@ #include "BLI_ghash.h" +#include "IMB_imbuf_types.h" + #include "ED_view3d.h" #include "GPU_batch.h" @@ -80,6 +84,8 @@ extern char datatoc_object_outline_detect_frag_glsl[]; extern char datatoc_object_outline_expand_frag_glsl[]; extern char datatoc_object_grid_frag_glsl[]; extern char datatoc_object_grid_vert_glsl[]; +extern char datatoc_object_camera_image_frag_glsl[]; +extern char datatoc_object_camera_image_vert_glsl[]; extern char datatoc_object_empty_image_frag_glsl[]; extern char datatoc_object_empty_image_vert_glsl[]; extern char datatoc_object_lightprobe_grid_vert_glsl[]; @@ -87,6 +93,7 @@ extern char datatoc_object_loose_points_frag_glsl[]; extern char datatoc_object_particle_prim_vert_glsl[]; extern char datatoc_object_particle_dot_vert_glsl[]; extern char datatoc_object_particle_dot_frag_glsl[]; +extern char datatoc_common_colormanagement_lib_glsl[]; extern char datatoc_common_globals_lib_glsl[]; extern char datatoc_common_view_lib_glsl[]; extern char datatoc_common_fxaa_lib_glsl[]; @@ -115,6 +122,8 @@ typedef struct OBJECT_PassList { struct DRWPass *bone_axes[2]; struct DRWPass *particle; struct DRWPass *lightprobes; + struct DRWPass *camera_images_back; + struct DRWPass *camera_images_front; } OBJECT_PassList; typedef struct OBJECT_FramebufferList { @@ -148,6 +157,8 @@ typedef struct OBJECT_Shaders { GPUShader *outline_fade_large; /* regular shaders */ + GPUShader *object_camera_image; + GPUShader *object_camera_image_cm; GPUShader *object_empty_image; GPUShader *object_empty_image_wire; GPUShader *grid; @@ -336,6 +347,7 @@ static struct { struct GPUTexture *outlines_blur_tx; ListBase smoke_domains; + ListBase movie_clips; } e_data = {NULL}; /* Engine data */ enum { @@ -460,7 +472,9 @@ static void OBJECT_engine_init(void *vedata) datatoc_common_view_lib_glsl, datatoc_object_empty_image_vert_glsl, NULL}, - .frag = (const char *[]){datatoc_object_empty_image_frag_glsl, NULL}, + .frag = (const char *[]){datatoc_common_colormanagement_lib_glsl, + datatoc_object_empty_image_frag_glsl, + NULL}, .defs = (const char *[]){sh_cfg_data->def, empty_image_defs, NULL}, }); sh_data->object_empty_image_wire = GPU_shader_create_from_arrays({ @@ -471,6 +485,21 @@ static void OBJECT_engine_init(void *vedata) .frag = (const char *[]){datatoc_object_empty_image_frag_glsl, NULL}, .defs = (const char *[]){sh_cfg_data->def, "#define USE_WIRE\n", empty_image_defs, NULL}, }); + + sh_data->object_camera_image_cm = GPU_shader_create_from_arrays({ + .vert = (const char *[]){sh_cfg_data->lib, datatoc_object_camera_image_vert_glsl, NULL}, + .frag = (const char *[]){datatoc_common_colormanagement_lib_glsl, + datatoc_object_camera_image_frag_glsl, + NULL}, + .defs = + (const char *[]){sh_cfg_data->def, "#define DRW_STATE_DO_COLOR_MANAGEMENT\n", NULL}, + }); + sh_data->object_camera_image = GPU_shader_create_from_arrays({ + .vert = (const char *[]){sh_cfg_data->lib, datatoc_object_camera_image_vert_glsl, NULL}, + .frag = (const char *[]){datatoc_common_colormanagement_lib_glsl, + datatoc_object_camera_image_frag_glsl, + NULL}, + }); } /* Grid */ @@ -1035,6 +1064,291 @@ static void DRW_shgroup_empty_image(OBJECT_Shaders *sh_data, } } +/* Draw Camera Background Images */ +typedef struct CameraEngineData { + DrawData dd; + ListBase bg_data; +} CameraEngineData; +typedef struct CameraEngineBGData { + float transform_mat[4][4]; +} CameraEngineBGData; + +static void camera_engine_data_free(DrawData *dd) +{ + CameraEngineData *data = (CameraEngineData *)dd; + for (LinkData *link = data->bg_data.first; link; link = link->next) { + CameraEngineBGData *bg_data = (CameraEngineBGData *)link->data; + MEM_freeN(bg_data); + } + BLI_freelistN(&data->bg_data); +} + +static void camera_background_images_stereo_setup(Scene *scene, + View3D *v3d, + Image *ima, + ImageUser *iuser) +{ + if (BKE_image_is_stereo(ima)) { + iuser->flag |= IMA_SHOW_STEREO; + + if ((scene->r.scemode & R_MULTIVIEW) == 0) { + iuser->multiview_eye = STEREO_LEFT_ID; + } + else if (v3d->stereo3d_camera != STEREO_3D_ID) { + /* show only left or right camera */ + iuser->multiview_eye = v3d->stereo3d_camera; + } + + BKE_image_multiview_index(ima, iuser); + } + else { + iuser->flag &= ~IMA_SHOW_STEREO; + } +} + +static void DRW_shgroup_camera_background_images(OBJECT_Shaders *sh_data, + OBJECT_PassList *psl, + Object *ob, + RegionView3D *rv3d) +{ + if (!BKE_object_empty_image_frame_is_visible_in_view3d(ob, rv3d)) { + return; + } + + const DRWContextState *draw_ctx = DRW_context_state_get(); + struct ARegion *ar = draw_ctx->ar; + View3D *v3d = draw_ctx->v3d; + Scene *scene = draw_ctx->scene; + Depsgraph *depsgraph = draw_ctx->depsgraph; + Camera *cam = ob->data; + const Object *camera_object = DEG_get_evaluated_object(depsgraph, v3d->camera); + const bool is_active = (ob == camera_object); + const bool look_through = (is_active && (rv3d->persp == RV3D_CAMOB)); + + if (look_through && (cam->flag & CAM_SHOW_BG_IMAGE)) { + GPUBatch *batch = DRW_cache_image_plane_get(); + + /* load camera engine data */ + CameraEngineData *camera_engine_data = (CameraEngineData *)DRW_drawdata_ensure( + &ob->id, + &draw_engine_object_type, + sizeof(CameraEngineData), + NULL, + camera_engine_data_free); + LinkData *list_node = camera_engine_data->bg_data.first; + + for (CameraBGImage *bgpic = cam->bg_images.first; bgpic; bgpic = bgpic->next) { + if ((bgpic->flag & CAM_BGIMG_FLAG_DISABLED)) { + continue; + } + + /* retrieve the image we want to show, continue to next when no image could be found */ + ImBuf *ibuf = NULL; + GPUTexture *tex = NULL; + float image_aspect_x, image_aspect_y; + float image_aspect = 1.0; + int image_width, image_height; + bool premultiplied = false; + + if (bgpic->source == CAM_BGIMG_SOURCE_IMAGE) { + Image *image = bgpic->ima; + if (image == NULL) { + continue; + } + premultiplied = (image->alpha_mode == IMA_ALPHA_PREMUL); + ImageUser *iuser = &bgpic->iuser; + BKE_image_user_frame_calc(image, iuser, (int)DEG_get_ctime(depsgraph)); + if (image->source == IMA_SRC_SEQUENCE && !(iuser->flag & IMA_USER_FRAME_IN_RANGE)) { + /* frame is out of range, dont show */ + continue; + } + else { + camera_background_images_stereo_setup(scene, v3d, image, iuser); + } + tex = GPU_texture_from_blender(image, iuser, GL_TEXTURE_2D); + if (tex == NULL) { + continue; + } + ibuf = BKE_image_acquire_ibuf(image, iuser, NULL); + if (ibuf == NULL) { + continue; + } + + image_aspect_x = bgpic->ima->aspx; + image_aspect_y = bgpic->ima->aspy; + + image_width = ibuf->x; + image_height = ibuf->y; + BKE_image_release_ibuf(image, ibuf, NULL); + image_aspect = (image_width * image_aspect_x) / (image_height * image_aspect_y); + } + else if (bgpic->source == CAM_BGIMG_SOURCE_MOVIE) { + MovieClip *clip = NULL; + if (bgpic->flag & CAM_BGIMG_FLAG_CAMERACLIP) { + if (scene->camera) { + clip = BKE_object_movieclip_get(scene, scene->camera, true); + } + } + else { + clip = bgpic->clip; + } + + if (clip == NULL) { + continue; + } + + image_aspect_x = clip->aspx; + image_aspect_y = clip->aspy; + + BKE_movieclip_user_set_frame(&bgpic->cuser, (int)DEG_get_ctime(depsgraph)); + tex = GPU_texture_from_movieclip(clip, &bgpic->cuser, GL_TEXTURE_2D); + if (tex == NULL) { + continue; + } + BLI_addtail(&e_data.movie_clips, BLI_genericNodeN(clip)); + BKE_movieclip_get_size(clip, &bgpic->cuser, &image_width, &image_height); + image_aspect = (image_width * image_aspect_x) / (image_height * image_aspect_y); + } + + /* ensure link_data is allocated to store matrice */ + CameraEngineBGData *bg_data; + if (list_node != NULL) { + bg_data = (CameraEngineBGData *)list_node->data; + list_node = list_node->next; + } + else { + bg_data = MEM_mallocN(sizeof(CameraEngineBGData), __func__); + BLI_addtail(&camera_engine_data->bg_data, BLI_genericNodeN(bg_data)); + } + + /* calculate the transformation matric for the current bg image */ + float uv2img_space[4][4]; + float img2cam_space[4][4]; + float rot_m4[4][4]; + float scale_m4[4][4]; + float translate_m4[4][4]; + float win_m4_scale[4][4]; + float win_m4_translate[4][4]; + + unit_m4(uv2img_space); + unit_m4(img2cam_space); + unit_m4(win_m4_scale); + unit_m4(win_m4_translate); + unit_m4(scale_m4); + axis_angle_to_mat4_single(rot_m4, 'Z', bgpic->rotation); + unit_m4(translate_m4); + + const float *size = DRW_viewport_size_get(); + float camera_aspect_x = 1.0; + float camera_aspect_y = 1.0; + float camera_offset_x = 0.0; + float camera_offset_y = 0.0; + float camera_aspect = 1.0; + float camera_width = size[0]; + float camera_height = size[1]; + + if (!DRW_state_is_image_render()) { + rctf render_border; + ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &render_border, true); + camera_width = render_border.xmax - render_border.xmin; + camera_height = render_border.ymax - render_border.ymin; + camera_aspect = camera_width / camera_height; + const float camera_aspect_center_x = (render_border.xmax + render_border.xmin) / 2.0; + const float camera_aspect_center_y = (render_border.ymax + render_border.ymin) / 2.0; + + camera_aspect_x = camera_width / size[0]; + camera_aspect_y = camera_height / size[1]; + win_m4_scale[0][0] = camera_aspect_x; + win_m4_scale[1][1] = camera_aspect_y; + + camera_offset_x = (camera_aspect_center_x - (ar->winx / 2.0)) / + (0.5 * camera_width / camera_aspect_x); + camera_offset_y = (camera_aspect_center_y - (ar->winy / 2.0)) / + (0.5 * camera_height / camera_aspect_y); + win_m4_translate[3][0] = camera_offset_x; + win_m4_translate[3][1] = camera_offset_y; + } + + /* Convert from uv space to image space -0.5..-.5 */ + uv2img_space[0][0] = image_width; + uv2img_space[1][1] = image_height; + + img2cam_space[0][0] = (1.0 / image_width); + img2cam_space[1][1] = (1.0 / image_height); + + /* Update scaling based on image and camera framing */ + float scale_x = bgpic->scale; + float scale_y = bgpic->scale; + + if (bgpic->flag & CAM_BGIMG_FLAG_CAMERA_ASPECT) { + float fit_scale = image_aspect / camera_aspect; + if (bgpic->flag & CAM_BGIMG_FLAG_CAMERA_CROP) { + if (image_aspect > camera_aspect) { + scale_x *= fit_scale; + } + else { + scale_y /= fit_scale; + } + } + else { + if (image_aspect > camera_aspect) { + scale_y /= fit_scale; + } + else { + scale_x *= fit_scale; + } + } + } + + // scale image to match the desired aspect ratio + scale_m4[0][0] = scale_x; + scale_m4[1][1] = scale_y; + + // translate + translate_m4[3][0] = bgpic->offset[0]; + translate_m4[3][1] = bgpic->offset[1]; + + mul_m4_series(bg_data->transform_mat, + win_m4_translate, + win_m4_scale, + translate_m4, + img2cam_space, + scale_m4, + rot_m4, + uv2img_space); + + DRWPass *pass = (bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) ? psl->camera_images_front : + psl->camera_images_back; + GPUShader *shader = DRW_state_do_color_management() ? sh_data->object_camera_image_cm : + sh_data->object_camera_image; + DRWShadingGroup *grp = DRW_shgroup_create(shader, pass); + + DRW_shgroup_uniform_float_copy( + grp, "depth", (bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) ? 0.000001 : 0.999999); + DRW_shgroup_uniform_float_copy(grp, "alpha", bgpic->alpha); + DRW_shgroup_uniform_texture(grp, "image", tex); + DRW_shgroup_uniform_bool_copy(grp, "imagePremultiplied", premultiplied); + + DRW_shgroup_uniform_float_copy( + grp, "flipX", (bgpic->flag & CAM_BGIMG_FLAG_FLIP_X) ? -1.0 : 1.0); + DRW_shgroup_uniform_float_copy( + grp, "flipY", (bgpic->flag & CAM_BGIMG_FLAG_FLIP_Y) ? -1.0 : 1.0); + DRW_shgroup_uniform_mat4(grp, "TransformMat", bg_data->transform_mat); + + DRW_shgroup_call(grp, batch, NULL); + } + } +} + +static void camera_background_images_free_textures(void) +{ + for (LinkData *link = e_data.movie_clips.first; link; link = link->next) { + MovieClip *clip = (MovieClip *)link->data; + GPU_free_texture_movieclip(clip); + } + BLI_freelistN(&e_data.movie_clips); +} + static void OBJECT_cache_init(void *vedata) { const GlobalsUboStorage *gb = &G_draw.block; @@ -1206,6 +1520,13 @@ static void OBJECT_cache_init(void *vedata) DRW_shgroup_call(grp, geom, NULL); } + /* Camera background images */ + { + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_ALPHA; + psl->camera_images_back = DRW_pass_create("Camera Images Back", state); + psl->camera_images_front = DRW_pass_create("Camera Images Front", state); + } + for (int i = 0; i < 2; ++i) { OBJECT_ShadingGroupList *sgl = (i == 1) ? &stl->g_data->sgl_ghost : &stl->g_data->sgl; @@ -3221,10 +3542,12 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) break; } geom = DRW_cache_lattice_wire_get(ob, false); + if (geom == NULL) { + break; + } if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); } - shgroup = shgroup_theme_id_to_wire(sgl, theme_id, ob->base_flag); DRW_shgroup_call(shgroup, geom, ob); } @@ -3236,6 +3559,9 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) break; } geom = DRW_cache_curve_edge_wire_get(ob); + if (geom == NULL) { + break; + } if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); } @@ -3261,6 +3587,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) break; } DRW_shgroup_camera(sgl, ob, view_layer); + DRW_shgroup_camera_background_images(sh_data, psl, ob, rv3d); break; case OB_EMPTY: if (hide_object_extra) { @@ -3444,6 +3771,8 @@ static void OBJECT_draw_scene(void *vedata) float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + DRW_draw_pass(psl->camera_images_back); + /* Don't draw Transparent passes in MSAA buffer. */ // DRW_draw_pass(psl->bone_envelope); /* Never drawn in Object mode currently. */ DRW_draw_pass(stl->g_data->sgl.transp_shapes); @@ -3513,7 +3842,6 @@ static void OBJECT_draw_scene(void *vedata) DRW_draw_pass(psl->outlines_resolve); } } - volumes_free_smoke_textures(); batch_camera_path_free(&stl->g_data->sgl.camera_path); @@ -3562,6 +3890,9 @@ static void OBJECT_draw_scene(void *vedata) batch_camera_path_free(&stl->g_data->sgl_ghost.camera_path); + DRW_draw_pass(psl->camera_images_front); + camera_background_images_free_textures(); + DRW_draw_pass(psl->ob_center); } diff --git a/source/blender/draw/modes/paint_texture_mode.c b/source/blender/draw/modes/paint_texture_mode.c index 5f833e4c6a1..82c11a278de 100644 --- a/source/blender/draw/modes/paint_texture_mode.c +++ b/source/blender/draw/modes/paint_texture_mode.c @@ -40,6 +40,7 @@ #include "DEG_depsgraph_query.h" +extern char datatoc_common_colormanagement_lib_glsl[]; extern char datatoc_common_globals_lib_glsl[]; extern char datatoc_common_view_lib_glsl[]; extern char datatoc_paint_texture_vert_glsl[]; @@ -160,7 +161,9 @@ static void PAINT_TEXTURE_engine_init(void *vedata) datatoc_common_view_lib_glsl, datatoc_paint_texture_vert_glsl, NULL}, - .frag = (const char *[]){datatoc_paint_texture_frag_glsl, NULL}, + .frag = (const char *[]){datatoc_common_colormanagement_lib_glsl, + datatoc_paint_texture_frag_glsl, + NULL}, .defs = (const char *[]){sh_cfg_data->def, NULL}, }); diff --git a/source/blender/draw/modes/pose_mode.c b/source/blender/draw/modes/pose_mode.c index 8cdf28f177a..3a5c87688fe 100644 --- a/source/blender/draw/modes/pose_mode.c +++ b/source/blender/draw/modes/pose_mode.c @@ -35,6 +35,10 @@ #include "draw_common.h" #include "draw_mode_engines.h" +extern char datatoc_common_view_lib_glsl[]; +extern char datatoc_gpu_shader_uniform_color_frag_glsl[]; +extern char datatoc_pose_selection_vert_glsl[]; + /* *********** LISTS *********** */ /** * All lists are per viewport specific datas. @@ -93,12 +97,18 @@ static bool POSE_is_bone_selection_overlay_active(void) static void POSE_engine_init(void *UNUSED(vedata)) { if (!e_data.bone_selection_sh) { - e_data.bone_selection_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); + e_data.bone_selection_sh = DRW_shader_create_with_lib( + datatoc_pose_selection_vert_glsl, + NULL, + datatoc_gpu_shader_uniform_color_frag_glsl, + datatoc_common_view_lib_glsl, + NULL); } } static void POSE_engine_free(void) { + DRW_SHADER_FREE_SAFE(e_data.bone_selection_sh); } /* Here init all passes and shading groups diff --git a/source/blender/draw/modes/sculpt_mode.c b/source/blender/draw/modes/sculpt_mode.c index 42a2333f305..1b196cd8bb7 100644 --- a/source/blender/draw/modes/sculpt_mode.c +++ b/source/blender/draw/modes/sculpt_mode.c @@ -155,7 +155,8 @@ static void SCULPT_cache_populate(void *vedata, Object *ob) if (ob->sculpt) { const DRWContextState *draw_ctx = DRW_context_state_get(); - if ((ob == draw_ctx->obact) && BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d)) { + if ((ob == draw_ctx->obact) && + (BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) || !ob->sculpt->modifiers_active)) { PBVH *pbvh = ob->sculpt->pbvh; if (pbvh && pbvh_has_mask(pbvh)) { DRW_shgroup_call_sculpt(stl->g_data->mask_overlay_grp, ob, false, true, false); diff --git a/source/blender/draw/modes/shaders/common_colormanagement_lib.glsl b/source/blender/draw/modes/shaders/common_colormanagement_lib.glsl new file mode 100644 index 00000000000..45f711296f3 --- /dev/null +++ b/source/blender/draw/modes/shaders/common_colormanagement_lib.glsl @@ -0,0 +1,30 @@ +float linearrgb_to_srgb(float c) +{ + if (c < 0.0031308) { + return (c < 0.0) ? 0.0 : c * 12.92; + } + else { + return 1.055 * pow(c, 1.0 / 2.4) - 0.055; + } +} + +vec4 texture_read_as_linearrgb(sampler2D tex, bool premultiplied, vec2 co) +{ + /* By convention image textures return scene linear colors, but + * overlays still assume srgb. */ + vec4 color = texture(tex, co); + /* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */ + if (premultiplied && !(color.a == 0.0 || color.a == 1.0)) { + color.rgb = color.rgb / color.a; + } + return color; +} + +vec4 texture_read_as_srgb(sampler2D tex, bool premultiplied, vec2 co) +{ + vec4 color = texture_read_as_linearrgb(tex, premultiplied, co); + color.r = linearrgb_to_srgb(color.r); + color.g = linearrgb_to_srgb(color.g); + color.b = linearrgb_to_srgb(color.b); + return color; +} diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl index 6aa20a9d21b..b79bae45f23 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl @@ -65,7 +65,7 @@ vec4 EDIT_MESH_face_color(int face_flag) vec4 EDIT_MESH_facedot_color(float facedot_flag) { if (facedot_flag < 0.0f) { - return colorEditMeshActive; + return vec4(colorEditMeshActive.xyz, 1.0); } else if (facedot_flag > 0.0f) { return colorFaceDot; diff --git a/source/blender/draw/modes/shaders/object_camera_image_frag.glsl b/source/blender/draw/modes/shaders/object_camera_image_frag.glsl new file mode 100644 index 00000000000..5d8ad3c79ea --- /dev/null +++ b/source/blender/draw/modes/shaders/object_camera_image_frag.glsl @@ -0,0 +1,23 @@ +in vec2 texCoord_interp; +out vec4 fragColor; + +uniform sampler2D image; +uniform float alpha; +uniform bool imagePremultiplied; + +void main() +{ +#ifdef DRW_STATE_DO_COLOR_MANAGEMENT + /* render engine has already applied the view transform. We sample the + * camera images as srgb*/ + vec4 color = texture_read_as_srgb(image, imagePremultiplied, texCoord_interp); + +#else + /* Render engine renders in linearrgb. We sample the camera images as + * linearrgb */ + vec4 color = texture_read_as_linearrgb(image, imagePremultiplied, texCoord_interp); +#endif + + color.a *= alpha; + fragColor = color; +} diff --git a/source/blender/draw/modes/shaders/object_camera_image_vert.glsl b/source/blender/draw/modes/shaders/object_camera_image_vert.glsl new file mode 100644 index 00000000000..61b88c013aa --- /dev/null +++ b/source/blender/draw/modes/shaders/object_camera_image_vert.glsl @@ -0,0 +1,18 @@ +uniform mat4 TransformMat; +uniform float flipX; +uniform float flipY; +uniform float depth; + +in vec2 texCoord; +in vec2 pos; + +out vec2 texCoord_interp; + +void main() +{ + vec4 position = TransformMat * vec4((pos - 0.5) * 2.0, 1.0, 1.0); + gl_Position = vec4(position.xy, depth, 1.0); + + vec2 uv_mul = vec2(flipX, flipY); + texCoord_interp = texCoord * uv_mul; +} diff --git a/source/blender/draw/modes/shaders/object_empty_image_frag.glsl b/source/blender/draw/modes/shaders/object_empty_image_frag.glsl index 88220140aec..7dfbf469adc 100644 --- a/source/blender/draw/modes/shaders/object_empty_image_frag.glsl +++ b/source/blender/draw/modes/shaders/object_empty_image_frag.glsl @@ -15,31 +15,6 @@ uniform bool imagePremultiplied; uniform int depthMode; uniform bool useAlphaTest; -float linearrgb_to_srgb(float c) -{ - if (c < 0.0031308) { - return (c < 0.0) ? 0.0 : c * 12.92; - } - else { - return 1.055 * pow(c, 1.0 / 2.4) - 0.055; - } -} - -vec4 texture_read_as_srgb(sampler2D tex, bool premultiplied, vec2 co) -{ - /* By convention image textures return scene linear colors, but - * overlays still assume srgb. */ - vec4 color = texture(tex, co); - /* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */ - if (premultiplied && !(color.a == 0.0 || color.a == 1.0)) { - color.rgb = color.rgb / color.a; - } - color.r = linearrgb_to_srgb(color.r); - color.g = linearrgb_to_srgb(color.g); - color.b = linearrgb_to_srgb(color.b); - return color; -} - void main() { #ifdef USE_WIRE diff --git a/source/blender/draw/modes/shaders/paint_texture_frag.glsl b/source/blender/draw/modes/shaders/paint_texture_frag.glsl index af7ea99e6a1..e8722590802 100644 --- a/source/blender/draw/modes/shaders/paint_texture_frag.glsl +++ b/source/blender/draw/modes/shaders/paint_texture_frag.glsl @@ -18,31 +18,6 @@ uniform vec3 maskingColor; uniform bool maskingInvertStencil; #endif -float linearrgb_to_srgb(float c) -{ - if (c < 0.0031308) { - return (c < 0.0) ? 0.0 : c * 12.92; - } - else { - return 1.055 * pow(c, 1.0 / 2.4) - 0.055; - } -} - -vec4 texture_read_as_srgb(sampler2D tex, bool premultiplied, vec2 co) -{ - /* By convention image textures return scene linear colors, but - * overlays still assume srgb. */ - vec4 color = texture(tex, co); - /* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */ - if (premultiplied && !(color.a == 0.0 || color.a == 1.0)) { - color.rgb = color.rgb / color.a; - } - color.r = linearrgb_to_srgb(color.r); - color.g = linearrgb_to_srgb(color.g); - color.b = linearrgb_to_srgb(color.b); - return color; -} - void main() { vec2 uv = uv_interp; diff --git a/source/blender/draw/modes/shaders/pose_selection_vert.glsl b/source/blender/draw/modes/shaders/pose_selection_vert.glsl new file mode 100644 index 00000000000..2dd84c0a060 --- /dev/null +++ b/source/blender/draw/modes/shaders/pose_selection_vert.glsl @@ -0,0 +1,12 @@ + +in vec3 pos; + +void main() +{ + vec3 world_pos = point_object_to_world(pos); + gl_Position = point_world_to_ndc(world_pos); + +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_calc_clip_distance(world_pos); +#endif +} diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c index f4e1268ab77..b42e8102c5b 100644 --- a/source/blender/editors/animation/fmodifier_ui.c +++ b/source/blender/editors/animation/fmodifier_ui.c @@ -70,8 +70,18 @@ #define B_REDR 1 #define B_FMODIFIER_REDRAW 20 +/* callback to update depsgraph on value changes */ +static void deg_update(bContext *C, void *owner_id, void *UNUSED(var2)) +{ + /* send notifiers */ + /* XXX for now, this is the only way to get updates in all the right places... + * but would be nice to have a special one in this case. */ + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); + DEG_id_tag_update(owner_id, ID_RECALC_ANIMATION); +} + /* callback to verify modifier data */ -static void validate_fmodifier_cb(bContext *UNUSED(C), void *fcm_v, void *UNUSED(arg)) +static void validate_fmodifier_cb(bContext *C, void *fcm_v, void *owner_id) { FModifier *fcm = (FModifier *)fcm_v; const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm); @@ -80,6 +90,9 @@ static void validate_fmodifier_cb(bContext *UNUSED(C), void *fcm_v, void *UNUSED if (fmi && fmi->verify_data) { fmi->verify_data(fcm); } + if (owner_id) { + deg_update(C, owner_id, NULL); + } } /* callback to remove the given modifier */ @@ -98,13 +111,8 @@ static void delete_fmodifier_cb(bContext *C, void *ctx_v, void *fcm_v) ED_undo_push(C, "Delete F-Curve Modifier"); - /* send notifiers */ - /* XXX for now, this is the only way to get updates in all the right places... - * but would be nice to have a special one in this case. */ - WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); - DEG_id_tag_update(ctx->fcurve_owner_id, ID_RECALC_ANIMATION); + deg_update(C, ctx->fcurve_owner_id, NULL); } - /* --------------- */ /* draw settings for generator modifier */ @@ -176,6 +184,7 @@ static void draw_modifier__generator(uiLayout *layout, /* draw polynomial order selector */ row = uiLayoutRow(layout, false); block = uiLayoutGetBlock(row); + but = uiDefButI( block, UI_BTYPE_NUM, @@ -191,7 +200,7 @@ static void draw_modifier__generator(uiLayout *layout, 0, 0, TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)")); - UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL); + UI_but_func_set(but, validate_fmodifier_cb, fcm, fcurve_owner_id); /* calculate maximum width of label for "x^n" labels */ if (data->arraysize > 2) { @@ -208,6 +217,9 @@ static void draw_modifier__generator(uiLayout *layout, row = uiLayoutRow(layout, true); block = uiLayoutGetBlock(row); + /* Update depsgraph when values change */ + UI_block_func_set(block, deg_update, fcurve_owner_id, NULL); + cp = data->coefficients; for (i = 0; (i < data->arraysize) && (cp); i++, cp++) { /* To align with first line... */ @@ -310,6 +322,7 @@ static void draw_modifier__generator(uiLayout *layout, /* draw polynomial order selector */ row = uiLayoutRow(layout, false); block = uiLayoutGetBlock(row); + but = uiDefButI( block, UI_BTYPE_NUM, @@ -325,12 +338,15 @@ static void draw_modifier__generator(uiLayout *layout, 0, 0, TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)")); - UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL); + UI_but_func_set(but, validate_fmodifier_cb, fcm, fcurve_owner_id); /* draw controls for each pair of coefficients */ row = uiLayoutRow(layout, true); block = uiLayoutGetBlock(row); + /* Update depsgraph when values change */ + UI_block_func_set(block, deg_update, fcurve_owner_id, NULL); + cp = data->coefficients; for (i = 0; (i < data->poly_order) && (cp); i++, cp += 2) { /* To align with first line */ diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 21a18a0b387..99843c66d0e 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -519,6 +519,9 @@ struct EDSelectID_Context *ED_view3d_select_id_context_create(struct ViewContext short select_mode); void ED_view3d_select_id_context_destroy(struct EDSelectID_Context *sel_id_ctx); +void ED_view3d_select_id_validate_view_matrices(const struct EDSelectID_Context *sel_id_ctx, + struct ViewContext *vc); + uint ED_view3d_select_id_context_offset_for_object_elem( const struct EDSelectID_Context *sel_id_ctx, int base_index, char elem_type); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 9612eab0025..697c289491a 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -6324,7 +6324,7 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) char *tmp = NULL; if (type == BUT_GET_LABEL) { - if (but->str) { + if (but->str && but->str[0]) { const char *str_sep; size_t str_len; @@ -6401,18 +6401,35 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) } } } - else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { - MenuType *mt = UI_but_menutype_get(but); - if (mt) { - /* not all menus are from python */ - if (mt->ext.srna) { + else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)) { + { + MenuType *mt = UI_but_menutype_get(but); + if (mt) { + if (type == BUT_GET_RNA_LABEL) { + tmp = BLI_strdup(mt->label); + } + else { + /* Not all menus are from Python. */ + if (mt->ext.srna) { + const char *t = RNA_struct_ui_description(mt->ext.srna); + if (t && t[0]) { + tmp = BLI_strdup(t); + } + } + } + } + } + + if (tmp == NULL) { + PanelType *pt = UI_but_paneltype_get(but); + if (pt) { if (type == BUT_GET_RNA_LABEL) { - tmp = BLI_strdup(RNA_struct_ui_name(mt->ext.srna)); + tmp = BLI_strdup(pt->label); } else { - const char *t = RNA_struct_ui_description(mt->ext.srna); - if (t && t[0]) { - tmp = BLI_strdup(t); + /* Not all panels are from Python. */ + if (pt->ext.srna) { + /* Panels don't yet have descriptions, this may be added. */ } } } diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 022c3b3cb51..7afdbe9d266 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1526,6 +1526,7 @@ static void ui_draw_colorband_handle(uint shdr_pos, immUniformArray4fv( "colors", (float *)(float[][4]){{0.8f, 0.8f, 0.8f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2); immUniform1f("dash_width", active ? 4.0f : 2.0f); + immUniform1f("dash_factor", 0.5f); immBegin(GPU_PRIM_LINES, 2); immVertex2f(shdr_pos, x, y1); diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c index 9d1b6fc92fc..f10702f3f3b 100644 --- a/source/blender/editors/interface/interface_region_tooltip.c +++ b/source/blender/editors/interface/interface_region_tooltip.c @@ -608,6 +608,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) { + uiStringInfo but_label = {BUT_GET_LABEL, NULL}; uiStringInfo but_tip = {BUT_GET_TIP, NULL}; uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, NULL}; uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, NULL}; @@ -623,6 +624,7 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) UI_but_string_info_get(C, but, + &but_label, &but_tip, &enum_label, &enum_tip, @@ -632,6 +634,17 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) &rna_prop, NULL); + /* Tip Label (only for buttons not already showing the label). + * Check prefix instead of comparing because the button may include the shortcut. */ + if (but_label.strinfo && !STRPREFIX(but->drawstr, but_label.strinfo)) { + uiTooltipField *field = text_field_add(data, + &(uiTooltipFormat){ + .style = UI_TIP_STYLE_HEADER, + .color_id = UI_TIP_LC_NORMAL, + }); + field->text = BLI_sprintfN("%s.", but_label.strinfo); + } + /* Tip */ if (but_tip.strinfo) { { @@ -844,6 +857,9 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) } /* Free strinfo's... */ + if (but_label.strinfo) { + MEM_freeN(but_label.strinfo); + } if (but_tip.strinfo) { MEM_freeN(but_tip.strinfo); } diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index d9ca58fa88c..c00223a3c49 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -500,6 +500,7 @@ static void mask_draw_curve_type(const bContext *C, immUniform1i("colors_len", 2); /* "advanced" mode */ immUniformArray4fv("colors", colors, 2); immUniform1f("dash_width", 4.0f); + immUniform1f("dash_factor", 0.5f); GPU_line_width(1.0f); mask_draw_array(pos, draw_method, points, tot_point); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 4f1154c02e3..a390cf67cf5 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -869,6 +869,8 @@ static int forcefield_toggle_exec(bContext *C, wmOperator *UNUSED(op)) WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); + return OPERATOR_FINISHED; } @@ -1709,7 +1711,7 @@ void OBJECT_OT_move_to_collection(wmOperatorType *ot) /* identifiers */ ot->name = "Move to Collection"; - ot->description = "Move objects to a scene collection"; + ot->description = "Move objects to a collection"; ot->idname = "OBJECT_OT_move_to_collection"; /* api callbacks */ diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 86144937844..394fea2cf27 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -53,6 +53,7 @@ #include "BKE_multires.h" #include "BKE_armature.h" #include "BKE_lattice.h" +#include "BKE_library.h" #include "BKE_tracking.h" #include "BKE_gpencil.h" @@ -460,11 +461,10 @@ void OBJECT_OT_origin_clear(wmOperatorType *ot) /* use this when the loc/size/rot of the parent has changed but the children * should stay in the same place, e.g. for apply-size-rot or object center */ -static void ignore_parent_tx(const bContext *C, Main *bmain, Scene *scene, Object *ob) +static void ignore_parent_tx(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob) { Object workob; Object *ob_child; - Depsgraph *depsgraph = CTX_data_depsgraph(C); /* a change was made, adjust the children to compensate */ for (ob_child = bmain->objects.first; ob_child; ob_child = ob_child->id.next) { @@ -479,6 +479,55 @@ static void ignore_parent_tx(const bContext *C, Main *bmain, Scene *scene, Objec } } +static void append_sorted_object_parent_hierarchy(Object *root_object, + Object *object, + Object **sorted_objects, + int *object_index) +{ + if (object->parent != NULL && object->parent != root_object) { + append_sorted_object_parent_hierarchy( + root_object, object->parent, sorted_objects, object_index); + } + if (object->id.tag & LIB_TAG_DOIT) { + sorted_objects[*object_index] = object; + (*object_index)++; + object->id.tag &= ~LIB_TAG_DOIT; + } +} + +static Object **sorted_selected_editable_objects(bContext *C, int *r_num_objects) +{ + Main *bmain = CTX_data_main(C); + + /* Count all objects, but also tag all the selected ones. */ + BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); + int num_objects = 0; + CTX_DATA_BEGIN (C, Object *, object, selected_editable_objects) { + object->id.tag |= LIB_TAG_DOIT; + num_objects++; + } + CTX_DATA_END; + if (num_objects == 0) { + *r_num_objects = 0; + return NULL; + } + + /* Append all the objects. */ + Object **sorted_objects = MEM_malloc_arrayN(num_objects, sizeof(Object *), "sorted objects"); + int object_index = 0; + CTX_DATA_BEGIN (C, Object *, object, selected_editable_objects) { + if ((object->id.tag & LIB_TAG_DOIT) == 0) { + continue; + } + append_sorted_object_parent_hierarchy(object, object, sorted_objects, &object_index); + } + CTX_DATA_END; + + *r_num_objects = num_objects; + + return sorted_objects; +} + static int apply_objects_internal(bContext *C, ReportList *reports, bool apply_loc, @@ -622,7 +671,14 @@ static int apply_objects_internal(bContext *C, changed = false; /* now execute */ - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { + int num_objects; + Object **objects = sorted_selected_editable_objects(C, &num_objects); + if (objects == NULL) { + return OPERATOR_CANCELLED; + } + + for (int object_index = 0; object_index < num_objects; ++object_index) { + Object *ob = objects[object_index]; /* calculate rotation/scale matrix */ if (apply_scale && apply_rot) { @@ -793,13 +849,14 @@ static int apply_objects_internal(bContext *C, BKE_pose_where_is(depsgraph, scene, ob_eval); } - ignore_parent_tx(C, bmain, scene, ob); + ignore_parent_tx(bmain, depsgraph, scene, ob); DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); changed = true; } - CTX_DATA_END; + + MEM_freeN(objects); if (!changed) { BKE_report(reports, RPT_WARNING, "Objects have no data to transform"); @@ -914,10 +971,6 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) const float *cursor = scene->cursor.location; int centermode = RNA_enum_get(op->ptr, "type"); - ListBase ctx_data_list; - CollectionPointerLink *ctx_ob; - CollectionPointerLink *ctx_ob_act = NULL; - /* keep track of what is changed */ int tot_change = 0, tot_lib_error = 0, tot_multiuser_arm_error = 0; @@ -986,23 +1039,24 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) } } - CTX_data_selected_editable_objects(C, &ctx_data_list); + int num_objects; + Object **objects = sorted_selected_editable_objects(C, &num_objects); + if (objects == NULL) { + return OPERATOR_CANCELLED; + } /* reset flags */ - for (ctx_ob = ctx_data_list.first; ctx_ob; ctx_ob = ctx_ob->next) { - Object *ob = ctx_ob->ptr.data; + for (int object_index = 0; object_index < num_objects; ++object_index) { + Object *ob = objects[object_index]; ob->flag &= ~OB_DONE; /* move active first */ if (ob == obact) { - ctx_ob_act = ctx_ob; + memmove(&objects[1], objects, object_index); + objects[0] = ob; } } - if (ctx_ob_act) { - BLI_listbase_rotate_first(&ctx_data_list, (LinkData *)ctx_ob_act); - } - for (tob = bmain->objects.first; tob; tob = tob->id.next) { if (tob->data) { ((ID *)tob->data)->tag &= ~LIB_TAG_DOIT; @@ -1012,8 +1066,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) } } - for (ctx_ob = ctx_data_list.first; ctx_ob; ctx_ob = ctx_ob->next) { - Object *ob = ctx_ob->ptr.data; + for (int object_index = 0; object_index < num_objects; ++object_index) { + Object *ob = objects[object_index]; if ((ob->flag & OB_DONE) == 0) { bool do_inverse_offset = false; @@ -1166,7 +1220,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) BKE_object_where_is_calc(depsgraph, scene, ob); BKE_pose_where_is(depsgraph, scene, ob); /* needed for bone parents */ - ignore_parent_tx(C, bmain, scene, ob); + ignore_parent_tx(bmain, depsgraph, scene, ob); if (obedit) { break; @@ -1288,7 +1342,6 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) /* offset other selected objects */ if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) { - CollectionPointerLink *ctx_link_other; float obmat[4][4]; /* was the object data modified @@ -1305,16 +1358,15 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) BKE_pose_where_is(depsgraph, scene, ob); /* needed for bone parents */ } - ignore_parent_tx(C, bmain, scene, ob); + ignore_parent_tx(bmain, depsgraph, scene, ob); /* other users? */ // CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects) //{ /* use existing context looper */ - for (ctx_link_other = ctx_data_list.first; ctx_link_other; - ctx_link_other = ctx_link_other->next) { - Object *ob_other = ctx_link_other->ptr.data; + for (int other_object_index = 0; other_object_index < num_objects; ++other_object_index) { + Object *ob_other = objects[other_object_index]; if ((ob_other->flag & OB_DONE) == 0 && ((ob->data && (ob->data == ob_other->data)) || @@ -1331,14 +1383,14 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) /* needed for bone parents */ BKE_pose_where_is(depsgraph, scene, ob_other); } - ignore_parent_tx(C, bmain, scene, ob_other); + ignore_parent_tx(bmain, depsgraph, scene, ob_other); } } // CTX_DATA_END; } } } - BLI_freelistN(&ctx_data_list); + MEM_freeN(objects); for (tob = bmain->objects.first; tob; tob = tob->id.next) { if (tob->data && (((ID *)tob->data)->tag & LIB_TAG_DOIT)) { diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 7506ad37908..dc634865a0a 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -778,7 +778,6 @@ static void foreach_mouse_hit_key_iter(void *__restrict iter_data_v, } ParticleSystem *psys = edit->psys; ParticleSystemModifierData *psmd_eval = iter_data->edit->psmd_eval; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); ParticleEditSettings *pset = PE_settings(data->scene); const int selected = iter_data->selected; float mat[4][4], imat[4][4]; @@ -794,7 +793,7 @@ static void foreach_mouse_hit_key_iter(void *__restrict iter_data_v, if (key_inside_circle(data, data->rad, KEY_WCO, &mouse_distance)) { if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { psys_mat_hair_to_global( - data->ob, mesh_final, psys->part->from, psys->particles + iter, mat); + data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, mat); invert_m4_m4(imat, mat); } iter_data->func(data, mat, imat, iter, point->totkey - 1, key, mouse_distance); @@ -813,7 +812,7 @@ static void foreach_mouse_hit_key_iter(void *__restrict iter_data_v, if (key_inside_circle(data, data->rad, KEY_WCO, &mouse_distance)) { if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { psys_mat_hair_to_global( - data->ob, mesh_final, psys->part->from, psys->particles + iter, mat); + data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, mat); invert_m4_m4(imat, mat); } iter_data->func(data, mat, imat, iter, k, key, mouse_distance); @@ -928,9 +927,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) psmd_eval = edit->psmd_eval; totpart = psys->totpart; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - - if (!mesh_final) { + if (!psmd_eval->mesh_final) { return; } @@ -940,7 +937,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) LOOP_PARTICLES { key = pa->hair; - psys_mat_hair_to_orco(ob, mesh_final, psys->part->from, pa, mat); + psys_mat_hair_to_orco(ob, psmd_eval->mesh_final, psys->part->from, pa, mat); copy_v3_v3(co, key->co); mul_m4_v3(mat, co); BLI_kdtree_3d_insert(tree, p, co); @@ -956,7 +953,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) LOOP_PARTICLES { key = pa->hair; - psys_mat_hair_to_orco(ob, mesh_final, psys->part->from, pa, mat); + psys_mat_hair_to_orco(ob, psmd_eval->mesh_final, psys->part->from, pa, mat); copy_v3_v3(co, key->co); mul_m4_v3(mat, co); co[0] = -co[0]; @@ -1087,9 +1084,8 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys) edit = psys->edit; psmd_eval = edit->psmd_eval; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - if (!mesh_final) { + if (!psmd_eval->mesh_final) { return; } @@ -1106,7 +1102,7 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys) LOOP_POINTS { if (point->flag & PEP_EDIT_RECALC) { - PE_mirror_particle(ob, mesh_final, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, psmd_eval->mesh_final, psys, psys->particles + p, NULL); if (edit->mirror_cache[p] != -1) { edit->points[edit->mirror_cache[p]].flag &= ~PEP_EDIT_RECALC; @@ -1156,8 +1152,8 @@ static void deflect_emitter_iter(void *__restrict iter_data_v, float *vec, *nor, dvec[3], dot, dist_1st = 0.0f; const float dist = iter_data->dist; const float emitterdist = iter_data->emitterdist; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - psys_mat_hair_to_object(object, mesh_final, psys->part->from, psys->particles + iter, hairmat); + psys_mat_hair_to_object( + object, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, hairmat); LOOP_KEYS { @@ -1221,8 +1217,7 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit) psys = edit->psys; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(edit->psmd_eval); - if (!mesh_final) { + if (!edit->psmd_eval->mesh_final) { return; } @@ -1387,7 +1382,7 @@ void recalc_lengths(PTCacheEdit *edit) void recalc_emitter_field(Depsgraph *UNUSED(depsgraph), Object *UNUSED(ob), ParticleSystem *psys) { PTCacheEdit *edit = psys->edit; - Mesh *mesh = BKE_particle_modifier_mesh_final_get(edit->psmd_eval); + Mesh *mesh = edit->psmd_eval->mesh_final; float *vec, *nor; int i, totface /*, totvert*/; @@ -1494,16 +1489,15 @@ void update_world_cos(Depsgraph *UNUSED(depsgraph), Object *ob, PTCacheEdit *edi KEY_K; float hairmat[4][4]; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - - if (psys == 0 || psys->edit == 0 || mesh_final == NULL) { + if (psys == 0 || psys->edit == 0 || psmd_eval->mesh_final == NULL) { return; } LOOP_POINTS { if (!(psys->flag & PSYS_GLOBAL_HAIR)) { - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + p, hairmat); + psys_mat_hair_to_global( + ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, hairmat); } LOOP_KEYS @@ -2275,12 +2269,11 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, const data.is_changed |= PE_deselect_all_visible_ex(edit); } - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - LOOP_VISIBLE_POINTS { if (edit->psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_global( + ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat); } if (pset->selectmode == SCE_SELECT_POINT) { @@ -2746,11 +2739,10 @@ static int remove_tagged_particles(Object *ob, ParticleSystem *psys, int mirror) if (mirror) { /* mirror tags */ psmd_eval = edit->psmd_eval; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); LOOP_TAGGED_POINTS { - PE_mirror_particle(ob, mesh_final, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, psmd_eval->mesh_final, psys, psys->particles + p, NULL); } } @@ -2839,13 +2831,12 @@ static void remove_tagged_keys(Depsgraph *depsgraph, Object *ob, ParticleSystem ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); ParticleSystemModifierData *psmd_eval = (ParticleSystemModifierData *)modifier_get_evaluated( depsgraph, ob, &psmd->modifier); - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); LOOP_POINTS { LOOP_TAGGED_KEYS { - PE_mirror_particle(ob, mesh_final, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, psmd_eval->mesh_final, psys, psys->particles + p, NULL); break; } } @@ -3072,8 +3063,6 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) psmd_eval = edit->psmd_eval; totremoved = 0; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - do { removed = 0; @@ -3082,7 +3071,8 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) /* insert particles into kd tree */ LOOP_SELECTED_POINTS { - psys_mat_hair_to_object(ob, mesh_final, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_object( + ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat); copy_v3_v3(co, point->keys->co); mul_m4_v3(mat, co); BLI_kdtree_3d_insert(tree, p, co); @@ -3093,7 +3083,8 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) /* tag particles to be removed */ LOOP_SELECTED_POINTS { - psys_mat_hair_to_object(ob, mesh_final, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_object( + ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat); copy_v3_v3(co, point->keys->co); mul_m4_v3(mat, co); @@ -3356,22 +3347,20 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) } psmd_eval = edit->psmd_eval; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(psmd_eval); - - if (!mesh_final) { + if (!psmd_eval->mesh_final) { return; } const bool use_dm_final_indices = (psys->part->use_modifier_stack && - !mesh_final->runtime.deformed_only); + !psmd_eval->mesh_final->runtime.deformed_only); /* NOTE: this is not nice to use tessfaces but hard to avoid since pa->num uses tessfaces */ BKE_mesh_tessface_ensure(me); /* NOTE: In case psys uses Mesh tessface indices, we mirror final Mesh itself, not orig mesh. * Avoids an (impossible) mesh -> orig -> mesh tessface indices conversion. */ - mirrorfaces = mesh_get_x_mirror_faces(ob, NULL, use_dm_final_indices ? mesh_final : NULL); + mirrorfaces = mesh_get_x_mirror_faces( + ob, NULL, use_dm_final_indices ? psmd_eval->mesh_final : NULL); if (!edit->mirror_cache) { PE_update_mirror_cache(ob, psys); @@ -3387,7 +3376,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) if (point_is_selected(point)) { if (edit->mirror_cache[p] != -1) { /* already has a mirror, don't need to duplicate */ - PE_mirror_particle(ob, mesh_final, psys, pa, NULL); + PE_mirror_particle(ob, psmd_eval->mesh_final, psys, pa, NULL); continue; } else { @@ -3402,7 +3391,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) } if (newtotpart != psys->totpart) { - MFace *mtessface = use_dm_final_indices ? mesh_final->mface : me->mface; + MFace *mtessface = use_dm_final_indices ? psmd_eval->mesh_final->mface : me->mface; /* allocate new arrays and copy existing */ new_pars = MEM_callocN(newtotpart * sizeof(ParticleData), "ParticleData new"); @@ -3478,7 +3467,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) } else { newpa->num_dmcache = psys_particle_dm_face_lookup( - mesh_final, mesh_original, newpa->num, newpa->fuv, NULL); + psmd_eval->mesh_final, psmd_eval->mesh_original, newpa->num, newpa->fuv, NULL); } /* update edit key pointers */ @@ -3489,7 +3478,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) } /* map key positions as mirror over x axis */ - PE_mirror_particle(ob, mesh_final, psys, pa, newpa); + PE_mirror_particle(ob, psmd_eval->mesh_final, psys, pa, newpa); newpa++; newpoint++; @@ -4168,18 +4157,19 @@ static void brush_add_count_iter(void *__restrict iter_data_v, 0, 0, 0)) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(psmd_eval); - if (psys->part->use_modifier_stack && !mesh_final->runtime.deformed_only) { + if (psys->part->use_modifier_stack && !psmd_eval->mesh_final->runtime.deformed_only) { add_pars[iter].num = add_pars[iter].num_dmcache; add_pars[iter].num_dmcache = DMCACHE_ISCHILD; } - else if (iter_data->mesh == mesh_original) { + else if (iter_data->mesh == psmd_eval->mesh_original) { /* Final DM is not same topology as orig mesh, * we have to map num_dmcache to real final dm. */ add_pars[iter].num = add_pars[iter].num_dmcache; - add_pars[iter].num_dmcache = psys_particle_dm_face_lookup( - mesh_final, mesh_original, add_pars[iter].num, add_pars[iter].fuv, NULL); + add_pars[iter].num_dmcache = psys_particle_dm_face_lookup(psmd_eval->mesh_final, + psmd_eval->mesh_original, + add_pars[iter].num, + add_pars[iter].fuv, + NULL); } else { add_pars[iter].num = add_pars[iter].num_dmcache; @@ -4237,12 +4227,11 @@ static int brush_add(const bContext *C, PEData *data, short number) timestep = psys_get_timestep(&sim); - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - if (psys->part->use_modifier_stack || mesh_final->runtime.deformed_only) { - mesh = mesh_final; + if (psys->part->use_modifier_stack || psmd_eval->mesh_final->runtime.deformed_only) { + mesh = psmd_eval->mesh_final; } else { - mesh = BKE_particle_modifier_mesh_original_get(psmd_eval); + mesh = psmd_eval->mesh_original; } BLI_assert(mesh); @@ -4326,7 +4315,7 @@ static int brush_add(const bContext *C, PEData *data, short number) tree = BLI_kdtree_3d_new(psys->totpart); for (i = 0, pa = psys->particles; i < totpart; i++, pa++) { - psys_particle_on_dm(mesh_final, + psys_particle_on_dm(psmd_eval->mesh_final, psys->part->from, pa->num, pa->num_dmcache, @@ -4383,7 +4372,7 @@ static int brush_add(const bContext *C, PEData *data, short number) int w, maxw; float maxd, totw = 0.0, weight[3]; - psys_particle_on_dm(mesh_final, + psys_particle_on_dm(psmd_eval->mesh_final, psys->part->from, pa->num, pa->num_dmcache, @@ -4461,7 +4450,7 @@ static int brush_add(const bContext *C, PEData *data, short number) } } for (k = 0, hkey = pa->hair; k < pset->totaddkey; k++, hkey++) { - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, psmd_eval->mesh_final, psys->part->from, pa, hairmat); invert_m4_m4(imat, hairmat); mul_m4_v3(imat, hkey->co); } @@ -4662,7 +4651,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) } case PE_BRUSH_PUFF: { if (edit->psys) { - data.mesh = BKE_particle_modifier_mesh_final_get(psmd_eval); + data.mesh = psmd_eval->mesh_final; data.mval = mval; data.rad = pe_brush_size_get(scene, brush); data.select = selected; @@ -4719,7 +4708,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) } case PE_BRUSH_WEIGHT: { if (edit->psys) { - data.mesh = BKE_particle_modifier_mesh_final_get(psmd_eval); + data.mesh = psmd_eval->mesh_final; data.mval = mval; data.rad = pe_brush_size_get(scene, brush); @@ -5093,8 +5082,8 @@ int PE_minmax(Scene *scene, ViewLayer *view_layer, float min[3], float max[3]) LOOP_VISIBLE_POINTS { if (psys) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_global( + ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat); } LOOP_SELECTED_KEYS @@ -5135,8 +5124,7 @@ void PE_create_particle_edit( } /* no psmd->dm happens in case particle system modifier is not enabled */ - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - if (!(psys && psmd && mesh_final) && !cache) { + if (!(psys && psmd && psmd_eval->mesh_final) && !cache) { return; } diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index d85bf72851d..b03ec56c7e4 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -620,7 +620,6 @@ static void disconnect_hair(Depsgraph *depsgraph, Scene *scene, Object *ob, Part edit = psys->edit; point = edit ? edit->points : NULL; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); for (i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) { if (point) { @@ -628,7 +627,7 @@ static void disconnect_hair(Depsgraph *depsgraph, Scene *scene, Object *ob, Part point++; } - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, psmd_eval->mesh_final, psys->part->from, pa, hairmat); for (k = 0, key = pa->hair; k < pa->totkey; k++, key++) { mul_m4_v3(hairmat, key->co); @@ -726,8 +725,7 @@ static bool remap_hair_emitter(Depsgraph *depsgraph, float from_ob_imat[4][4], to_ob_imat[4][4]; float from_imat[4][4], to_imat[4][4]; - Mesh *target_mesh_final = BKE_particle_modifier_mesh_final_get(target_psmd); - if (!target_mesh_final) { + if (!target_psmd->mesh_final) { return false; } if (!psys->part || psys->part->type != PART_HAIR) { @@ -744,14 +742,14 @@ static bool remap_hair_emitter(Depsgraph *depsgraph, invert_m4_m4(from_imat, from_mat); invert_m4_m4(to_imat, to_mat); - if (target_mesh_final->runtime.deformed_only) { + if (target_psmd->mesh_final->runtime.deformed_only) { /* we don't want to mess up target_psmd->dm when converting to global coordinates below */ - mesh = target_mesh_final; + mesh = target_psmd->mesh_final; } else { - mesh = BKE_particle_modifier_mesh_original_get(target_psmd); + mesh = target_psmd->mesh_original; } - target_mesh = target_mesh_final; + target_mesh = target_psmd->mesh_final; if (mesh == NULL) { return false; } @@ -1157,13 +1155,10 @@ static bool copy_particle_systems_to_object(const bContext *C, modifier_unique_name(&ob_to->modifiers, (ModifierData *)psmd); psmd->psys = psys; + BKE_id_copy_ex(NULL, &final_mesh->id, (ID **)&psmd->mesh_final, LIB_ID_COPY_LOCALIZE); - /* TODO(sergey): This should probably be accessing evaluated psmd. */ - ParticleSystemModifierDataRuntime *runtime = BKE_particle_modifier_runtime_ensure(psmd); - BKE_id_copy_ex(NULL, &final_mesh->id, (ID **)&runtime->mesh_final, LIB_ID_COPY_LOCALIZE); - - BKE_mesh_calc_normals(runtime->mesh_final); - BKE_mesh_tessface_ensure(runtime->mesh_final); + BKE_mesh_calc_normals(psmd->mesh_final); + BKE_mesh_tessface_ensure(psmd->mesh_final); if (psys_from->edit) { copy_particle_edit(depsgraph, scene, ob_to, psys, psys_from); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 9a46dab8c20..12891484e73 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -182,6 +182,7 @@ static void paint_draw_line_cursor(bContext *C, int x, int y, void *customdata) immUniformArray4fv( "colors", (float *)(float[][4]){{0.0f, 0.0f, 0.0f, alpha}, {1.0f, 1.0f, 1.0f, alpha}}, 2); immUniform1f("dash_width", 6.0f); + immUniform1f("dash_factor", 0.5f); immBegin(GPU_PRIM_LINES, 2); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 5a7fb1abb7b..ec7cb410f2c 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -5807,6 +5807,7 @@ static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(o } WM_cursor_wait(0); + WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 75a2af4526f..8c8d4487ada 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -459,6 +459,7 @@ static void sculpt_undo_restore_list(bContext *C, ListBase *lb) { Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); + View3D *v3d = CTX_wm_view3d(C); Object *ob = OBACT(view_layer); Depsgraph *depsgraph = CTX_data_depsgraph(C); SculptSession *ss = ob->sculpt; @@ -560,7 +561,7 @@ static void sculpt_undo_restore_list(bContext *C, ListBase *lb) } } - tag_update |= ((Mesh *)ob->data)->id.us > 1; + tag_update |= ((Mesh *)ob->data)->id.us > 1 || !BKE_sculptsession_use_pbvh_draw(ob, v3d); if (ss->kb || ss->modifiers_active) { Mesh *mesh = ob->data; diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 9b57644b6ec..86db6d50fcc 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -699,6 +699,7 @@ void draw_image_sample_line(SpaceImage *sima) immUniformArray4fv( "colors", (float *)(float[][4]){{1.0f, 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2); immUniform1f("dash_width", 2.0f); + immUniform1f("dash_factor", 0.5f); immBegin(GPU_PRIM_LINES, 2); immVertex2fv(shdr_dashed_pos, hist->co[0]); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index bdc6c394609..9eda7ffdc34 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -234,14 +234,6 @@ static bool image_not_packed_poll(bContext *C) return (ima && BLI_listbase_is_empty(&ima->packedfiles)); } -static bool imbuf_format_writeable(const ImBuf *ibuf) -{ - ImageFormatData im_format; - ImbFormatOptions options_dummy; - BKE_imbuf_to_image_format(&im_format, ibuf); - return (BKE_image_imtype_to_ftype(im_format.imtype, &options_dummy) == ibuf->ftype); -} - bool space_image_main_region_poll(bContext *C) { SpaceImage *sima = CTX_wm_space_image(C); @@ -2060,7 +2052,7 @@ static bool image_file_path_saveable(bContext *C, Image *ima, ImageUser *iuser) else if (!BLI_file_is_writable(name)) { CTX_wm_operator_poll_msg_set(C, "image path can't be written to"); } - else if (!imbuf_format_writeable(ibuf)) { + else if (!BKE_image_buffer_format_writable(ibuf)) { CTX_wm_operator_poll_msg_set(C, "image format is read-only"); } else { @@ -2254,9 +2246,9 @@ static bool image_should_be_saved_when_modified(Image *ima) return !ELEM(ima->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE); } -static bool image_should_be_saved(Image *ima) +static bool image_should_be_saved(Image *ima, bool *is_format_writable) { - if (BKE_image_is_dirty(ima) && + if (BKE_image_is_dirty_writable(ima, is_format_writable) && (ima->source == IMA_SRC_FILE || ima->source == IMA_SRC_GENERATED)) { return image_should_be_saved_when_modified(ima); } @@ -2272,7 +2264,15 @@ static bool image_has_valid_path(Image *ima) bool ED_image_should_save_modified(const bContext *C) { - return ED_image_save_all_modified_info(C, NULL) > 0; + ReportList reports; + BKE_reports_init(&reports, RPT_STORE); + + uint modified_images_count = ED_image_save_all_modified_info(C, &reports); + bool should_save = modified_images_count || !BLI_listbase_is_empty(&reports.list); + + BKE_reports_clear(&reports); + + return should_save; } int ED_image_save_all_modified_info(const bContext *C, ReportList *reports) @@ -2283,7 +2283,9 @@ int ED_image_save_all_modified_info(const bContext *C, ReportList *reports) int num_saveable_images = 0; for (Image *ima = bmain->images.first; ima; ima = ima->id.next) { - if (image_should_be_saved(ima)) { + bool is_format_writable; + + if (image_should_be_saved(ima, &is_format_writable)) { if (BKE_image_has_packedfile(ima) || (ima->source == IMA_SRC_GENERATED)) { if (ima->id.lib == NULL) { num_saveable_images++; @@ -2292,10 +2294,16 @@ int ED_image_save_all_modified_info(const bContext *C, ReportList *reports) BKE_reportf(reports, RPT_WARNING, "Packed library image: %s from library %s can't be saved", - ima->id.name, + ima->id.name + 2, ima->id.lib->name); } } + else if (!is_format_writable) { + BKE_reportf(reports, + RPT_WARNING, + "Image %s can't be saved automatically, must use a different file format", + ima->id.name + 2); + } else { if (image_has_valid_path(ima)) { num_saveable_images++; @@ -2313,7 +2321,7 @@ int ED_image_save_all_modified_info(const bContext *C, ReportList *reports) BKE_reportf(reports, RPT_WARNING, "Image %s can't be saved, no valid file path: %s", - ima->id.name, + ima->id.name + 2, ima->name); } } @@ -2332,11 +2340,13 @@ bool ED_image_save_all_modified(const bContext *C, ReportList *reports) bool ok = true; for (Image *ima = bmain->images.first; ima; ima = ima->id.next) { - if (image_should_be_saved(ima)) { + bool is_format_writable; + + if (image_should_be_saved(ima, &is_format_writable)) { if (BKE_image_has_packedfile(ima) || (ima->source == IMA_SRC_GENERATED)) { BKE_image_memorypack(ima); } - else { + else if (is_format_writable) { if (image_has_valid_path(ima)) { ImageSaveOptions opts; Scene *scene = CTX_data_scene(C); diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index fed56f3d452..a151061ae64 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -31,6 +31,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_sequence_types.h" +#include "DNA_object_force_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" @@ -2207,6 +2208,9 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) else if (ob->empty_drawtype == OB_EMPTY_IMAGE) { data.icon = ICON_OUTLINER_OB_IMAGE; } + else if (ob->pd && ob->pd->forcefield) { + data.icon = ICON_OUTLINER_OB_FORCE_FIELD; + } else { data.icon = ICON_OUTLINER_OB_EMPTY; } diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 525874c5939..b24f8e8d00f 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -625,13 +625,14 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad } } + if (op->customdata) { + MEM_freeN(op->customdata); + } + if (seq_load.tot_success == 0) { BKE_reportf(op->reports, RPT_ERROR, "File '%s' could not be loaded", seq_load.path); - return OPERATOR_CANCELLED; - } - if (op->customdata) { - MEM_freeN(op->customdata); + return OPERATOR_CANCELLED; } BKE_sequencer_sort(scene); diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index f1ee606a06b..e53a3cb02a7 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -38,12 +38,14 @@ #include "DNA_space_types.h" #include "DNA_userdef_types.h" #include "DNA_sound_types.h" +#include "DNA_anim_types.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_sequencer.h" #include "BKE_sound.h" #include "BKE_scene.h" +#include "BKE_fcurve.h" #include "IMB_colormanagement.h" #include "IMB_imbuf.h" @@ -251,8 +253,10 @@ static void drawseqwave(View2D *v2d, float yscale = (y2 - y1) / 2.0f; float samplestep; float startsample, endsample; + float volume = seq->volume; float value1, value2; bSound *sound = seq->sound; + FCurve *fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, NULL); SoundWaveform *waveform; @@ -329,8 +333,12 @@ static void drawseqwave(View2D *v2d, value2 = (1.0f - f) * value2 + f * waveform->data[p * 3 + 4]; } - value1 *= seq->volume; - value2 *= seq->volume; + if (fcu) { + float evaltime = x1_offset + (i * stepsize); + volume = evaluate_fcurve(fcu, evaltime); + } + value1 *= volume; + value2 *= volume; if (value2 > 1 || value1 < -1) { immAttr4f(col, 1.0f, 0.0f, 0.0f, 0.5f); diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 1bc21664287..12b446c3f4c 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -849,7 +849,7 @@ void ED_spacetype_sequencer(void) /* regions: listview/buttons */ art = MEM_callocN(sizeof(ARegionType), "spacetype sequencer region"); art->regionid = RGN_TYPE_UI; - art->prefsizex = UI_SIDEBAR_PANEL_WIDTH; + art->prefsizex = UI_SIDEBAR_PANEL_WIDTH * 1.3f; art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES; art->listener = sequencer_buttons_region_listener; art->init = sequencer_buttons_region_init; diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c index 08ac0d91d42..386c3164843 100644 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c @@ -301,341 +301,6 @@ uint *ED_view3d_select_id_read(int xmin, int ymin, int xmax, int ymax, uint *r_b return buf; } -/* ************************************************************* */ - -static void view3d_stereo_bgpic_setup(Scene *scene, View3D *v3d, Image *ima, ImageUser *iuser) -{ - if (BKE_image_is_stereo(ima)) { - iuser->flag |= IMA_SHOW_STEREO; - - if ((scene->r.scemode & R_MULTIVIEW) == 0) { - iuser->multiview_eye = STEREO_LEFT_ID; - } - else if (v3d->stereo3d_camera != STEREO_3D_ID) { - /* show only left or right camera */ - iuser->multiview_eye = v3d->stereo3d_camera; - } - - BKE_image_multiview_index(ima, iuser); - } - else { - iuser->flag &= ~IMA_SHOW_STEREO; - } -} - -static void view3d_draw_bgpic(Scene *scene, - Depsgraph *depsgraph, - ARegion *ar, - View3D *v3d, - const bool do_foreground, - const bool do_camera_frame) -{ - RegionView3D *rv3d = ar->regiondata; - int fg_flag = do_foreground ? CAM_BGIMG_FLAG_FOREGROUND : 0; - if (v3d->camera == NULL || v3d->camera->type != OB_CAMERA) { - return; - } - Camera *cam = v3d->camera->data; - - for (CameraBGImage *bgpic = cam->bg_images.first; bgpic; bgpic = bgpic->next) { - if ((bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) != fg_flag) { - continue; - } - - { - float image_aspect[2]; - float x1, y1, x2, y2, centx, centy; - - void *lock; - - Image *ima = NULL; - - /* disable individual images */ - if ((bgpic->flag & CAM_BGIMG_FLAG_DISABLED)) { - continue; - } - - ImBuf *ibuf = NULL; - ImBuf *freeibuf = NULL; - ImBuf *releaseibuf = NULL; - if (bgpic->source == CAM_BGIMG_SOURCE_IMAGE) { - ima = bgpic->ima; - if (ima == NULL) { - continue; - } - - ImageUser iuser = bgpic->iuser; - iuser.scene = scene; /* Needed for render results. */ - BKE_image_user_frame_calc(ima, &iuser, (int)DEG_get_ctime(depsgraph)); - if (ima->source == IMA_SRC_SEQUENCE && !(iuser.flag & IMA_USER_FRAME_IN_RANGE)) { - ibuf = NULL; /* frame is out of range, dont show */ - } - else { - view3d_stereo_bgpic_setup(scene, v3d, ima, &iuser); - ibuf = BKE_image_acquire_ibuf(ima, &iuser, &lock); - releaseibuf = ibuf; - } - - image_aspect[0] = ima->aspx; - image_aspect[1] = ima->aspy; - } - else if (bgpic->source == CAM_BGIMG_SOURCE_MOVIE) { - /* TODO: skip drawing when out of frame range (as image sequences do above) */ - MovieClip *clip = NULL; - - if (bgpic->flag & CAM_BGIMG_FLAG_CAMERACLIP) { - if (scene->camera) { - clip = BKE_object_movieclip_get(scene, scene->camera, true); - } - } - else { - clip = bgpic->clip; - } - - if (clip == NULL) { - continue; - } - - BKE_movieclip_user_set_frame(&bgpic->cuser, (int)DEG_get_ctime(depsgraph)); - ibuf = BKE_movieclip_get_ibuf(clip, &bgpic->cuser); - - image_aspect[0] = clip->aspx; - image_aspect[1] = clip->aspy; - - /* working with ibuf from image and clip has got different workflow now. - * ibuf acquired from clip is referenced by cache system and should - * be dereferenced after usage. */ - freeibuf = ibuf; - } - else { - /* perhaps when loading future files... */ - BLI_assert(0); - copy_v2_fl(image_aspect, 1.0f); - } - - if (ibuf == NULL) { - continue; - } - - if ((ibuf->rect == NULL && ibuf->rect_float == NULL) || ibuf->channels != 4) { - /* invalid image format */ - if (freeibuf) { - IMB_freeImBuf(freeibuf); - } - if (releaseibuf) { - BKE_image_release_ibuf(ima, releaseibuf, lock); - } - - continue; - } - - if (ibuf->rect == NULL) { - IMB_rect_from_float(ibuf); - } - - BLI_assert(rv3d->persp == RV3D_CAMOB); - { - if (do_camera_frame) { - rctf vb; - ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &vb, false); - x1 = vb.xmin; - y1 = vb.ymin; - x2 = vb.xmax; - y2 = vb.ymax; - } - else { - x1 = ar->winrct.xmin; - y1 = ar->winrct.ymin; - x2 = ar->winrct.xmax; - y2 = ar->winrct.ymax; - } - - /* apply offset last - camera offset is different to offset in blender units */ - /* so this has some sane way of working - this matches camera's shift _exactly_ */ - { - const float max_dim = max_ff(x2 - x1, y2 - y1); - const float xof_scale = bgpic->offset[0] * max_dim; - const float yof_scale = bgpic->offset[1] * max_dim; - - x1 += xof_scale; - y1 += yof_scale; - x2 += xof_scale; - y2 += yof_scale; - } - - centx = (x1 + x2) * 0.5f; - centy = (y1 + y2) * 0.5f; - - /* aspect correction */ - if (bgpic->flag & CAM_BGIMG_FLAG_CAMERA_ASPECT) { - /* apply aspect from clip */ - const float w_src = ibuf->x * image_aspect[0]; - const float h_src = ibuf->y * image_aspect[1]; - - /* destination aspect is already applied from the camera frame */ - const float w_dst = x1 - x2; - const float h_dst = y1 - y2; - - const float asp_src = w_src / h_src; - const float asp_dst = w_dst / h_dst; - - if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) { - if ((asp_src > asp_dst) == ((bgpic->flag & CAM_BGIMG_FLAG_CAMERA_CROP) != 0)) { - /* fit X */ - const float div = asp_src / asp_dst; - x1 = ((x1 - centx) * div) + centx; - x2 = ((x2 - centx) * div) + centx; - } - else { - /* fit Y */ - const float div = asp_dst / asp_src; - y1 = ((y1 - centy) * div) + centy; - y2 = ((y2 - centy) * div) + centy; - } - } - } - } - - /* complete clip? */ - rctf clip_rect; - BLI_rctf_init(&clip_rect, x1, x2, y1, y2); - if (bgpic->rotation) { - BLI_rctf_rotate_expand(&clip_rect, &clip_rect, bgpic->rotation); - } - - if (clip_rect.xmax < 0 || clip_rect.ymax < 0 || clip_rect.xmin > ar->winx || - clip_rect.ymin > ar->winy) { - if (freeibuf) { - IMB_freeImBuf(freeibuf); - } - if (releaseibuf) { - BKE_image_release_ibuf(ima, releaseibuf, lock); - } - - continue; - } - - float zoomx = (x2 - x1) / ibuf->x; - float zoomy = (y2 - y1) / ibuf->y; - - /* For some reason; zoom-levels down refuses to use GL_ALPHA_SCALE. */ - if (zoomx < 1.0f || zoomy < 1.0f) { - float tzoom = min_ff(zoomx, zoomy); - int mip = 0; - - if ((ibuf->userflags & IB_MIPMAP_INVALID) != 0) { - IMB_remakemipmap(ibuf, 0); - ibuf->userflags &= ~IB_MIPMAP_INVALID; - } - else if (ibuf->mipmap[0] == NULL) { - IMB_makemipmap(ibuf, 0); - } - - while (tzoom < 1.0f && mip < 8 && ibuf->mipmap[mip]) { - tzoom *= 2.0f; - zoomx *= 2.0f; - zoomy *= 2.0f; - mip++; - } - if (mip > 0) { - ibuf = ibuf->mipmap[mip - 1]; - } - } - - GPU_depth_test(!do_foreground); - glDepthMask(GL_FALSE); - - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - - GPU_matrix_push_projection(); - GPU_matrix_push(); - ED_region_pixelspace(ar); - - GPU_matrix_translate_2f(centx, centy); - GPU_matrix_scale_1f(bgpic->scale); - GPU_matrix_rotate_2d(RAD2DEGF(-bgpic->rotation)); - - if (bgpic->flag & CAM_BGIMG_FLAG_FLIP_X) { - zoomx *= -1.0f; - x1 = x2; - } - if (bgpic->flag & CAM_BGIMG_FLAG_FLIP_Y) { - zoomy *= -1.0f; - y1 = y2; - } - - float col[4] = {1.0f, 1.0f, 1.0f, bgpic->alpha}; - IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); - immDrawPixelsTex(&state, - x1 - centx, - y1 - centy, - ibuf->x, - ibuf->y, - GL_RGBA, - GL_UNSIGNED_BYTE, - GL_LINEAR, - ibuf->rect, - zoomx, - zoomy, - col); - - GPU_matrix_pop_projection(); - GPU_matrix_pop(); - - GPU_blend(false); - - glDepthMask(GL_TRUE); - GPU_depth_test(true); - - if (freeibuf) { - IMB_freeImBuf(freeibuf); - } - if (releaseibuf) { - BKE_image_release_ibuf(ima, releaseibuf, lock); - } - } - } -} - -void ED_view3d_draw_bgpic_test(Scene *scene, - Depsgraph *depsgraph, - ARegion *ar, - View3D *v3d, - const bool do_foreground, - const bool do_camera_frame) -{ - RegionView3D *rv3d = ar->regiondata; - - if ((rv3d->persp == RV3D_CAMOB) && v3d->camera && (v3d->camera->type == OB_CAMERA)) { - Camera *cam = v3d->camera->data; - if ((cam->flag & CAM_SHOW_BG_IMAGE) == 0) { - return; - } - } - else { - return; - } - - /* disabled - mango request, since footage /w only render is quite useful - * and this option is easy to disable all background images at once */ -#if 0 - if (v3d->flag2 & V3D_HIDE_OVERLAYS) { - return; - } -#endif - - if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) { - if (rv3d->persp == RV3D_CAMOB) { - view3d_draw_bgpic(scene, depsgraph, ar, v3d, do_foreground, do_camera_frame); - } - } - else { - view3d_draw_bgpic(scene, depsgraph, ar, v3d, do_foreground, do_camera_frame); - } -} - /* *********************** */ void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect) diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index 566a15cc7b7..ebfd66008f7 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -563,6 +563,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2); immUniform1f("dash_width", 6.0f); + immUniform1f("dash_factor", 0.5f); immBegin(GPU_PRIM_LINE_STRIP, 3); @@ -725,6 +726,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2); immUniform1f("dash_width", 6.0f); + immUniform1f("dash_factor", 0.5f); immBegin(GPU_PRIM_LINES, 2); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index c1b5b553c21..a694a8e7305 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -138,6 +138,9 @@ struct EDSelectID_Context { uint bases_len; /** Total number of items `base_array_index_offsets[bases_len - 1].vert`. */ uint base_array_index_len; + /** Used to check for changes. (Use depsgraph instead?). */ + float persmat[4][4]; + short select_mode; }; static bool check_ob_drawface_dot(short select_mode, const View3D *v3d, char dt) @@ -191,6 +194,14 @@ static void ed_select_id_draw_bases(struct EDSelectID_Context *sel_id_ctx, DRW_framebuffer_select_id_release(vc->ar); } +void ED_view3d_select_id_validate_view_matrices(const struct EDSelectID_Context *sel_id_ctx, + ViewContext *vc) +{ + if (!compare_m4m4(sel_id_ctx->persmat, vc->rv3d->persmat, FLT_EPSILON)) { + ed_select_id_draw_bases(sel_id_ctx, vc, sel_id_ctx->select_mode); + } +} + uint ED_view3d_select_id_context_offset_for_object_elem( const struct EDSelectID_Context *sel_id_ctx, int base_index, char elem_type) { @@ -223,7 +234,8 @@ struct EDSelectID_Context *ED_view3d_select_id_context_create(ViewContext *vc, __func__); sel_id_ctx->bases = bases; sel_id_ctx->bases_len = bases_len; - + copy_m4_m4(sel_id_ctx->persmat, vc->rv3d->persmat); + sel_id_ctx->select_mode = select_mode; ed_select_id_draw_bases(sel_id_ctx, vc, select_mode); return sel_id_ctx; @@ -3520,6 +3532,7 @@ static bool mesh_circle_select(ViewContext *vc, struct EditSelectBuf_Cache *esel = wm_userdata->data; if (use_zbuf) { + ED_view3d_select_id_validate_view_matrices(esel->sel_id_ctx, vc); const uint buffer_len = ED_view3d_select_id_context_elem_len(esel->sel_id_ctx); esel->select_bitmap = ED_select_buffer_bitmap_from_circle(buffer_len, mval, (int)(rad + 1.0f)); } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index a9acdcd001c..1ed0d5e9221 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2424,8 +2424,8 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { ParticleSystemModifierData *psmd_eval = edit->psmd_eval; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + i, mat); + psys_mat_hair_to_global( + ob, psmd_eval->mesh_final, psys->part->from, psys->particles + i, mat); } for (k = 0, key = point->keys; k < point->totkey; k++, key++) { @@ -2516,8 +2516,8 @@ void flushTransParticles(TransInfo *t) if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { ParticleSystemModifierData *psmd_eval = edit->psmd_eval; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + i, mat); + psys_mat_hair_to_global( + ob, psmd_eval->mesh_final, psys->part->from, psys->particles + i, mat); invert_m4_m4(imat, mat); for (k = 0, key = point->keys; k < point->totkey; k++, key++) { diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index fa2a7eb9812..b1d22e12b10 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -117,6 +117,7 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2]) immUniformArray4fv( "colors", (float *)(float[][4]){{1.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2); immUniform1f("dash_width", 8.0f); + immUniform1f("dash_factor", 0.5f); immBegin(GPU_PRIM_LINES, 8); @@ -137,6 +138,7 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2]) immUniformArray4fv( "colors", (float *)(float[][4]){{1.0f, 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2); immUniform1f("dash_width", 2.0f); + immUniform1f("dash_factor", 0.5f); immBegin(GPU_PRIM_LINES, 8); @@ -360,6 +362,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit, Depsgraph * edges, "viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC); GPU_batch_uniform_1i(edges, "colors_len", 2); /* "advanced" mode */ GPU_batch_uniform_1f(edges, "dash_width", 4.0f); + GPU_batch_uniform_1f(edges, "dash_factor", 0.5f); GPU_batch_draw(edges); break; } diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index bb73d61a139..14cdb674698 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -1272,10 +1272,11 @@ static void uv_map_rotation_matrix_ex(float result[4][4], } /* but shifting */ - copy_v4_fl(viewmatrix[3], 0.0f); + zero_v3(viewmatrix[3]); /* get rotation of the current object matrix */ copy_m4_m4(rotobj, ob->obmat); + zero_v3(rotobj[3]); /* but shifting */ add_v4_v4(rotobj[3], offset); diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index 3fb7dfc6331..d5e763987cb 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -33,6 +33,8 @@ extern "C" { struct GPUVertBuf; struct Image; struct ImageUser; +struct MovieClip; +struct MovieClipUser; struct PreviewImage; struct rcti; @@ -189,6 +191,12 @@ GPUTexture *GPU_texture_from_bindcode(int textarget, int bindcode); GPUTexture *GPU_texture_from_blender(struct Image *ima, struct ImageUser *iuser, int textarget); GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap); +/* movie clip drawing */ +GPUTexture *GPU_texture_from_movieclip(struct MovieClip *clip, + struct MovieClipUser *cuser, + int textarget); +void GPU_free_texture_movieclip(struct MovieClip *clip); + void GPU_texture_add_mipmap(GPUTexture *tex, eGPUDataFormat gpu_data_format, int miplvl, diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 7813ae68371..f5d599eb647 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -59,6 +59,7 @@ #include "BKE_image.h" #include "BKE_main.h" #include "BKE_material.h" +#include "BKE_movieclip.h" #include "BKE_node.h" #include "BKE_scene.h" @@ -247,7 +248,7 @@ static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget) * this allows us to use sRGB texture formats and preserves color values in * zero alpha areas, and appears generally closer to what game engines that we * want to be compatible with do. */ - const bool store_premultiplied = (ima->alpha_mode == IMA_ALPHA_PREMUL); + const bool store_premultiplied = ima ? (ima->alpha_mode == IMA_ALPHA_PREMUL) : true; IMB_colormanagement_imbuf_to_byte_texture( rect, 0, 0, ibuf->x, ibuf->y, ibuf, compress_as_srgb, store_premultiplied); } @@ -256,14 +257,13 @@ static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget) /* Float image is already in scene linear colorspace or non-color data by * convention, no colorspace conversion needed. But we do require 4 channels * currently. */ - const bool store_premultiplied = (ima->alpha_mode != IMA_ALPHA_STRAIGHT); + const bool store_premultiplied = ima ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) : false; if (ibuf->channels != 4 || !store_premultiplied) { rect_float = MEM_mallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, __func__); if (rect_float == NULL) { return bindcode; } - IMB_colormanagement_imbuf_to_float_texture( rect_float, 0, 0, ibuf->x, ibuf->y, ibuf, store_premultiplied); } @@ -291,6 +291,36 @@ static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget) return bindcode; } +static GPUTexture **gpu_get_movieclip_gputexture(MovieClip *clip, + MovieClipUser *cuser, + GLenum textarget) +{ + MovieClip_RuntimeGPUTexture *tex; + for (tex = clip->runtime.gputextures.first; tex; tex = tex->next) { + if (memcmp(&tex->user, cuser, sizeof(MovieClipUser)) == 0) { + break; + } + } + + if (tex == NULL) { + tex = MEM_mallocN(sizeof(MovieClip_RuntimeGPUTexture), __func__); + + for (int i = 0; i < TEXTARGET_COUNT; i++) { + tex->gputexture[i] = NULL; + } + + memcpy(&tex->user, cuser, sizeof(MovieClipUser)); + BLI_addtail(&clip->runtime.gputextures, tex); + } + + if (textarget == GL_TEXTURE_2D) + return &tex->gputexture[TEXTARGET_TEXTURE_2D]; + else if (textarget == GL_TEXTURE_CUBE_MAP) + return &tex->gputexture[TEXTARGET_TEXTURE_CUBE_MAP]; + + return NULL; +} + static void gpu_texture_update_scaled( uchar *rect, float *rect_float, int full_w, int full_h, int x, int y, int w, int h) { @@ -472,6 +502,52 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int textarget return *tex; } +GPUTexture *GPU_texture_from_movieclip(MovieClip *clip, MovieClipUser *cuser, int textarget) +{ + if (clip == NULL) { + return NULL; + } + + GPUTexture **tex = gpu_get_movieclip_gputexture(clip, cuser, textarget); + if (*tex) { + return *tex; + } + + /* check if we have a valid image buffer */ + uint bindcode = 0; + ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, cuser); + if (ibuf == NULL) { + *tex = GPU_texture_from_bindcode(textarget, bindcode); + return *tex; + } + + bindcode = gpu_texture_create_from_ibuf(NULL, ibuf, textarget); + IMB_freeImBuf(ibuf); + + *tex = GPU_texture_from_bindcode(textarget, bindcode); + return *tex; +} + +void GPU_free_texture_movieclip(struct MovieClip *clip) +{ + /* number of gpu textures to keep around as cache + * We don't want to keep too many GPU textures for + * movie clips around, as they can be large.*/ + const int MOVIECLIP_NUM_GPUTEXTURES = 1; + + while (BLI_listbase_count(&clip->runtime.gputextures) > MOVIECLIP_NUM_GPUTEXTURES) { + MovieClip_RuntimeGPUTexture *tex = BLI_pophead(&clip->runtime.gputextures); + for (int i = 0; i < TEXTARGET_COUNT; i++) { + /* free glsl image binding */ + if (tex->gputexture[i]) { + GPU_texture_free(tex->gputexture[i]); + tex->gputexture[i] = NULL; + } + } + MEM_freeN(tex); + } +} + static void **gpu_gen_cube_map(uint *rect, float *frect, int rectw, int recth) { size_t block_size = frect ? sizeof(float[4]) : sizeof(uchar[4]); diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 0d87ae09943..a81bff60146 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -882,24 +882,17 @@ enum { MOD_MDEF_SURFACE = 1, }; -/* Is stored in ModifierData.runtime. */ -# -# -typedef struct ParticleSystemModifierDataRuntime { +typedef struct ParticleSystemModifierData { + ModifierData modifier; + + struct ParticleSystem *psys; /** Final Mesh - its topology may differ from orig mesh. */ struct Mesh *mesh_final; /** Original mesh that particles are attached to. */ struct Mesh *mesh_original; int totdmvert, totdmedge, totdmface; -} ParticleSystemModifierDataRuntime; - -typedef struct ParticleSystemModifierData { - ModifierData modifier; - - struct ParticleSystem *psys; - void *_pad1; short flag; - char _pad[6]; + char _pad[2]; } ParticleSystemModifierData; typedef enum { diff --git a/source/blender/makesdna/DNA_movieclip_types.h b/source/blender/makesdna/DNA_movieclip_types.h index c804a78eccb..efda24d6e0e 100644 --- a/source/blender/makesdna/DNA_movieclip_types.h +++ b/source/blender/makesdna/DNA_movieclip_types.h @@ -57,6 +57,17 @@ typedef struct MovieClipProxy { short build_tc_flag; } MovieClipProxy; +typedef struct MovieClip_RuntimeGPUTexture { + void *next, *prev; + MovieClipUser user; + /** Not written in file 2 = TEXTARGET_COUNT. */ + struct GPUTexture *gputexture[2]; +} MovieClip_RuntimeGPUTexture; + +typedef struct MovieClip_Runtime { + struct ListBase gputextures; +} MovieClip_Runtime; + typedef struct MovieClip { ID id; /** Animation data (must be immediately after id for utilities to use it). */ @@ -111,6 +122,8 @@ typedef struct MovieClip { /* color management */ ColorManagedColorspaceSettings colorspace_settings; + + struct MovieClip_Runtime runtime; } MovieClip; typedef struct MovieClipScopes { diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c index 7cb1610fd31..bb236fc3ef4 100644 --- a/source/blender/makesrna/intern/rna_camera.c +++ b/source/blender/makesrna/intern/rna_camera.c @@ -231,12 +231,14 @@ static void rna_def_camera_background_image(BlenderRNA *brna) prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "offset"); RNA_def_property_ui_text(prop, "Offset", ""); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 0.1, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "scale"); RNA_def_property_ui_text(prop, "Scale", "Scale the background image"); RNA_def_property_range(prop, 0.0, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0, 10.0, 0.100, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_ANGLE); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 8112231ed16..c1822b35f28 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -173,8 +173,7 @@ static void rna_ParticleHairKey_location_object_info(PointerRNA *ptr, for (md = ob->modifiers.first; md; md = md->next) { if (md->type == eModifierType_ParticleSystem) { psmd = (ParticleSystemModifierData *)md; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - if (psmd && mesh_final && psmd->psys) { + if (psmd && psmd->mesh_final && psmd->psys) { psys = psmd->psys; for (i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) { /* hairkeys are stored sequentially in memory, so we can @@ -209,8 +208,7 @@ static void rna_ParticleHairKey_location_object_get(PointerRNA *ptr, float *valu } else { float hairmat[4][4]; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - psys_mat_hair_to_object(ob, mesh_final, psmd->psys->part->from, pa, hairmat); + psys_mat_hair_to_object(ob, psmd->mesh_final, psmd->psys->part->from, pa, hairmat); copy_v3_v3(values, hkey->co); mul_m4_v3(hairmat, values); } @@ -240,8 +238,7 @@ static void rna_ParticleHairKey_location_object_set(PointerRNA *ptr, const float float hairmat[4][4]; float imat[4][4]; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - psys_mat_hair_to_object(ob, mesh_final, psmd->psys->part->from, pa, hairmat); + psys_mat_hair_to_object(ob, psmd->mesh_final, psmd->psys->part->from, pa, hairmat); invert_m4_m4(imat, hairmat); copy_v3_v3(hkey->co, values); mul_m4_v3(imat, hkey->co); @@ -268,8 +265,8 @@ static void rna_ParticleHairKey_co_object(HairKey *hairkey, } else { float hairmat[4][4]; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); - psys_mat_hair_to_object(object, mesh_final, modifier->psys->part->from, particle, hairmat); + psys_mat_hair_to_object( + object, modifier->mesh_final, modifier->psys->part->from, particle, hairmat); copy_v3_v3(n_co, hairkey->co); mul_m4_v3(hairmat, n_co); } @@ -293,15 +290,14 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, int num = particle->num_dmcache; int from = modifier->psys->part->from; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); - if (!CustomData_has_layer(&mesh_final->ldata, CD_MLOOPUV)) { + if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) { BKE_report(reports, RPT_ERROR, "Mesh has no UV data"); return; } - BKE_mesh_tessface_ensure(mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ + BKE_mesh_tessface_ensure(modifier->mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ if (num == DMCACHE_NOTFOUND) { - if (particle->num < mesh_final->totface) { + if (particle->num < modifier->mesh_final->totface) { num = particle->num; } } @@ -313,8 +309,8 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, MFace *mface; MTFace *mtface; - mface = mesh_final->mface; - mtface = mesh_final->mtface; + mface = modifier->mesh_final->mface; + mtface = modifier->mesh_final->mtface; if (mface && mtface) { mtface += num; @@ -443,10 +439,9 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys int totvert; int num = -1; - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); - BKE_mesh_tessface_ensure(mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ - totface = mesh_final->totface; - totvert = mesh_final->totvert; + BKE_mesh_tessface_ensure(modifier->mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ + totface = modifier->mesh_final->totface; + totvert = modifier->mesh_final->totvert; /* 1. check that everything is ok & updated */ if (!particlesystem || !totface) { @@ -479,7 +474,7 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys } else if (part->from == PART_FROM_VERT) { if (num != DMCACHE_NOTFOUND && num < totvert) { - MFace *mface = mesh_final->mface; + MFace *mface = modifier->mesh_final->mface; *r_fuv = &particle->fuv; @@ -522,7 +517,7 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys } else if (part->from == PART_FROM_VERT) { if (num != DMCACHE_NOTFOUND && num < totvert) { - MFace *mface = mesh_final->mface; + MFace *mface = modifier->mesh_final->mface; *r_fuv = &parent->fuv; @@ -550,13 +545,12 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, int uv_no, float r_uv[2]) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); - if (mesh_final == NULL) { + if (modifier->mesh_final == NULL) { BKE_report(reports, RPT_ERROR, "Object was not yet evaluated"); zero_v2(r_uv); return; } - if (!CustomData_has_layer(&mesh_final->ldata, CD_MLOOPUV)) { + if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) { BKE_report(reports, RPT_ERROR, "Mesh has no UV data"); zero_v2(r_uv); return; @@ -573,8 +567,9 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, zero_v2(r_uv); } else { - MFace *mface = &mesh_final->mface[num]; - MTFace *mtface = (MTFace *)CustomData_get_layer_n(&mesh_final->fdata, CD_MTFACE, uv_no); + MFace *mface = &modifier->mesh_final->mface[num]; + MTFace *mtface = (MTFace *)CustomData_get_layer_n( + &modifier->mesh_final->fdata, CD_MTFACE, uv_no); psys_interpolate_uvs(&mtface[num], mface->v4, *fuv, r_uv); } @@ -589,8 +584,7 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, int vcol_no, float r_mcol[3]) { - Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); - if (!CustomData_has_layer(&mesh_final->ldata, CD_MLOOPCOL)) { + if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPCOL)) { BKE_report(reports, RPT_ERROR, "Mesh has no VCol data"); zero_v3(r_mcol); return; @@ -607,8 +601,8 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, zero_v3(r_mcol); } else { - MFace *mface = &mesh_final->mface[num]; - MCol *mc = (MCol *)CustomData_get_layer_n(&mesh_final->fdata, CD_MCOL, vcol_no); + MFace *mface = &modifier->mesh_final->mface[num]; + MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->mesh_final->fdata, CD_MCOL, vcol_no); MCol mcol; psys_interpolate_mcol(&mc[num * 4], mface->v4, *fuv, &mcol); diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 4e7f9f51d12..8eaccfd1066 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -1606,7 +1606,7 @@ static void rna_def_sequence(BlenderRNA *brna) prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_MUTE); - RNA_def_property_ui_icon(prop, ICON_HIDE_OFF, -1); + RNA_def_property_ui_icon(prop, ICON_CHECKBOX_HLT, -1); RNA_def_property_ui_text( prop, "Mute", "Disable strip so that it cannot be viewed in the output"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_mute_update"); @@ -1957,6 +1957,12 @@ static void rna_def_filter_video(StructRNA *srna) {0, NULL, 0, NULL, NULL}, }; + static const EnumPropertyItem playback_direction_items[] = { + {0, "FORWARD", 0, "Forwards", "Play strip forwards"}, + {SEQ_REVERSE_FRAMES, "BACKWARD", 0, "Backwards", "Play strip backwards"}, + {0, NULL, 0, NULL, NULL}, + }; + prop = RNA_def_property(srna, "use_deinterlace", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_FILTERY); RNA_def_property_ui_text(prop, "Deinterlace", "Remove fields from video movies"); @@ -1983,9 +1989,10 @@ static void rna_def_filter_video(StructRNA *srna) RNA_def_property_ui_text(prop, "Convert Float", "Convert input to float data"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update"); - prop = RNA_def_property(srna, "use_reverse_frames", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_REVERSE_FRAMES); - RNA_def_property_ui_text(prop, "Flip Time", "Reverse frame order"); + prop = RNA_def_property(srna, "playback_direction", PROP_ENUM, PROP_NONE); /* as an enum */ + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, playback_direction_items); + RNA_def_property_ui_text(prop, "Playback Direction", "Play strip forwards or backwards"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update"); prop = RNA_def_property(srna, "color_multiply", PROP_FLOAT, PROP_UNSIGNED); @@ -2201,6 +2208,16 @@ static void rna_def_scene(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + static const EnumPropertyItem scene_input_items[] = { + {0, "3D_CAMERA", ICON_VIEW3D, "3D Camera", "Use the Scene's 3D camera as input"}, + {SEQ_SCENE_STRIPS, + "SEQUENCE", + ICON_SEQUENCE, + "Sequence", + "Use the Scene's Sequencer timeline as input"}, + {0, NULL, 0, NULL, NULL}, + }; + srna = RNA_def_struct(brna, "SceneSequence", "Sequence"); RNA_def_struct_ui_text( srna, "Scene Sequence", "Sequence strip to used the rendered image of a scene"); @@ -2217,10 +2234,10 @@ static void rna_def_scene(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Camera Override", "Override the scenes active camera"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update"); - prop = RNA_def_property(srna, "use_sequence", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_SCENE_STRIPS); - RNA_def_property_ui_text( - prop, "Use Sequence", "Use scenes sequence strips directly, instead of rendering"); + prop = RNA_def_property(srna, "scene_input", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, scene_input_items); + RNA_def_property_ui_text(prop, "Input", "Input type to use for the Scene strip"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_use_sequence"); prop = RNA_def_property(srna, "use_grease_pencil", PROP_BOOLEAN, PROP_NONE); @@ -2401,7 +2418,8 @@ static void rna_def_sound(BlenderRNA *brna) prop = RNA_def_property(srna, "show_waveform", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_AUDIO_DRAW_WAVEFORM); - RNA_def_property_ui_text(prop, "Display Waveform", "Display the audio waveform inside the clip"); + RNA_def_property_ui_text( + prop, "Display Waveform", "Display the audio waveform inside the strip"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL); rna_def_input(srna); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 561cbb2ec3a..2b51b1eee97 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -985,7 +985,7 @@ static int rna_3DViewShading_type_get(PointerRNA *ptr) return shading->type; } else if (BKE_scene_uses_blender_workbench(scene)) { - return (shading->type == OB_MATERIAL) ? OB_RENDER : shading->type; + return (shading->type == OB_MATERIAL) ? OB_SOLID : shading->type; } else { if (shading->type == OB_RENDER && !(type && type->view_draw)) { @@ -5489,6 +5489,8 @@ static void rna_def_space_filebrowser(BlenderRNA *brna) RNA_def_struct_sdna(srna, "SpaceFile"); RNA_def_struct_ui_text(srna, "Space File Browser", "File browser space data"); + rna_def_space_generic_show_region_toggles(srna, (1 << RGN_TYPE_TOOLS) | (1 << RGN_TYPE_UI)); + prop = RNA_def_property(srna, "params", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "params"); RNA_def_property_ui_text( diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 9b1586f4982..4ed787810a8 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -1125,7 +1125,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes if (psys->part == NULL || psys->particles == NULL) { return mesh; } - if (BKE_particle_modifier_mesh_final_get(psmd) == NULL) { + if (psmd->mesh_final == NULL) { return mesh; } diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index c61ebe0448c..c64d9be1158 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -185,7 +185,10 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes * accessible via MVert. For this reason we do not evaluate multires to * grids when orco is requested. */ const bool for_orco = (ctx->flag & MOD_APPLY_ORCO) != 0; - if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco) { + /* Needed when rendering or baking will in sculpt mode. */ + const bool for_render = (ctx->flag & MOD_APPLY_RENDER) != 0; + + if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco && !for_render) { /* NOTE: CCG takes ownership over Subdiv. */ result = multires_as_ccg(mmd, ctx, mesh, subdiv); result->runtime.subdiv_ccg_tot_level = mmd->totlvl; diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index 651feb836cc..71913378277 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -415,11 +415,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes ChildParticle *cpa = psys->child + (p - psys->totpart); pa = psys->particles + (between ? cpa->pa[0] : cpa->parent); } - psys_mat_hair_to_global(sim.ob, - BKE_particle_modifier_mesh_final_get(sim.psmd), - sim.psys->part->from, - pa, - hairmat); + psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, sim.psys->part->from, pa, hairmat); copy_m3_m4(mat, hairmat); /* to quaternion */ mat3_to_quat(frame, mat); diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index 02d477b1bde..5d7b380a751 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -23,8 +23,6 @@ #include <stddef.h> -#include "MEM_guardedalloc.h" - #include "BLI_utildefines.h" #include "DNA_material_types.h" @@ -44,27 +42,24 @@ static void initData(ModifierData *md) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; psmd->psys = NULL; + psmd->mesh_final = NULL; + psmd->mesh_original = NULL; + psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0; } - -static void freeRuntimeData(void *runtime_data_v) -{ - if (runtime_data_v == NULL) { - return; - } - ParticleSystemModifierDataRuntime *runtime_data = runtime_data_v; - if (runtime_data->mesh_final) { - BKE_id_free(NULL, runtime_data->mesh_final); - } - if (runtime_data->mesh_original) { - BKE_id_free(NULL, runtime_data->mesh_original); - } - MEM_freeN(runtime_data); -} - static void freeData(ModifierData *md) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; - freeRuntimeData(md->runtime); + + if (psmd->mesh_final) { + BKE_id_free(NULL, psmd->mesh_final); + psmd->mesh_final = NULL; + if (psmd->mesh_original) { + BKE_id_free(NULL, psmd->mesh_original); + psmd->mesh_original = NULL; + } + } + psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0; + /* ED_object_modifier_remove may have freed this first before calling * modifier_free (which calls this function) */ if (psmd->psys) { @@ -72,6 +67,20 @@ static void freeData(ModifierData *md) } } +static void copyData(const ModifierData *md, ModifierData *target, const int flag) +{ +#if 0 + const ParticleSystemModifierData *psmd = (const ParticleSystemModifierData *)md; +#endif + ParticleSystemModifierData *tpsmd = (ParticleSystemModifierData *)target; + + modifier_copyData_generic(md, target, flag); + + tpsmd->mesh_final = NULL; + tpsmd->mesh_original = NULL; + tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0; +} + static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks) @@ -111,16 +120,14 @@ static void deformVerts(ModifierData *md, } } - ParticleSystemModifierDataRuntime *runtime = BKE_particle_modifier_runtime_ensure(psmd); - /* clear old dm */ - bool had_mesh_final = (runtime->mesh_final != NULL); - if (runtime->mesh_final) { - BKE_id_free(NULL, runtime->mesh_final); - runtime->mesh_final = NULL; - if (runtime->mesh_original) { - BKE_id_free(NULL, runtime->mesh_original); - runtime->mesh_original = NULL; + bool had_mesh_final = (psmd->mesh_final != NULL); + if (psmd->mesh_final) { + BKE_id_free(NULL, psmd->mesh_final); + psmd->mesh_final = NULL; + if (psmd->mesh_original) { + BKE_id_free(NULL, psmd->mesh_original); + psmd->mesh_original = NULL; } } else if (psmd->flag & eParticleSystemFlag_file_loaded) { @@ -136,13 +143,13 @@ static void deformVerts(ModifierData *md, } /* make new mesh */ - runtime->mesh_final = BKE_mesh_copy_for_eval(mesh_src, false); - BKE_mesh_apply_vert_coords(runtime->mesh_final, vertexCos); - BKE_mesh_calc_normals(runtime->mesh_final); + psmd->mesh_final = BKE_mesh_copy_for_eval(mesh_src, false); + BKE_mesh_apply_vert_coords(psmd->mesh_final, vertexCos); + BKE_mesh_calc_normals(psmd->mesh_final); - BKE_mesh_tessface_ensure(runtime->mesh_final); + BKE_mesh_tessface_ensure(psmd->mesh_final); - if (!runtime->mesh_final->runtime.deformed_only) { + if (!psmd->mesh_final->runtime.deformed_only) { /* Get the original mesh from the object, this is what the particles * are attached to so in case of non-deform modifiers we need to remap * them to the final mesh (typically subdivision surfaces). */ @@ -153,7 +160,7 @@ static void deformVerts(ModifierData *md, if (em) { /* In edit mode get directly from the edit mesh. */ - runtime->mesh_original = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL); + psmd->mesh_original = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL); } else { /* Otherwise get regular mesh. */ @@ -168,13 +175,13 @@ static void deformVerts(ModifierData *md, /* Make a persistent copy of the mesh. We don't actually need * all this data, just some topology for remapping. Could be * optimized once. */ - runtime->mesh_original = BKE_mesh_copy_for_eval(mesh_original, false); + psmd->mesh_original = BKE_mesh_copy_for_eval(mesh_original, false); } - BKE_mesh_tessface_ensure(runtime->mesh_original); + BKE_mesh_tessface_ensure(psmd->mesh_original); } - if (mesh_src != runtime->mesh_final && mesh_src != mesh) { + if (mesh_src != psmd->mesh_final && mesh_src != mesh) { BKE_id_free(NULL, mesh_src); } @@ -182,13 +189,13 @@ static void deformVerts(ModifierData *md, * This is an unreliable check for the topology check, but allows some * handy configuration like emitting particles from inside particle * instance. */ - if (had_mesh_final && (runtime->mesh_final->totvert != runtime->totdmvert || - runtime->mesh_final->totedge != runtime->totdmedge || - runtime->mesh_final->totface != runtime->totdmface)) { + if (had_mesh_final && (psmd->mesh_final->totvert != psmd->totdmvert || + psmd->mesh_final->totedge != psmd->totdmedge || + psmd->mesh_final->totface != psmd->totdmface)) { psys->recalc |= ID_RECALC_PSYS_RESET; - runtime->totdmvert = runtime->mesh_final->totvert; - runtime->totdmedge = runtime->mesh_final->totedge; - runtime->totdmface = runtime->mesh_final->totface; + psmd->totdmvert = psmd->mesh_final->totvert; + psmd->totdmedge = psmd->mesh_final->totedge; + psmd->totdmface = psmd->mesh_final->totface; } if (!(ctx->object->transflag & OB_NO_PSYS_UPDATE)) { @@ -238,11 +245,12 @@ ModifierTypeInfo modifierType_ParticleSystem = { /* structSize */ sizeof(ParticleSystemModifierData), /* type */ eModifierTypeType_OnlyDeform, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | - eModifierTypeFlag_UsesPointCache, /* | + eModifierTypeFlag_UsesPointCache /* | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode */ + , - /* copyData */ modifier_copyData_generic, + /* copyData */ copyData, /* deformVerts */ deformVerts, /* deformMatrices */ NULL, @@ -260,5 +268,5 @@ ModifierTypeInfo modifierType_ParticleSystem = { /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, /* foreachTexLink */ NULL, - /* freeRuntimeData */ freeRuntimeData, + /* freeRuntimeData */ NULL, }; diff --git a/source/blender/python/generic/blf_py_api.c b/source/blender/python/generic/blf_py_api.c index a2c7c9099c1..b90483e89b9 100644 --- a/source/blender/python/generic/blf_py_api.c +++ b/source/blender/python/generic/blf_py_api.c @@ -468,7 +468,7 @@ static PyMethodDef BLF_methods[] = { {NULL, NULL, 0, NULL}, }; -PyDoc_STRVAR(BLF_doc, "This module provides access to blenders text drawing functions."); +PyDoc_STRVAR(BLF_doc, "This module provides access to Blender's text drawing functions."); static struct PyModuleDef BLF_module_def = { PyModuleDef_HEAD_INIT, "blf", /* m_name */ diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index a3dd8ef93f2..cbd57b28242 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -86,7 +86,7 @@ static PyStructSequence_Field app_info_fields[] = { {(char *)"version_char", (char *)"The Blender version character (for minor releases)"}, {(char *)"version_cycle", (char *)"The release status of this build alpha/beta/rc/release"}, {(char *)"binary_path", - (char *)"The location of blenders executable, useful for utilities that spawn new instances"}, + (char *)"The location of Blender's executable, useful for utilities that open new instances"}, {(char *)"background", (char *)"Boolean, True when blender is running without a user interface (started with -b)"}, {(char *)"factory_startup", diff --git a/source/blender/python/intern/bpy_interface_atexit.c b/source/blender/python/intern/bpy_interface_atexit.c index cb79a1f7f93..1c48dc1baae 100644 --- a/source/blender/python/intern/bpy_interface_atexit.c +++ b/source/blender/python/intern/bpy_interface_atexit.c @@ -17,7 +17,7 @@ /** \file * \ingroup pythonintern * - * This file inserts an exit callback into pythons 'atexit' module. + * This file inserts an exit callback into Python's 'atexit' module. * Without this sys.exit() can crash because blender is not properly closing * resources. */ diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c index 3de8e49dffd..5ea16c8c197 100644 --- a/source/blender/python/intern/bpy_library_load.c +++ b/source/blender/python/intern/bpy_library_load.c @@ -19,9 +19,9 @@ * * This file exposed blend file library appending/linking to python, typically * this would be done via RNA api but in this case a hand written python api - * allows us to use pythons context manager (__enter__ and __exit__). + * allows us to use Python's context manager (`__enter__` and `__exit__`). * - * Everything here is exposed via bpy.data.libraries.load(...) which returns + * Everything here is exposed via `bpy.data.libraries.load(...)` which returns * a context manager. */ diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 074d72f094f..ad7d5137ebc 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -2986,8 +2986,8 @@ PyDoc_STRVAR( " .. warning::\n" "\n" " There is a known bug with using a callback,\n" - " Python must keep a reference to the strings returned or Blender will misbehave\n" - " or even crash." + " Python must keep a reference to the strings returned by the callback or Blender\n" + " will misbehave or even crash." "\n" " :type items: sequence of string tuples or a function\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 8385bff0256..734e929fdf4 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -17,11 +17,11 @@ /** \file * \ingroup pythonintern * - * This file is the main interface between python and blenders data api (RNA), - * exposing RNA to python so blender data can be accessed in a python like way. + * This file is the main interface between Python and Blender's data api (RNA), + * exposing RNA to Python so blender data can be accessed in a Python like way. * - * The two main types are 'BPy_StructRNA' and 'BPy_PropertyRNA' - the base - * classes for most of the data python accesses in blender. + * The two main types are #BPy_StructRNA and #BPy_PropertyRNA - the base + * classes for most of the data Python accesses in blender. */ #include <Python.h> @@ -67,10 +67,10 @@ #include "BKE_report.h" #include "BKE_idprop.h" -/* only for types */ +/* Only for types. */ #include "BKE_node.h" -#include "../generic/idprop_py_api.h" /* for IDprop lookups */ +#include "../generic/idprop_py_api.h" /* For IDprop lookups. */ #include "../generic/py_capi_utils.h" #include "../generic/python_utildefines.h" @@ -86,7 +86,7 @@ static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self); #define BPY_DOC_ID_PROP_TYPE_NOTE \ " .. note::\n" \ "\n" \ - " Only :class:`bpy.types.ID`, :class:`bpy.types.Bone` and\n" \ + " Only the :class:`bpy.types.ID`, :class:`bpy.types.Bone` and\n" \ " :class:`bpy.types.PoseBone` classes support custom properties.\n" int pyrna_struct_validity_check(BPy_StructRNA *pysrna) @@ -119,7 +119,7 @@ void pyrna_invalidate(BPy_DummyPointerRNA *self) #ifdef USE_PYRNA_INVALIDATE_GC # define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g) + 1)) -/* only for sizeof() */ +/* Only for sizeof(). */ struct gc_generation { PyGC_Head head; int threshold; @@ -131,7 +131,7 @@ static void id_release_gc(struct ID *id) unsigned int j; // unsigned int i = 0; for (j = 0; j < 3; j++) { - /* hack below to get the 2 other lists from _PyGC_generation0 that are normally not exposed */ + /* Hack below to get the 2 other lists from _PyGC_generation0 that are normally not exposed. */ PyGC_Head *gen = (PyGC_Head *)(((char *)_PyGC_generation0) + (sizeof(gc_generation) * j)); PyGC_Head *g = gen->gc.gc_next; while ((g = g->gc.gc_next) != gen) { @@ -159,7 +159,7 @@ static PyObject *id_free_weakref_cb(PyObject *weakinfo_pair, PyObject *weakref); static PyMethodDef id_free_weakref_cb_def = { "id_free_weakref_cb", (PyCFunction)id_free_weakref_cb, METH_O, NULL}; -/* adds a reference to the list, remember to decref */ +/* Adds a reference to the list, remember to decref. */ static GHash *id_weakref_pool_get(ID *id) { GHash *weakinfo_hash = NULL; @@ -168,13 +168,13 @@ static GHash *id_weakref_pool_get(ID *id) weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id); } else { - /* first time, allocate pool */ + /* First time, allocate pool. */ id_weakref_pool = BLI_ghash_ptr_new("rna_global_pool"); weakinfo_hash = NULL; } if (weakinfo_hash == NULL) { - /* we're using a ghash as a set, could use libHX's HXMAP_SINGULAR but would be an extra dep. */ + /* We use a ghash as a set, we could use libHX's HXMAP_SINGULAR, but would be an extra dep. */ weakinfo_hash = BLI_ghash_ptr_new("rna_id"); BLI_ghash_insert(id_weakref_pool, id, weakinfo_hash); } @@ -182,7 +182,7 @@ static GHash *id_weakref_pool_get(ID *id) return weakinfo_hash; } -/* called from pyrna_struct_CreatePyObject() and pyrna_prop_CreatePyObject() */ +/* Called from pyrna_struct_CreatePyObject() and pyrna_prop_CreatePyObject(). */ static void id_weakref_pool_add(ID *id, BPy_DummyPointerRNA *pyrna) { PyObject *weakref; @@ -191,24 +191,25 @@ static void id_weakref_pool_add(ID *id, BPy_DummyPointerRNA *pyrna) /* Create a new function instance and insert the list as 'self' * so we can remove ourself from it. */ - GHash *weakinfo_hash = id_weakref_pool_get(id); /* new or existing */ + GHash *weakinfo_hash = id_weakref_pool_get(id); /* New or existing. */ weakref_capsule = PyCapsule_New(weakinfo_hash, NULL, NULL); weakref_cb_py = PyCFunction_New(&id_free_weakref_cb_def, weakref_capsule); Py_DECREF(weakref_capsule); - /* add weakref to weakinfo_hash list */ + /* Add weakref to weakinfo_hash list. */ weakref = PyWeakref_NewRef((PyObject *)pyrna, weakref_cb_py); - Py_DECREF(weakref_cb_py); /* function owned by the weakref now */ + Py_DECREF(weakref_cb_py); /* Function owned by the weakref now. */ - /* important to add at the end, since first removal looks at the end */ - BLI_ghash_insert( - weakinfo_hash, weakref, id); /* using a hash table as a set, all 'id's are the same */ + /* Important to add at the end of the hash, since first removal looks at the end. */ + + /* Using a hash table as a set, all 'id's are the same. */ + BLI_ghash_insert(weakinfo_hash, weakref, id); /* weakinfo_hash owns the weakref */ } -/* workaround to get the last id without a lookup */ +/* Workaround to get the last id without a lookup. */ static ID *_id_tmp_ptr; static void value_id_set(void *id) { @@ -218,13 +219,13 @@ static void value_id_set(void *id) static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash); static PyObject *id_free_weakref_cb(PyObject *weakinfo_capsule, PyObject *weakref) { - /* important to search backwards */ + /* Important to search backwards. */ GHash *weakinfo_hash = PyCapsule_GetPointer(weakinfo_capsule, NULL); if (BLI_ghash_len(weakinfo_hash) > 1) { BLI_ghash_remove(weakinfo_hash, weakref, NULL, NULL); } - else { /* get the last id and free it */ + else { /* Get the last id and free it. */ BLI_ghash_remove(weakinfo_hash, weakref, NULL, value_id_set); id_release_weakref_list(_id_tmp_ptr, weakinfo_hash); } @@ -310,7 +311,8 @@ static bool rna_id_write_error(PointerRNA *ptr, PyObject *key) ID *id = ptr->id.data; if (id) { const short idcode = GS(id->name); - if (!ELEM(idcode, ID_WM, ID_SCR, ID_WS)) { /* may need more added here */ + /* May need more ID types added here. */ + if (!ELEM(idcode, ID_WM, ID_SCR, ID_WS)) { const char *idtype = BKE_idcode_to_name(idcode); const char *pyname; if (key && PyUnicode_Check(key)) { @@ -320,7 +322,7 @@ static bool rna_id_write_error(PointerRNA *ptr, PyObject *key) pyname = "<UNKNOWN>"; } - /* make a nice string error */ + /* Make a nice string error. */ BLI_assert(idtype != NULL); PyErr_Format(PyExc_AttributeError, "Writing to ID classes in this context is not allowed: " @@ -354,7 +356,7 @@ bool pyrna_write_check(void) } void pyrna_write_set(bool UNUSED(val)) { - /* nothing */ + /* pass */ } #endif /* USE_PEDANTIC_WRITE */ @@ -365,7 +367,7 @@ static int pyrna_py_to_prop( static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item); #ifdef USE_MATHUTILS -# include "../mathutils/mathutils.h" /* so we can have mathutils callbacks */ +# include "../mathutils/mathutils.h" /* So we can have mathutils callbacks. */ static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, @@ -377,10 +379,10 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr, const short order_fallback, PropertyRNA **r_prop_eul_order); -/* bpyrna vector/euler/quat callbacks */ -static unsigned char mathutils_rna_array_cb_index = -1; /* index for our callbacks */ +/* bpyrna vector/euler/quat callbacks. */ +static unsigned char mathutils_rna_array_cb_index = -1; /* Index for our callbacks. */ -/* subtype not used much yet */ +/* Subtype not used much yet. */ # define MATHUTILS_CB_SUBTYPE_EUL 0 # define MATHUTILS_CB_SUBTYPE_VEC 1 # define MATHUTILS_CB_SUBTYPE_QUAT 2 @@ -407,7 +409,7 @@ static int mathutils_rna_vector_get(BaseMathObject *bmo, int subtype) RNA_property_float_get_array(&self->ptr, self->prop, bmo->data); - /* Euler order exception */ + /* Euler order exception. */ if (subtype == MATHUTILS_CB_SUBTYPE_EUL) { EulerObject *eul = (EulerObject *)bmo; PropertyRNA *prop_eul_order = NULL; @@ -456,7 +458,7 @@ static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype) RNA_property_update(BPy_GetContext(), &self->ptr, self->prop); } - /* Euler order exception */ + /* Euler order exception. */ if (subtype == MATHUTILS_CB_SUBTYPE_EUL) { EulerObject *eul = (EulerObject *)bmo; PropertyRNA *prop_eul_order = NULL; @@ -528,7 +530,7 @@ static Mathutils_Callback mathutils_rna_array_cb = { }; /* bpyrna matrix callbacks */ -static unsigned char mathutils_rna_matrix_cb_index = -1; /* index for our callbacks */ +static unsigned char mathutils_rna_matrix_cb_index = -1; /* Index for our callbacks. */ static int mathutils_rna_matrix_get(BaseMathObject *bmo, int UNUSED(subtype)) { @@ -568,7 +570,7 @@ static int mathutils_rna_matrix_set(BaseMathObject *bmo, int UNUSED(subtype)) return -1; } - /* can ignore clamping here */ + /* Can ignore clamping here. */ RNA_property_float_set_array(&self->ptr, self->prop, bmo->data); if (RNA_property_update_check(self->prop)) { @@ -589,14 +591,14 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr, const short order_fallback, PropertyRNA **r_prop_eul_order) { - /* attempt to get order */ + /* Attempt to get order. */ if (*r_prop_eul_order == NULL) { *r_prop_eul_order = RNA_struct_find_property(ptr, "rotation_mode"); } if (*r_prop_eul_order) { short order = RNA_property_enum_get(ptr, *r_prop_eul_order); - /* could be quat or axisangle */ + /* Could be quat or axisangle. */ if (order >= EULER_ORDER_XYZ && order <= EULER_ORDER_ZYX) { return order; } @@ -607,8 +609,10 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr, #endif /* USE_MATHUTILS */ -/* note that PROP_NONE is included as a vector subtype. this is because its handy to - * have x/y access to fcurve keyframes and other fixed size float arrays of length 2-4. */ +/** + * Note that #PROP_NONE is included as a vector subtype. this is because it is handy to + * have x/y access to fcurve keyframes and other fixed size float arrays of length 2-4. + */ #define PROP_ALL_VECTOR_SUBTYPES \ PROP_COORDS: \ case PROP_TRANSLATION: \ @@ -656,7 +660,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) if (totdim == 1 || (totdim == 2 && subtype == PROP_MATRIX)) { if (!is_thick) { - /* owned by the mathutils PyObject */ + /* Owned by the mathutils PyObject. */ ret = pyrna_prop_CreatePyObject(ptr, prop); } @@ -670,8 +674,8 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) else { PyObject *vec_cb = Vector_CreatePyObject_cb( ret, len, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_VEC); - Py_DECREF(ret); /* the vector owns now */ - ret = vec_cb; /* return the vector instead */ + Py_DECREF(ret); /* The vector owns 'ret' now. */ + ret = vec_cb; /* Return the vector instead. */ } } break; @@ -684,8 +688,8 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) else { PyObject *mat_cb = Matrix_CreatePyObject_cb( ret, 4, 4, mathutils_rna_matrix_cb_index, 0); - Py_DECREF(ret); /* the matrix owns now */ - ret = mat_cb; /* return the matrix instead */ + Py_DECREF(ret); /* The matrix owns 'ret' now. */ + ret = mat_cb; /* Return the matrix instead. */ } } else if (len == 9) { @@ -696,30 +700,30 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) else { PyObject *mat_cb = Matrix_CreatePyObject_cb( ret, 3, 3, mathutils_rna_matrix_cb_index, 0); - Py_DECREF(ret); /* the matrix owns now */ - ret = mat_cb; /* return the matrix instead */ + Py_DECREF(ret); /* The matrix owns 'ret' now. */ + ret = mat_cb; /* Return the matrix instead. */ } } break; case PROP_EULER: case PROP_QUATERNION: - if (len == 3) { /* euler */ + if (len == 3) { /* Euler. */ if (is_thick) { /* Attempt to get order, * only needed for thick types since wrapped with update via callbacks. */ PropertyRNA *prop_eul_order = NULL; short order = pyrna_rotation_euler_order_get(ptr, EULER_ORDER_XYZ, &prop_eul_order); - ret = Euler_CreatePyObject(NULL, order, NULL); /* TODO, get order from RNA */ + ret = Euler_CreatePyObject(NULL, order, NULL); /* TODO, get order from RNA. */ RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul); } else { - /* order will be updated from callback on use */ + /* Order will be updated from callback on use. */ // TODO, get order from RNA PyObject *eul_cb = Euler_CreatePyObject_cb( ret, EULER_ORDER_XYZ, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_EUL); - Py_DECREF(ret); /* the euler owns now */ - ret = eul_cb; /* return the euler instead */ + Py_DECREF(ret); /* The euler owns 'ret' now. */ + ret = eul_cb; /* Return the euler instead. */ } } else if (len == 4) { @@ -730,14 +734,14 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) else { PyObject *quat_cb = Quaternion_CreatePyObject_cb( ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_QUAT); - Py_DECREF(ret); /* the quat owns now */ - ret = quat_cb; /* return the quat instead */ + Py_DECREF(ret); /* The quat owns 'ret' now. */ + ret = quat_cb; /* Return the quat instead. */ } } break; case PROP_COLOR: case PROP_COLOR_GAMMA: - if (len == 3) { /* color */ + if (len == 3) { /* Color. */ if (is_thick) { ret = Color_CreatePyObject(NULL, NULL); RNA_property_float_get_array(ptr, prop, ((ColorObject *)ret)->col); @@ -745,8 +749,8 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) else { PyObject *col_cb = Color_CreatePyObject_cb( ret, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_COLOR); - Py_DECREF(ret); /* the color owns now */ - ret = col_cb; /* return the color instead */ + Py_DECREF(ret); /* The color owns 'ret' now. */ + ret = col_cb; /* Return the color instead. */ } } break; @@ -757,13 +761,13 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) if (ret == NULL) { if (is_thick) { - /* this is an array we cant reference (since its not thin wrappable) - * and cannot be coerced into a mathutils type, so return as a list */ + /* This is an array we can't reference (since it is not thin wrappable) + * and cannot be coerced into a mathutils type, so return as a list. */ thick_wrap_slice: ret = pyrna_prop_array_subscript_slice(NULL, ptr, prop, 0, len, len); } else { - ret = pyrna_prop_CreatePyObject(ptr, prop); /* owned by the mathutils PyObject */ + ret = pyrna_prop_CreatePyObject(ptr, prop); /* Owned by the mathutils PyObject. */ } } #else /* USE_MATHUTILS */ @@ -774,7 +778,9 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) return ret; } -/* same as RNA_enum_value_from_id but raises an exception */ +/** + * Same as #RNA_enum_value_from_id, but raises an exception. + */ int pyrna_enum_value_from_id(const EnumPropertyItem *item, const char *identifier, int *r_value, @@ -817,7 +823,7 @@ static int pyrna_prop_compare(BPy_PropertyRNA *a, BPy_PropertyRNA *b) static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op) { PyObject *res; - int ok = -1; /* zero is true */ + int ok = -1; /* Zero is true. */ if (BPy_StructRNA_Check(a) && BPy_StructRNA_Check(b)) { ok = pyrna_struct_compare((BPy_StructRNA *)a, (BPy_StructRNA *)b); @@ -848,7 +854,7 @@ static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op) static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op) { PyObject *res; - int ok = -1; /* zero is true */ + int ok = -1; /* Zero is true. */ if (BPy_PropertyRNA_Check(a) && BPy_PropertyRNA_Check(b)) { ok = pyrna_prop_compare((BPy_PropertyRNA *)a, (BPy_PropertyRNA *)b); @@ -886,7 +892,7 @@ static PyObject *pyrna_struct_str(BPy_StructRNA *self) return PyUnicode_FromFormat("<bpy_struct, %.200s invalid>", Py_TYPE(self)->tp_name); } - /* print name if available */ + /* Print name if available. */ name = RNA_struct_name_get_alloc(&self->ptr, NULL, 0, NULL); if (name) { ret = PyUnicode_FromFormat( @@ -920,7 +926,7 @@ static PyObject *pyrna_struct_repr(BPy_StructRNA *self) const char *path; path = RNA_path_from_ID_to_struct(&self->ptr); if (path) { - if (GS(id->name) == ID_NT) { /* nodetree paths are not accurate */ + if (GS(id->name) == ID_NT) { /* Nodetree paths are not accurate. */ ret = PyUnicode_FromFormat("bpy.data...%s", path); } else { @@ -930,7 +936,8 @@ static PyObject *pyrna_struct_repr(BPy_StructRNA *self) MEM_freeN((void *)path); } - else { /* cant find, print something sane */ + else { + /* Can't find the path, print something useful as a fallback. */ ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s", BKE_idcode_to_name_plural(GS(id->name)), tmp_str, @@ -957,12 +964,12 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) type = RNA_property_type(self->prop); if (RNA_enum_id_from_value(rna_enum_property_type_items, type, &type_id) == 0) { - PyErr_SetString(PyExc_RuntimeError, - "could not use property type, internal error"); /* should never happen */ + /* Should never happen. */ + PyErr_SetString(PyExc_RuntimeError, "could not use property type, internal error"); return NULL; } else { - /* this should never fail */ + /* This should never fail. */ int len = -1; char *c = type_fmt; @@ -981,7 +988,7 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) } } - /* if a pointer, try to print name of pointer target too */ + /* If a pointer, try to print name of pointer target too. */ if (type == PROP_POINTER) { ptr = RNA_property_pointer_get(&self->ptr, self->prop); name = RNA_struct_name_get_alloc(&ptr, NULL, 0, NULL); @@ -1020,7 +1027,7 @@ static PyObject *pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim, PYRNA_PROP_CHECK_OBJ(self); if (id == NULL) { - /* fallback */ + /* Fallback. */ return pyrna_prop_str(self); } @@ -1030,7 +1037,7 @@ static PyObject *pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim, if (path) { const char *data_delim = (path[0] == '[') ? "" : "."; - if (GS(id->name) == ID_NT) { /* nodetree paths are not accurate */ + if (GS(id->name) == ID_NT) { /* Nodetree paths are not accurate. */ ret = PyUnicode_FromFormat("bpy.data...%s", path); } else { @@ -1043,7 +1050,8 @@ static PyObject *pyrna_prop_repr_ex(BPy_PropertyRNA *self, const int index_dim, MEM_freeN((void *)path); } - else { /* cant find, print something sane */ + else { + /* Can't find the path, print something useful as a fallback. */ ret = PyUnicode_FromFormat("bpy.data.%s[%R]...%s", BKE_idcode_to_name_plural(GS(id->name)), tmp_str, @@ -1078,7 +1086,7 @@ static Py_hash_t pyrna_struct_hash(BPy_StructRNA *self) return _Py_HashPointer(self->ptr.data); } -/* from python's meth_hash v3.1.2 */ +/* From Python's meth_hash v3.1.2. */ static long pyrna_prop_hash(BPy_PropertyRNA *self) { long x, y; @@ -1116,7 +1124,7 @@ static int pyrna_struct_clear(BPy_StructRNA *self) } #endif /* !USE_PYRNA_STRUCT_REFERENCE */ -/* use our own dealloc so we can free a property if we use one */ +/* Use our own dealloc so we can free a property if we use one. */ static void pyrna_struct_dealloc(BPy_StructRNA *self) { #ifdef PYRNA_FREE_SUPPORT @@ -1139,7 +1147,7 @@ static void pyrna_struct_dealloc(BPy_StructRNA *self) } #endif /* !USE_PYRNA_STRUCT_REFERENCE */ - /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */ + /* Note, for subclassed PyObjects calling PyObject_DEL() directly crashes. */ Py_TYPE(self)->tp_free(self); } @@ -1150,7 +1158,7 @@ static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference) // PyObject_GC_UnTrack(self); /* INITIALIZED TRACKED ? */ pyrna_struct_clear(self); } - /* reference is now NULL */ + /* Reference is now NULL. */ if (reference) { self->reference = reference; @@ -1160,7 +1168,7 @@ static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference) } #endif /* !USE_PYRNA_STRUCT_REFERENCE */ -/* use our own dealloc so we can free a property if we use one */ +/* Use our own dealloc so we can free a property if we use one. */ static void pyrna_prop_dealloc(BPy_PropertyRNA *self) { #ifdef USE_WEAKREFS @@ -1168,7 +1176,7 @@ static void pyrna_prop_dealloc(BPy_PropertyRNA *self) PyObject_ClearWeakRefs((PyObject *)self); } #endif - /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */ + /* Note, for subclassed PyObjects calling PyObject_DEL() directly crashes. */ Py_TYPE(self)->tp_free(self); } @@ -1179,7 +1187,7 @@ static void pyrna_prop_array_dealloc(BPy_PropertyRNA *self) PyObject_ClearWeakRefs((PyObject *)self); } #endif - /* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */ + /* Note, for subclassed PyObjects calling PyObject_DEL() directly crashes. */ Py_TYPE(self)->tp_free(self); } @@ -1247,7 +1255,7 @@ BLI_bitmap *pyrna_set_to_enum_bitmap(const EnumPropertyItem *items, int bitmap_size, const char *error_prefix) { - /* set looping */ + /* Set looping. */ Py_ssize_t pos = 0; Py_ssize_t hash = 0; PyObject *key; @@ -1303,16 +1311,16 @@ error: return NULL; } -/* 'value' _must_ be a set type, error check before calling */ +/* 'value' _must_ be a set type, error check before calling. */ int pyrna_set_to_enum_bitfield(const EnumPropertyItem *items, PyObject *value, int *r_value, const char *error_prefix) { - /* set of enum items, concatenate all values with OR */ + /* Set of enum items, concatenate all values with OR. */ int ret, flag = 0; - /* set looping */ + /* Set looping. */ Py_ssize_t pos = 0; Py_ssize_t hash = 0; PyObject *key; @@ -1439,7 +1447,7 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val) if (enum_item != DummyRNA_NULL_items) { const char *ptr_name = RNA_struct_name_get_alloc(ptr, NULL, 0, NULL); - /* prefer not fail silently in case of api errors, maybe disable it later */ + /* Prefer not to fail silently in case of API errors, maybe disable it later. */ CLOG_WARN(BPY_LOG_RNA, "current value '%d' " "matches no enum in '%s', '%s', '%s'", @@ -1448,7 +1456,7 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val) ptr_name, RNA_property_identifier(prop)); -#if 0 /* gives python decoding errors while generating docs :( */ +#if 0 /* Gives Python decoding errors while generating docs :( */ char error_str[256]; BLI_snprintf(error_str, sizeof(error_str), @@ -1487,7 +1495,7 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) return pyrna_py_from_array(ptr, prop); } - /* see if we can coerce into a python type - PropertyType */ + /* See if we can coerce into a Python type - 'PropertyType'. */ switch (type) { case PROP_BOOLEAN: ret = PyBool_FromLong(RNA_property_boolean_get(ptr, prop)); @@ -1506,7 +1514,7 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) buf = RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed), &buf_len); #ifdef USE_STRING_COERCE - /* only file paths get special treatment, they may contain non utf-8 chars */ + /* Only file paths get special treatment, they may contain non utf-8 chars. */ if (subtype == PROP_BYTESTRING) { ret = PyBytes_FromStringAndSize(buf, buf_len); } @@ -1561,7 +1569,7 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) /** * This function is used by operators and converting dicts into collections. - * Its takes keyword args and fills them with property values + * It takes keyword args and fills them with property values. */ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, @@ -1591,7 +1599,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, break; } - item = PyDict_GetItemString(kw, arg_name); /* wont set an error */ + item = PyDict_GetItemString(kw, arg_name); /* Wont set an error. */ if (item == NULL) { if (all_args) { @@ -1599,7 +1607,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, "%.200s: keyword \"%.200s\" missing", error_prefix, arg_name ? arg_name : "<UNKNOWN>"); - error_val = -1; /* pyrna_py_to_prop sets the error */ + error_val = -1; /* pyrna_py_to_prop sets the error. */ break; } } @@ -1613,7 +1621,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, } RNA_STRUCT_END; - if (error_val == 0 && totkw > 0) { /* some keywords were given that were not used :/ */ + if (error_val == 0 && totkw > 0) { /* Some keywords were given that were not used :/. */ PyObject *key, *value; Py_ssize_t pos = 0; @@ -1646,33 +1654,33 @@ static PyObject *pyrna_func_to_py(const PointerRNA *ptr, FunctionRNA *func) static int pyrna_py_to_prop( PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix) { - /* XXX hard limits should be checked here */ + /* XXX hard limits should be checked here. */ const int type = RNA_property_type(prop); if (RNA_property_array_check(prop)) { - /* done getting the length */ + /* Done getting the length. */ if (pyrna_py_to_array(ptr, prop, data, value, error_prefix) == -1) { return -1; } } else { - /* Normal Property (not an array) */ + /* Normal Property (not an array). */ - /* see if we can coerce into a python type - PropertyType */ + /* See if we can coerce into a Python type - 'PropertyType'. */ switch (type) { case PROP_BOOLEAN: { int param; - /* prefer not to have an exception here + /* Prefer not to have an exception here * however so many poll functions return None or a valid Object. - * its a hassle to convert these into a bool before returning, */ + * It's a hassle to convert these into a bool before returning. */ if (RNA_parameter_flag(prop) & PARM_OUTPUT) { param = PyObject_IsTrue(value); } else { param = PyC_Long_AsI32(value); - if (UNLIKELY(param & ~1)) { /* only accept 0/1 */ - param = -1; /* error out below */ + if (UNLIKELY(param & ~1)) { /* Only accept 0/1. */ + param = -1; /* Error out below. */ } } @@ -1774,7 +1782,7 @@ static int pyrna_py_to_prop( } else if (subtype == PROP_BYTESTRING) { - /* Byte String */ + /* Byte String. */ param = PyBytes_AsString(value); @@ -1810,11 +1818,11 @@ static int pyrna_py_to_prop( } } else { - /* Unicode String */ + /* Unicode String. */ #ifdef USE_STRING_COERCE PyObject *value_coerce = NULL; if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { - /* TODO, get size */ + /* TODO, get size. */ param = PyC_UnicodeAsByte(value, &value_coerce); } else { @@ -1847,8 +1855,8 @@ static int pyrna_py_to_prop( return -1; } else { - /* same as bytes */ - /* XXX, this is suspect but needed for function calls, + /* Same as bytes. */ + /* XXX, this is suspect, but needed for function calls, * need to see if theres a better way. */ if (data) { *((char **)data) = (char *)param; @@ -1866,15 +1874,15 @@ static int pyrna_py_to_prop( case PROP_ENUM: { int val = 0; - /* type checkins is done by each function */ + /* Type checking is done by each function. */ if (RNA_property_flag(prop) & PROP_ENUM_FLAG) { - /* set of enum items, concatenate all values with OR */ + /* Set of enum items, concatenate all values with OR. */ if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) == -1) { return -1; } } else { - /* simple enum string */ + /* Simple enum string. */ if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) == -1) { return -1; } @@ -1896,18 +1904,18 @@ static int pyrna_py_to_prop( int flag = RNA_property_flag(prop); int flag_parameter = RNA_parameter_flag(prop); - /* this is really nasty!, so we can fake the operator having direct properties eg: + /* This is really nasty! Done so we can fake the operator having direct properties, eg: * layout.prop(self, "filepath") - * ... which in fact should be + * ... which in fact should be: * layout.prop(self.properties, "filepath") * * we need to do this trick. * if the prop is not an operator type and the pyobject is an operator, - * use its properties in place of its self. + * use its properties in place of itself. * - * This is so bad that its almost a good reason to do away with fake + * This is so bad that it is almost a good reason to do away with fake * 'self.properties -> self' - * class mixing if this causes problems in the future it should be removed. + * class mixing. If this causes problems in the future it should be removed. */ if ((ptr_type == &RNA_AnyType) && (BPy_StructRNA_Check(value))) { const StructRNA *base_type = RNA_struct_base_child_of( @@ -1932,8 +1940,8 @@ static int pyrna_py_to_prop( } } - /* another exception, allow to pass a collection as an RNA property */ - if (Py_TYPE(value) == &pyrna_prop_collection_Type) { /* ok to ignore idprop collections */ + /* Another exception, allow to pass a collection as an RNA property. */ + if (Py_TYPE(value) == &pyrna_prop_collection_Type) { /* Ok to ignore idprop collections. */ PointerRNA c_ptr; BPy_PropertyRNA *value_prop = (BPy_PropertyRNA *)value; if (RNA_property_collection_type_get(&value_prop->ptr, value_prop->prop, &c_ptr)) { @@ -1943,7 +1951,7 @@ static int pyrna_py_to_prop( else { PyErr_Format(PyExc_TypeError, "%.200s %.200s.%.200s collection has no type, " - "cant be used as a %.200s type", + "can't be used as a %.200s type", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), @@ -1976,7 +1984,7 @@ static int pyrna_py_to_prop( else if ((value != Py_None) && ((flag & PROP_ID_SELF_CHECK) && ptr->id.data == ((BPy_StructRNA *)value)->ptr.id.data)) { PyErr_Format(PyExc_TypeError, - "%.200s %.200s.%.200s ID type does not support assignment to its self", + "%.200s %.200s.%.200s ID type does not support assignment to itself", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop)); @@ -2002,8 +2010,8 @@ static int pyrna_py_to_prop( } else { /* For function calls, we sometimes want to pass the 'ptr' directly, - * watch out that it remains valid!, - * possibly we could support this later if needed. */ + * but watch out that it remains valid! + * We could possibly support this later if needed. */ BLI_assert(value_new == NULL); if (value == Py_None) { *((void **)data) = NULL; @@ -2027,7 +2035,7 @@ static int pyrna_py_to_prop( } } else { - /* data == NULL, assign to RNA */ + /* Data == NULL, assign to RNA. */ if (value == Py_None || RNA_struct_is_a(param->ptr.type, ptr_type)) { ReportList reports; BKE_reports_init(&reports, RPT_STORE); @@ -2046,7 +2054,7 @@ static int pyrna_py_to_prop( if (raise_error) { if (pyrna_struct_validity_check(param) == -1) { - /* error set */ + /* Error set. */ } else { PointerRNA tmp; @@ -2077,7 +2085,7 @@ static int pyrna_py_to_prop( lb = (data) ? (ListBase *)data : NULL; - /* convert a sequence of dict's into a collection */ + /* Convert a sequence of dict's into a collection. */ if (!PySequence_Check(value)) { PyErr_Format( PyExc_TypeError, @@ -2127,7 +2135,7 @@ static int pyrna_py_to_prop( } if (pyrna_pydict_to_props( - &itemptr, item, true, "Converting a python list to an RNA collection") == -1) { + &itemptr, item, true, "Converting a Python list to an RNA collection") == -1) { PyObject *msg = PyC_ExceptionBuffer(); const char *msg_char = _PyUnicode_AsString(msg); @@ -2158,7 +2166,7 @@ static int pyrna_py_to_prop( } } - /* Run rna property functions */ + /* Run RNA property functions. */ if (RNA_property_update_check(prop)) { RNA_property_update(BPy_GetContext(), ptr, prop); } @@ -2181,21 +2189,21 @@ static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, P const int totdim = RNA_property_array_dimension(ptr, prop, NULL); if (totdim > 1) { - /* char error_str[512]; */ + // char error_str[512]; if (pyrna_py_to_array_index( &self->ptr, self->prop, self->arraydim, self->arrayoffset, index, value, "") == -1) { - /* error is set */ + /* Error is set. */ ret = -1; } } else { - /* see if we can coerce into a python type - PropertyType */ + /* See if we can coerce into a Python type - 'PropertyType'. */ switch (RNA_property_type(prop)) { case PROP_BOOLEAN: { int param = PyC_Long_AsBool(value); if (param == -1) { - /* error is set */ + /* Error is set. */ ret = -1; } else { @@ -2234,7 +2242,7 @@ static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, P } } - /* Run rna property functions */ + /* Run RNA property functions. */ if (RNA_property_update_check(prop)) { RNA_property_update(BPy_GetContext(), ptr, prop); } @@ -2273,7 +2281,7 @@ static int pyrna_prop_array_bool(BPy_PropertyRNA *self) static int pyrna_prop_collection_bool(BPy_PropertyRNA *self) { - /* no callback defined, just iterate and find the nth item */ + /* No callback defined, just iterate and find the nth item. */ CollectionPropertyIterator iter; int test; @@ -2298,7 +2306,7 @@ static int pyrna_prop_collection_bool(BPy_PropertyRNA *self) } \ (void)0 -/* internal use only */ +/* Internal use only. */ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum) { PointerRNA newptr; @@ -2323,7 +2331,7 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s else { PyErr_Format(PyExc_RuntimeError, "bpy_prop_collection[index]: internal error, " - "valid index %d given in %d sized collection but value not found", + "valid index %d given in %d sized collection, but value not found", keynum_abs, len); } @@ -2332,7 +2340,7 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s } } -/* values type must have been already checked */ +/* Values type must have been already checked. */ static int pyrna_prop_collection_ass_subscript_int(BPy_PropertyRNA *self, Py_ssize_t keynum, PyObject *value) @@ -2399,15 +2407,15 @@ static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, cons PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname); return NULL; } -/* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */ +// static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) /** * Special case: `bpy.data.objects["some_id_name", "//some_lib_name.blend"]` * also for: `bpy.data.objects.get(("some_id_name", "//some_lib_name.blend"), fallback)` * * \note - * error codes since this is not to be called directly from python, - * this matches pythons `__contains__` values capi. + * error codes since this is not to be called directly from Python, + * this matches Python's `__contains__` values C-API. * - -1: exception set * - 0: not found * - 1: found @@ -2420,7 +2428,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel { const char *keyname; - /* first validate the args, all we know is that they are a tuple */ + /* First validate the args, all we know is that they are a tuple. */ if (PyTuple_GET_SIZE(key) != 2) { PyErr_Format(PyExc_KeyError, "%s: tuple key must be a pair, not size %d", @@ -2480,7 +2488,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel * either way can do direct comparison with id.lib */ RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { - ID *id = itemptr.data; /* always an ID */ + ID *id = itemptr.data; /* Always an ID. */ if (id->lib == lib && (STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2))) { found = true; if (r_ptr) { @@ -2491,14 +2499,14 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel } RNA_PROP_END; - /* we may want to fail silently as with collection.get() */ + /* We may want to fail silently as with collection.get(). */ if ((found == false) && err_not_found) { - /* only runs for getitem access so use fixed string */ + /* Only runs for getitem access so use fixed string. */ PyErr_SetString(PyExc_KeyError, "bpy_prop_collection[key, lib]: not found"); return -1; } else { - return found; /* 1 / 0, no exception */ + return found; /* 1 / 0, no exception. */ } } } @@ -2534,11 +2542,11 @@ static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, list = PyList_New(0); - /* skip to start */ + /* Skip to start. */ RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter); RNA_property_collection_skip(&rna_macro_iter, start); - /* add items until stop */ + /* Add items until stop. */ for (count = start; rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) { item = pyrna_struct_CreatePyObject(&rna_macro_iter.ptr); PyList_APPEND(list, item); @@ -2554,8 +2562,8 @@ static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, return list; } -/* TODO - dimensions - * note: could also use pyrna_prop_array_to_py_index(self, count) in a loop but its a lot slower +/** TODO - dimensions + * \note Could also use pyrna_prop_array_to_py_index(self, count) in a loop, but it's much slower * since at the moment it reads (and even allocates) the entire array for each index. */ static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, @@ -2568,7 +2576,7 @@ static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, int count, totdim; PyObject *tuple; - /* isn't needed, internal use only */ + /* Isn't needed, internal use only. */ // PYRNA_PROP_CHECK_OBJ((BPy_PropertyRNA *)self); tuple = PyTuple_New(stop - start); @@ -2686,7 +2694,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject else { Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; - /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ + /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) { return NULL; } @@ -2695,7 +2703,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject } if (start < 0 || stop < 0) { - /* only get the length for negative values */ + /* Only get the length for negative values. */ Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop); if (start < 0) { start += len; @@ -2714,7 +2722,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject } } else if (PyTuple_Check(key)) { - /* special case, for ID datablocks we */ + /* Special case, for ID datablocks we. */ return pyrna_prop_collection_subscript_str_lib_pair( self, key, "bpy_prop_collection[id, lib]", true); } @@ -2741,7 +2749,7 @@ static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *val return -1; } else { - return 0; /* None is OK */ + return 0; /* None is OK. */ } } else if (BPy_StructRNA_Check(value) == 0) { @@ -2762,7 +2770,7 @@ static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *val return -1; } else { - return 0; /* OK, this is the correct type!*/ + return 0; /* OK, this is the correct type! */ } } @@ -2780,13 +2788,13 @@ static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, { PYRNA_PROP_CHECK_INT(self); - /* validate the assigned value */ + /* Validate the assigned value. */ if (value == NULL) { PyErr_SetString(PyExc_TypeError, "del bpy_prop_collection[key]: not supported"); return -1; } else if (pyrna_prop_collection_type_check(self, value) == -1) { - return -1; /* exception is set */ + return -1; /* Exception is set. */ } #if 0 @@ -2803,7 +2811,7 @@ static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, return pyrna_prop_collection_ass_subscript_int(self, i, value); } -#if 0 /* TODO, fake slice assignment */ +#if 0 /* TODO, fake slice assignment. */ else if (PySlice_Check(key)) { PySliceObject *key_slice = (PySliceObject *)key; Py_ssize_t step = 1; @@ -2821,7 +2829,7 @@ static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, else { Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; - /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ + /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) { return NULL; } @@ -2830,7 +2838,7 @@ static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self, } if (start < 0 || stop < 0) { - /* only get the length for negative values */ + /* Only get the length for negative values. */ Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop); if (start < 0) { start += len; @@ -2887,7 +2895,7 @@ static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject return NULL; } else if (key_slice->start == Py_None && key_slice->stop == Py_None) { - /* note, no significant advantage with optimizing [:] slice as with collections + /* Note: no significant advantage with optimizing [:] slice as with collections, * but include here for consistency with collection slice func */ Py_ssize_t len = (Py_ssize_t)pyrna_prop_array_length(self); return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len); @@ -3038,7 +3046,7 @@ static int prop_subscript_ass_array_slice__bool_recursive(PyObject **value_items } } -/* could call (pyrna_py_to_prop_array_index(self, i, value) in a loop but it is slow */ +/* Could call `pyrna_py_to_prop_array_index(self, i, value)` in a loop, but it is slow. */ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, int arraydim, @@ -3094,7 +3102,7 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, (values_alloc = PyMem_MALLOC(sizeof(*values) * length_flat)) : values_stack; if (start != 0 || stop != length) { - /* partial assignment? - need to get the array */ + /* Partial assignment? - need to get the array. */ RNA_property_float_get_array(ptr, prop, values); } @@ -3122,7 +3130,7 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, (values_alloc = PyMem_MALLOC(sizeof(*values) * length_flat)) : values_stack; if (start != 0 || stop != length) { - /* partial assignment? - need to get the array */ + /* Partial assignment? - need to get the array. */ RNA_property_int_get_array(ptr, prop, values); } @@ -3151,7 +3159,7 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, values_stack; if (start != 0 || stop != length) { - /* partial assignment? - need to get the array */ + /* Partial assignment? - need to get the array. */ RNA_property_boolean_get_array(ptr, prop, values); } @@ -3210,7 +3218,7 @@ static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self, PyObject *key, PyObject *value) { - /* char *keyname = NULL; */ /* not supported yet */ + // char *keyname = NULL; /* Not supported yet. */ int ret = -1; PYRNA_PROP_CHECK_INT((BPy_PropertyRNA *)self); @@ -3240,14 +3248,14 @@ static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self, ret = -1; } else if (slicelength <= 0) { - ret = 0; /* do nothing */ + ret = 0; /* Do nothing. */ } else if (step == 1) { ret = prop_subscript_ass_array_slice( &self->ptr, self->prop, self->arraydim, self->arrayoffset, start, stop, len, value); } else { - PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna"); + PyErr_SetString(PyExc_TypeError, "slice steps not supported with RNA"); ret = -1; } } @@ -3265,7 +3273,7 @@ static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self, return ret; } -/* for slice only */ +/* For slice only. */ static PyMappingMethods pyrna_prop_array_as_mapping = { (lenfunc)pyrna_prop_array_length, /* mp_length */ (binaryfunc)pyrna_prop_array_subscript, /* mp_subscript */ @@ -3278,7 +3286,7 @@ static PyMappingMethods pyrna_prop_collection_as_mapping = { (objobjargproc)pyrna_prop_collection_ass_subscript, /* mp_ass_subscript */ }; -/* only for fast bool's, large structs, assign nb_bool on init */ +/* Only for fast bool's, large structs, assign nb_bool on init. */ static PyNumberMethods pyrna_prop_array_as_number = { NULL, /* nb_add */ NULL, /* nb_subtract */ @@ -3311,16 +3319,16 @@ static int pyrna_prop_array_contains(BPy_PropertyRNA *self, PyObject *value) static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key) { - PointerRNA newptr; /* not used, just so RNA_property_collection_lookup_string runs */ + PointerRNA newptr; /* Not used, just so RNA_property_collection_lookup_string runs. */ if (PyTuple_Check(key)) { - /* special case, for ID datablocks we */ + /* Special case, for ID data-blocks. */ return pyrna_prop_collection_subscript_str_lib_pair_ptr( self, key, "(id, lib) in bpy_prop_collection", false, NULL); } else { - /* key in dict style check */ + /* Key in dict style check. */ const char *keyname = _PyUnicode_AsString(key); if (keyname == NULL) { @@ -3393,7 +3401,7 @@ static PySequenceMethods pyrna_prop_collection_as_sequence = { }; static PySequenceMethods pyrna_struct_as_sequence = { - NULL, /* Cant set the len otherwise it can evaluate as false */ + NULL, /* Can't set the len otherwise it can evaluate as false */ NULL, /* sq_concat */ NULL, /* sq_repeat */ NULL, @@ -3408,7 +3416,7 @@ static PySequenceMethods pyrna_struct_as_sequence = { static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key) { - /* mostly copied from BPy_IDGroup_Map_GetItem */ + /* Mostly copied from BPy_IDGroup_Map_GetItem. */ IDProperty *group, *idprop; const char *name = _PyUnicode_AsString(key); @@ -3487,7 +3495,7 @@ static PyMappingMethods pyrna_struct_as_mapping = { PyDoc_STRVAR(pyrna_struct_keys_doc, ".. method:: keys()\n" "\n" - " Returns the keys of this objects custom properties (matches pythons\n" + " Returns the keys of this objects custom properties (matches Python's\n" " dictionary function of the same name).\n" "\n" " :return: custom property keys.\n" @@ -3514,7 +3522,7 @@ static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self) PyDoc_STRVAR(pyrna_struct_items_doc, ".. method:: items()\n" "\n" - " Returns the items of this objects custom properties (matches pythons\n" + " Returns the items of this objects custom properties (matches Python's\n" " dictionary function of the same name).\n" "\n" " :return: custom property key, value pairs.\n" @@ -3541,7 +3549,7 @@ static PyObject *pyrna_struct_items(BPy_PropertyRNA *self) PyDoc_STRVAR(pyrna_struct_values_doc, ".. method:: values()\n" "\n" - " Returns the values of this objects custom properties (matches pythons\n" + " Returns the values of this objects custom properties (matches Python's\n" " dictionary function of the same name).\n" "\n" " :return: custom property values.\n" @@ -3750,7 +3758,7 @@ PyDoc_STRVAR(pyrna_struct_path_resolve_doc, " :arg path: path which this property resolves.\n" " :type path: string\n" " :arg coerce: optional argument, when True, the property will be converted\n" - " into its python representation.\n" + " into its Python representation.\n" " :type coerce: boolean\n"); static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args) { @@ -3845,7 +3853,7 @@ static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args) if (path == NULL) { if (name) { PyErr_Format(PyExc_ValueError, - "%.200s.path_from_id(\"%s\") found but does not support path creation", + "%.200s.path_from_id(\"%s\") found, but does not support path creation", RNA_struct_identifier(self->ptr.type), name); } @@ -3895,7 +3903,7 @@ static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self) PyDoc_STRVAR(pyrna_prop_as_bytes_doc, ".. method:: as_bytes()\n" "\n" - " Returns this string property as a byte rather than a python string.\n" + " Returns this string property as a byte rather than a Python string.\n" "\n" " :return: The string as bytes.\n" " :rtype: bytes\n"); @@ -3934,7 +3942,7 @@ PyDoc_STRVAR(pyrna_prop_update_doc, "\n" " .. note::\n" " This is called when assigning a property,\n" - " however in rare cases its useful to call explicitly.\n"); + " however in rare cases it's useful to call explicitly.\n"); static PyObject *pyrna_prop_update(BPy_PropertyRNA *self) { RNA_property_update(BPy_GetContext(), &self->ptr, self->prop); @@ -4085,7 +4093,7 @@ static void pyrna_dir_members_py(PyObject *list, PyObject *self) pyrna_dir_members_py__add_keys(list, dict); } - /* since this is least common case, handle it last */ + /* Since this is least common case, handle it last. */ if (BPy_PropertyRNA_Check(self)) { BPy_PropertyRNA *self_prop = (BPy_PropertyRNA *)self; if (RNA_property_type(self_prop->prop) == PROP_COLLECTION) { @@ -4105,7 +4113,7 @@ static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr) { const char *idname; - /* for looping over attrs and funcs */ + /* For looping over attrs and funcs. */ PointerRNA tptr; PropertyRNA *iterprop; @@ -4153,9 +4161,8 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA *self) PYRNA_STRUCT_CHECK_OBJ(self); - /* Include this in case this instance is a subtype of a python class - * In these instances we may want to return a function or variable provided by the subtype - * */ + /* Include this in case this instance is a subtype of a Python class + * In these instances we may want to return a function or variable provided by the subtype. */ ret = PyList_New(0); if (!BPy_StructRNA_CheckExact(self)) { @@ -4177,7 +4184,7 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA *self) { /* set(), this is needed to remove-doubles because the deferred - * register-props will be in both the python __dict__ and accessed as RNA */ + * register-props will be in both the Python __dict__ and accessed as RNA */ PyObject *set = PySet_New(ret); @@ -4204,9 +4211,9 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) ret = NULL; } else if ( - /* rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups */ + /* RNA can't start with a "_", so for __dict__ and similar we can skip using RNA lookups. */ name[0] == '_') { - /* annoying exception, maybe we need to have different types for this... */ + /* Annoying exception, maybe we need to have different types for this... */ if (STR_ELEM(name, "__getitem__", "__setitem__") && !RNA_struct_idprops_check(self->ptr.type)) { PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type"); @@ -4219,7 +4226,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) else if ((prop = RNA_struct_find_property(&self->ptr, name))) { ret = pyrna_prop_to_py(&self->ptr, prop); } - /* RNA function only if callback is declared (no optional functions) */ + /* RNA function only if callback is declared (no optional functions). */ else if ((func = RNA_struct_find_function(self->ptr.type, name)) && RNA_function_defined(func)) { ret = pyrna_func_to_py(&self->ptr, func); } @@ -4238,7 +4245,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) int done = CTX_data_get(C, name, &newptr, &newlb, &newtype); - if (done == 1) { /* found */ + if (done == 1) { /* Found. */ switch (newtype) { case CTX_DATA_TYPE_POINTER: if (newptr.data == NULL) { @@ -4260,7 +4267,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) break; } default: - /* should never happen */ + /* Should never happen. */ BLI_assert(!"Invalid context type"); PyErr_Format(PyExc_AttributeError, @@ -4271,12 +4278,12 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) break; } } - else if (done == -1) { /* found but not set */ + else if (done == -1) { /* Found, but not set. */ ret = Py_None; Py_INCREF(ret); } - else { /* not found in the context */ - /* lookup the subclass. raise an error if its not found */ + else { /* Not found in the context. */ + /* Lookup the subclass. raise an error if it's not found. */ ret = PyObject_GenericGetAttr((PyObject *)self, pyname); } @@ -4288,11 +4295,11 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" not found", name); ret = NULL; #endif - /* Include this in case this instance is a subtype of a python class + /* Include this in case this instance is a subtype of a Python class * In these instances we may want to return a function or variable provided by the subtype * - * Also needed to return methods when its not a subtype - * */ + * Also needed to return methods when it's not a subtype. + */ /* The error raised here will be displayed */ ret = PyObject_GenericGetAttr((PyObject *)self, pyname); @@ -4342,7 +4349,7 @@ static PyObject *pyrna_struct_meta_idprop_getattro(PyObject *cls, PyObject *attr PropertyRNA *prop = RNA_struct_type_find_property(srna, _PyUnicode_AsString(attr)); if (prop) { PointerRNA tptr; - PyErr_Clear(); /* clear error from tp_getattro */ + PyErr_Clear(); /* Clear error from tp_getattro. */ RNA_pointer_create(NULL, &RNA_Property, prop, &tptr); ret = pyrna_struct_CreatePyObject(&tptr); } @@ -4371,7 +4378,7 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb } if (srna == NULL) { - /* allow setting on unregistered classes which can be registered later on */ + /* Allow setting on unregistered classes which can be registered later on. */ #if 0 if (value && is_deferred_prop) { PyErr_Format(PyExc_AttributeError, @@ -4380,31 +4387,31 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb return -1; } #endif - /* srna_from_self may set an error */ + /* srna_from_self may set an error. */ PyErr_Clear(); return PyType_Type.tp_setattro(cls, attr, value); } if (value) { - /* check if the value is a property */ + /* Check if the value is a property. */ if (is_deferred_prop) { int ret = deferred_register_prop(srna, attr, value); if (ret == -1) { - /* error set */ + /* Error set. */ return ret; } /* pass through and assign to the classes __dict__ as well - * when the value isn't assigned it still creates the RNA property - * but gets confusing from script writers POV if the assigned value cant be read back. */ + * so when the value isn't assigned it still creates the RNA property, + * but gets confusing from script writers POV if the assigned value can't be read back. */ } else { - /* remove existing property if its set or we also end up with confusion */ - RNA_def_property_free_identifier(srna, attr_str); /* ignore on failure */ + /* Remove existing property if it's set or we also end up with confusion. */ + RNA_def_property_free_identifier(srna, attr_str); /* Ignore on failure. */ } } else { /* __delattr__ */ - /* first find if this is a registered property */ + /* First find if this is a registered property. */ const int ret = RNA_def_property_free_identifier(srna, attr_str); if (ret == -1) { PyErr_Format( @@ -4413,7 +4420,7 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb } } - /* fallback to standard py, delattr/setattr */ + /* Fallback to standard py, delattr/setattr. */ return PyType_Type.tp_setattro(cls, attr, value); } @@ -4444,8 +4451,8 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject } } else if (self->ptr.type == &RNA_Context) { - /* Code just raises correct error, context prop's cant be set, - * unless its apart of the py class. */ + /* Code just raises correct error, context prop's can't be set, + * unless it's a part of the py class. */ bContext *C = self->ptr.data; if (C == NULL) { PyErr_Format(PyExc_AttributeError, @@ -4489,9 +4496,8 @@ static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self) PyObject *ret; PointerRNA r_ptr; - /* Include this in case this instance is a subtype of a python class - * In these instances we may want to return a function or variable provided by the subtype - * */ + /* Include this in case this instance is a subtype of a Python class + * In these instances we may want to return a function or variable provided by the subtype. */ ret = PyList_New(0); if (!BPy_PropertyRNA_CheckExact(self)) { @@ -4553,8 +4559,8 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject PyObject *ret = PyObject_GenericGetAttr((PyObject *)self, pyname); - if (ret == NULL && name[0] != '_') { /* avoid inheriting __call__ and similar */ - /* since this is least common case, handle it last */ + if (ret == NULL && name[0] != '_') { /* Avoid inheriting __call__ and similar. */ + /* Since this is least common case, handle it last. */ PointerRNA r_ptr; if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { PyObject *cls; @@ -4567,7 +4573,7 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject ret = PyObject_GenericGetAttr(cls, pyname); Py_DECREF(cls); - /* restore the original error */ + /* Restore the original error. */ if (ret == NULL) { PyErr_Restore(error_type, error_value, error_traceback); } @@ -4602,7 +4608,7 @@ static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pynam } else if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { if ((prop = RNA_struct_find_property(&r_ptr, name))) { - /* pyrna_py_to_prop sets its own exceptions */ + /* pyrna_py_to_prop sets its own exceptions. */ return pyrna_py_to_prop(&r_ptr, prop, NULL, value, "BPy_PropertyRNA - Attribute (setattr):"); } } @@ -4611,7 +4617,9 @@ static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pynam return -1; } -/* odd case, we need to be able return a python method from a tp_getset */ +/** + * Odd case, we need to be able return a Python method from a #PyTypeObject.tp_getset. + */ static PyObject *pyrna_prop_collection_idprop_add(BPy_PropertyRNA *self) { PointerRNA r_ptr; @@ -4699,7 +4707,7 @@ PyDoc_STRVAR(pyrna_struct_get_id_data_doc, "all data types)"); static PyObject *pyrna_struct_get_id_data(BPy_DummyPointerRNA *self) { - /* used for struct and pointer since both have a ptr */ + /* Used for struct and pointer since both have a ptr. */ if (self->ptr.id.data) { PointerRNA id_ptr; RNA_id_pointer_create((ID *)self->ptr.id.data, &id_ptr); @@ -4767,7 +4775,7 @@ PyDoc_STRVAR(pyrna_prop_collection_keys_doc, ".. method:: keys()\n" "\n" " Return the identifiers of collection members\n" - " (matching pythons dict.keys() functionality).\n" + " (matching Python's dict.keys() functionality).\n" "\n" " :return: the identifiers for each member of this collection.\n" " :rtype: list of strings\n"); @@ -4797,7 +4805,7 @@ PyDoc_STRVAR(pyrna_prop_collection_items_doc, ".. method:: items()\n" "\n" " Return the identifiers of collection members\n" - " (matching pythons dict.items() functionality).\n" + " (matching Python's dict.items() functionality).\n" "\n" " :return: (key, value) pairs for each member of this collection.\n" " :rtype: list of tuples\n"); @@ -4811,7 +4819,7 @@ static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self) RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { if (itemptr.data) { - /* add to python list */ + /* Add to Python list. */ item = PyTuple_New(2); nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen); if (nameptr) { @@ -4821,7 +4829,7 @@ static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self) } } else { - /* a bit strange but better then returning an empty list */ + /* A bit strange, but better then returning an empty list. */ PyTuple_SET_ITEM(item, 0, PyLong_FromLong(i)); } PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&itemptr)); @@ -4840,13 +4848,13 @@ PyDoc_STRVAR(pyrna_prop_collection_values_doc, ".. method:: values()\n" "\n" " Return the values of collection\n" - " (matching pythons dict.values() functionality).\n" + " (matching Python's dict.values() functionality).\n" "\n" " :return: the members of this collection.\n" " :rtype: list\n"); static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self) { - /* re-use slice*/ + /* Re-use slice. */ return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX); } @@ -4854,7 +4862,7 @@ PyDoc_STRVAR(pyrna_struct_get_doc, ".. method:: get(key, default=None)\n" "\n" " Returns the value of the custom property assigned to key or default\n" - " when not found (matches pythons dictionary function of the same name).\n" + " when not found (matches Python's dictionary function of the same name).\n" "\n" " :arg key: The key associated with the custom property.\n" " :type key: string\n" @@ -4875,7 +4883,7 @@ static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args) return NULL; } - /* mostly copied from BPy_IDGroup_Map_GetItem */ + /* Mostly copied from BPy_IDGroup_Map_GetItem. */ if (RNA_struct_idprops_check(self->ptr.type) == 0) { PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties"); return NULL; @@ -4897,7 +4905,7 @@ PyDoc_STRVAR(pyrna_struct_pop_doc, ".. method:: pop(key, default=None)\n" "\n" " Remove and return the value of the custom property assigned to key or default\n" - " when not found (matches pythons dictionary function of the same name).\n" + " when not found (matches Python's dictionary function of the same name).\n" "\n" " :arg key: The key associated with the custom property.\n" " :type key: string\n" @@ -4918,7 +4926,7 @@ static PyObject *pyrna_struct_pop(BPy_StructRNA *self, PyObject *args) return NULL; } - /* mostly copied from BPy_IDGroup_Map_GetItem */ + /* Mostly copied from BPy_IDGroup_Map_GetItem. */ if (RNA_struct_idprops_check(self->ptr.type) == 0) { PyErr_SetString(PyExc_TypeError, "this type doesn't support IDProperties"); return NULL; @@ -4945,7 +4953,7 @@ static PyObject *pyrna_struct_pop(BPy_StructRNA *self, PyObject *args) PyDoc_STRVAR(pyrna_struct_as_pointer_doc, ".. method:: as_pointer()\n" "\n" - " Returns the memory address which holds a pointer to blenders internal data\n" + " Returns the memory address which holds a pointer to Blender's internal data\n" "\n" " :return: int (memory address).\n" " :rtype: int\n" @@ -4961,7 +4969,7 @@ PyDoc_STRVAR(pyrna_prop_collection_get_doc, ".. method:: get(key, default=None)\n" "\n" " Returns the value of the item assigned to key or default when not found\n" - " (matches pythons dictionary function of the same name).\n" + " (matches Python's dictionary function of the same name).\n" "\n" " :arg key: The identifier for the collection member.\n" " :type key: string\n" @@ -5008,7 +5016,7 @@ 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" + " (matches Python's string find function of the same name).\n" "\n" " :arg key: The identifier for the collection member.\n" " :type key: string\n" @@ -5018,7 +5026,7 @@ static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key { 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 */ + const int key_len = (int)key_len_ssize_t; /* Comare with same type. */ char name[256], *nameptr; int namelen; @@ -5050,7 +5058,7 @@ static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key static bool foreach_attr_type(BPy_PropertyRNA *self, const char *attr, - /* values to assign */ + /* Values to assign. */ RawPropertyType *raw_type, int *attr_tot, bool *attr_signed) @@ -5061,7 +5069,7 @@ static bool foreach_attr_type(BPy_PropertyRNA *self, *attr_tot = 0; *attr_signed = false; - /* note: this is fail with zero length lists, so don't let this get caled in that case */ + /* Note: this is fail with zero length lists, so don't let this get caled in that case. */ RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) { prop = RNA_struct_find_property(&itemptr, attr); if (prop) { @@ -5079,11 +5087,11 @@ static bool foreach_attr_type(BPy_PropertyRNA *self, return attr_ok; } -/* pyrna_prop_collection_foreach_get/set both use this */ +/* pyrna_prop_collection_foreach_get/set both use this. */ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args, - /* values to assign */ + /* Values to assign. */ const char **attr, PyObject **seq, int *tot, @@ -5113,7 +5121,8 @@ static int foreach_parse_args(BPy_PropertyRNA *self, return -1; } - *tot = PySequence_Size(*seq); /* TODO - buffer may not be a sequence! array.array() is tho. */ + /* TODO - buffer may not be a sequence! array.array() is though. */ + *tot = PySequence_Size(*seq); if (*tot > 0) { if (!foreach_attr_type(self, *attr, raw_type, attr_tot, attr_signed)) { @@ -5126,7 +5135,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, } *size = RNA_raw_type_sizeof(*raw_type); -#if 0 /* works fine but not strictly needed, \ +#if 0 /* Works fine, but not strictly needed. \ * we could allow RNA_property_collection_raw_* to do the checks */ if ((*attr_tot) < 1) { *attr_tot = 1; @@ -5141,7 +5150,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, target_tot = array_tot * (*attr_tot); - /* rna_access.c - rna_raw_access(...) uses this same method */ + /* rna_access.c - rna_raw_access(...) uses this same method. */ if (target_tot != (*tot)) { PyErr_Format(PyExc_TypeError, "foreach_get(attr, sequence) sequence length mismatch given %d, needed %d", @@ -5152,9 +5161,9 @@ static int foreach_parse_args(BPy_PropertyRNA *self, #endif } - /* Check 'attr_tot' otherwise we don't know if any values were set - * this isn't ideal because it means running on an empty list may - * fail silently when its not compatible. */ + /* Check 'attr_tot' otherwise we don't know if any values were set. + * This isn't ideal because it means running on an empty list may + * fail silently when it's not compatible. */ if (*size == 0 && *attr_tot != 0) { PyErr_SetString(PyExc_AttributeError, "attribute does not support foreach method"); return -1; @@ -5208,7 +5217,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) bool buffer_is_compat; void *array = NULL; - /* get/set both take the same args currently */ + /* Get/set both take the same args currently. */ const char *attr; PyObject *seq; int tot, size, attr_tot; @@ -5224,13 +5233,13 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) Py_RETURN_NONE; } - if (set) { /* get the array from python */ + if (set) { /* Get the array from python. */ buffer_is_compat = false; if (PyObject_CheckBuffer(seq)) { Py_buffer buf; PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); - /* check if the buffer matches */ + /* Check if the buffer matches. */ buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format); @@ -5242,7 +5251,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) PyBuffer_Release(&buf); } - /* could not use the buffer, fallback to sequence */ + /* Could not use the buffer, fallback to sequence. */ if (!buffer_is_compat) { array = PyMem_Malloc(size * tot); @@ -5268,7 +5277,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) ((double *)array)[i] = (double)PyFloat_AsDouble(item); break; case PROP_RAW_UNSET: - /* should never happen */ + /* Should never happen. */ BLI_assert(!"Invalid array type - set"); break; } @@ -5286,7 +5295,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) Py_buffer buf; PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); - /* check if the buffer matches, TODO - signed/unsigned types */ + /* Check if the buffer matches, TODO - signed/unsigned types. */ buffer_is_compat = foreach_compat_buffer(raw_type, attr_signed, buf.format); @@ -5298,7 +5307,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) PyBuffer_Release(&buf); } - /* could not use the buffer, fallback to sequence */ + /* Could not use the buffer, fallback to sequence. */ if (!buffer_is_compat) { array = PyMem_Malloc(size * tot); @@ -5306,7 +5315,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) NULL, &self->ptr, self->prop, attr, array, raw_type, tot); if (!ok) { - /* skip the loop */ + /* Skip the loop. */ i = tot; } @@ -5332,7 +5341,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) item = PyBool_FromLong((long)((bool *)array)[i]); break; default: /* PROP_RAW_UNSET */ - /* should never happen */ + /* Should never happen. */ BLI_assert(!"Invalid array type - get"); item = Py_None; Py_INCREF(item); @@ -5350,7 +5359,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) } if (PyErr_Occurred()) { - /* Maybe we could make our own error */ + /* Maybe we could make our own error. */ PyErr_Print(); PyErr_SetString(PyExc_TypeError, "couldn't access the py sequence"); return NULL; @@ -5386,10 +5395,10 @@ static PyObject *pyrna_prop_collection_foreach_set(BPy_PropertyRNA *self, PyObje } /* A bit of a kludge, make a list out of a collection or array, - * then return the lists iter function, not especially fast but convenient for now */ + * then return the list's iter function, not especially fast, but convenient for now. */ static PyObject *pyrna_prop_array_iter(BPy_PropertyArrayRNA *self) { - /* Try get values from a collection */ + /* Try get values from a collection. */ PyObject *ret; PyObject *iter = NULL; int len; @@ -5414,7 +5423,7 @@ static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self); #ifndef USE_PYRNA_ITER static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self) { - /* Try get values from a collection */ + /* Try get values from a collection. */ PyObject *ret; PyObject *iter = NULL; ret = pyrna_prop_collection_values(self); @@ -5432,7 +5441,7 @@ static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self) static struct PyMethodDef pyrna_struct_methods[] = { - /* only for PointerRNA's with ID'props */ + /* Only for PointerRNA's with ID'props. */ {"keys", (PyCFunction)pyrna_struct_keys, METH_NOARGS, pyrna_struct_keys_doc}, {"values", (PyCFunction)pyrna_struct_values, METH_NOARGS, pyrna_struct_values_doc}, {"items", (PyCFunction)pyrna_struct_items, METH_NOARGS, pyrna_struct_items_doc}, @@ -5581,7 +5590,7 @@ static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject * } else if (PyType_IsSubtype(Py_TYPE(base), &pyrna_struct_Type)) { /* this almost never runs, only when using user defined subclasses of built-in object. - * this isn't common since its NOT related to registerable subclasses. eg: + * this isn't common since it's NOT related to registerable subclasses. eg: * * >>> class MyObSubclass(bpy.types.Object): * ... def test_func(self): @@ -5597,11 +5606,11 @@ static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject * if ((ret = (BPy_StructRNA *)type->tp_alloc(type, 0))) { ret->ptr = base->ptr; } - /* pass on exception & NULL if tp_alloc fails */ + /* Pass on exception & NULL if tp_alloc fails. */ return (PyObject *)ret; } - /* error, invalid type given */ + /* Error, invalid type given. */ PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(type): type '%.200s' is not a subtype of bpy_struct", type->tp_name); @@ -5659,9 +5668,9 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat len = RNA_property_array_length(ptr, prop); } - /* resolve the array from a new pytype */ + /* Resolve the array from a new pytype. */ - /* kazanbas: TODO make multidim sequences here */ + /* TODO(Kazanbas) make multi-dimensional sequences here. */ switch (type) { case PROP_BOOLEAN: @@ -5709,7 +5718,7 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat } } else { - /* see if we can coerce into a python type - PropertyType */ + /* See if we can coerce into a python type - PropertyType. */ switch (type) { case PROP_BOOLEAN: ret = PyBool_FromLong(*(bool *)data); @@ -5766,7 +5775,7 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat StructRNA *ptype = RNA_property_pointer_type(ptr, prop); if (flag_parameter & PARM_RNAPTR) { - /* in this case we get the full ptr */ + /* In this case we get the full ptr. */ newptr = *(PointerRNA *)data; } else { @@ -5813,9 +5822,11 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat return ret; } -/* Use to replace PyDict_GetItemString() when the overhead of converting a - * string into a python unicode is higher than a non hash lookup. - * works on small dict's such as keyword args. */ +/** + * Use to replace PyDict_GetItemString() when the overhead of converting a + * string into a Python unicode is higher than a non hash lookup. + * works on small dict's such as keyword args. + */ static PyObject *small_dict_get_item_string(PyObject *dict, const char *key_lookup) { PyObject *key = NULL; @@ -5835,7 +5846,7 @@ static PyObject *small_dict_get_item_string(PyObject *dict, const char *key_look static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject *kw) { - /* Note, both BPy_StructRNA and BPy_PropertyRNA can be used here */ + /* Note, both BPy_StructRNA and BPy_PropertyRNA can be used here. */ PointerRNA *self_ptr = &self->ptr; FunctionRNA *self_func = self->func; @@ -5858,24 +5869,24 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject PyObject *string_free_ls = PyList_New(0); #endif - /* Should never happen but it does in rare cases */ + /* Should never happen, but it does in rare cases. */ BLI_assert(self_ptr != NULL); if (self_ptr == NULL) { PyErr_SetString(PyExc_RuntimeError, - "rna functions internal rna pointer is NULL, this is a bug. aborting"); + "RNA functions internal RNA pointer is NULL, this is a bug. aborting"); return NULL; } if (self_func == NULL) { PyErr_Format( PyExc_RuntimeError, - "%.200s.<unknown>(): rna function internal function is NULL, this is a bug. aborting", + "%.200s.<unknown>(): RNA function internal function is NULL, this is a bug. aborting", RNA_struct_identifier(self_ptr->type)); return NULL; } - /* for testing */ + /* For testing. */ #if 0 { const char *fn; @@ -5913,12 +5924,12 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject err = -1; } - /* parse function parameters */ + /* Parse function parameters. */ for (i = 0; iter.valid && err == 0; RNA_parameter_list_next(&iter)) { parm = iter.parm; flag_parameter = RNA_parameter_flag(parm); - /* only useful for single argument returns, we'll need another list loop for multiple */ + /* Only useful for single argument returns, we'll need another list loop for multiple. */ if (flag_parameter & PARM_OUTPUT) { ret_len++; if (pret_single == NULL) { @@ -5932,7 +5943,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject item = NULL; if (i < pyargs_len) { - /* New in 2.8x, optional arguments must be keywords. */ + /* New in 2.8x, optional arguments must be keywords. */ if (UNLIKELY((flag_parameter & PARM_REQUIRED) == 0)) { PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): required parameter \"%.200s\" to be a keyword argument!", @@ -5948,18 +5959,18 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject } else if (kw != NULL) { #if 0 - item = PyDict_GetItemString(kw, RNA_property_identifier(parm)); /* borrow ref */ + item = PyDict_GetItemString(kw, RNA_property_identifier(parm)); /* Borrow reference. */ #else - item = small_dict_get_item_string(kw, RNA_property_identifier(parm)); /* borrow ref */ + item = small_dict_get_item_string(kw, RNA_property_identifier(parm)); /* Borrow reference. */ #endif if (item) { - kw_tot++; /* make sure invalid keywords are not given */ + kw_tot++; /* Make sure invalid keywords are not given. */ } kw_arg = true; } - i++; /* current argument */ + i++; /* Current argument. */ if (item == NULL) { if (flag_parameter & PARM_REQUIRED) { @@ -5971,7 +5982,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject err = -1; break; } - else { /* PyDict_GetItemString wont raise an error */ + else { /* PyDict_GetItemString wont raise an error. */ continue; } } @@ -5989,7 +6000,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject /* the error generated isn't that useful, so generate it again with a useful prefix * could also write a function to prepend to error messages */ char error_prefix[512]; - PyErr_Clear(); /* re-raise */ + PyErr_Clear(); /* Re-raise. */ if (kw_arg == true) { BLI_snprintf(error_prefix, @@ -6018,8 +6029,8 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject RNA_parameter_list_end(&iter); /* Check if we gave args that don't exist in the function - * printing the error is slow but it should only happen when developing. - * the if below is quick, checking if it passed less keyword args then we gave. + * Printing the error is slow, but it should only happen when developing. + * The "if" below is quick check to make sure less keyword args were passed then we gave. * (Don't overwrite the error if we have one, * otherwise can skip important messages and confuse with args). */ @@ -6038,11 +6049,11 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject arg_name = _PyUnicode_AsString(key); found = false; - if (arg_name == NULL) { /* unlikely the argname is not a string but ignore if it is*/ + if (arg_name == NULL) { /* Unlikely the argname is not a string, but ignore if it is. */ PyErr_Clear(); } else { - /* Search for arg_name */ + /* Search for arg_name. */ RNA_parameter_list_begin(&parms, &iter); for (; iter.valid; RNA_parameter_list_next(&iter)) { parm = iter.parm; @@ -6061,7 +6072,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject } } - /* list good args */ + /* List good args. */ first = true; RNA_parameter_list_begin(&parms, &iter); @@ -6097,7 +6108,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject ret = NULL; if (err == 0) { - /* call function */ + /* Call function. */ ReportList reports; bContext *C = BPy_GetContext(); @@ -6106,12 +6117,12 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true)); - /* return value */ + /* Return value. */ if (err != -1) { if (ret_len > 0) { if (ret_len > 1) { ret = PyTuple_New(ret_len); - i = 0; /* arg index */ + i = 0; /* Arg index. */ RNA_parameter_list_begin(&parms, &iter); @@ -6129,7 +6140,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject ret = pyrna_param_to_py(&funcptr, pret_single, retdata_single); } - /* possible there is an error in conversion */ + /* Possible there is an error in conversion. */ if (ret == NULL) { err = -1; } @@ -6150,7 +6161,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject # undef DEBUG_STRING_FREE #endif - /* cleanup */ + /* Cleanup. */ RNA_parameter_list_end(&iter); RNA_parameter_list_free(&parms); @@ -6183,7 +6194,7 @@ static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *UNUSED(closure) return ret; } -/* subclasses of pyrna_struct_Type which support idprop definitions use this as a metaclass */ +/* Subclasses of pyrna_struct_Type which support idprop definitions use this as a metaclass. */ /* note: tp_base member is set to &PyType_Type on init */ PyTypeObject pyrna_struct_meta_idprop_Type = { PyVarObject_HEAD_INIT(NULL, 0) "bpy_struct_meta_idprop", /* tp_name */ @@ -6198,7 +6209,7 @@ PyTypeObject pyrna_struct_meta_idprop_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, - /* tp_compare */ /* deprecated in python 3.0! */ + /* tp_compare */ /* deprecated in Python 3.0! */ NULL, /* tp_repr */ /* Method suites for standard classes */ @@ -6279,7 +6290,7 @@ PyTypeObject pyrna_struct_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, - /* tp_compare */ /* DEPRECATED in python 3.0! */ + /* tp_compare */ /* DEPRECATED in Python 3.0! */ (reprfunc)pyrna_struct_repr, /* tp_repr */ /* Method suites for standard classes */ @@ -6368,7 +6379,7 @@ PyTypeObject pyrna_prop_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, - /* tp_compare */ /* DEPRECATED in python 3.0! */ + /* tp_compare */ /* DEPRECATED in Python 3.0! */ (reprfunc)pyrna_prop_repr, /* tp_repr */ /* Method suites for standard classes */ @@ -6452,7 +6463,7 @@ PyTypeObject pyrna_prop_array_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, - /* tp_compare */ /* DEPRECATED in python 3.0! */ + /* tp_compare */ /* DEPRECATED in Python 3.0! */ (reprfunc)pyrna_prop_array_repr, /* tp_repr */ /* Method suites for standard classes */ @@ -6535,7 +6546,7 @@ PyTypeObject pyrna_prop_collection_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, - /* tp_compare */ /* DEPRECATED in python 3.0! */ + /* tp_compare */ /* DEPRECATED in Python 3.0! */ NULL, /* subclassed */ /* tp_repr */ @@ -6621,7 +6632,7 @@ static PyTypeObject pyrna_prop_collection_idprop_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, - /* tp_compare */ /* DEPRECATED in python 3.0! */ + /* tp_compare */ /* DEPRECATED in Python 3.0! */ NULL, /* subclassed */ /* tp_repr */ @@ -6707,7 +6718,7 @@ PyTypeObject pyrna_func_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, - /* tp_compare */ /* DEPRECATED in python 3.0! */ + /* tp_compare */ /* DEPRECATED in Python 3.0! */ (reprfunc)pyrna_func_repr, /* tp_repr */ /* Method suites for standard classes */ @@ -6783,7 +6794,7 @@ PyTypeObject pyrna_func_Type = { #ifdef USE_PYRNA_ITER /* --- collection iterator: start --- */ -/* wrap rna collection iterator functions */ +/* wrap RNA collection iterator functions */ /* * RNA_property_collection_begin(...) * RNA_property_collection_next(...) @@ -6803,7 +6814,7 @@ static PyTypeObject pyrna_prop_collection_iter_Type = { NULL, /* getattrfunc tp_getattr; */ NULL, /* setattrfunc tp_setattr; */ NULL, - /* tp_compare */ /* DEPRECATED in python 3.0! */ + /* tp_compare */ /* DEPRECATED in Python 3.0! */ NULL, /* subclassed */ /* tp_repr */ @@ -6914,7 +6925,7 @@ static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA * BPy_StructRNA *pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&self->iter.ptr); # ifdef USE_PYRNA_STRUCT_REFERENCE - if (pyrna) { /* unlikely but may fail */ + if (pyrna) { /* Unlikely, but may fail. */ if ((PyObject *)pyrna != Py_None) { /* hold a reference to the iterator since it may have * allocated memory 'pyrna' needs. eg: introspecting dynamic enum's */ @@ -6962,18 +6973,19 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) RNA_struct_py_type_set(srna, (void *)newclass); /* Store for later use */ - /* Not 100% needed but useful, - * having an instance within a type looks wrong however this instance IS an rna type */ + /* Not 100% needed, but useful, + * having an instance within a type looks wrong, but this instance _is_ an RNA type. */ - /* python deals with the circular ref */ + /* Python deals with the circular reference. */ RNA_pointer_create(NULL, &RNA_Struct, srna, &ptr); item = pyrna_struct_CreatePyObject(&ptr); - /* note, must set the class not the __dict__ else the internal slots are not updated correctly */ + /* Note, must set the class not the __dict__ else the internal slots are not updated correctly. + */ PyObject_SetAttr(newclass, bpy_intern_str_bl_rna, item); Py_DECREF(item); - /* add staticmethods and classmethods */ + /* Add staticmethods and classmethods. */ { const PointerRNA func_ptr = {{NULL}, srna, NULL}; const ListBase *lb; @@ -6983,10 +6995,10 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) for (link = lb->first; link; link = link->next) { FunctionRNA *func = (FunctionRNA *)link; const int flag = RNA_function_flag(func); - if ((flag & FUNC_NO_SELF) && /* is staticmethod or classmethod */ - (flag & FUNC_REGISTER) == false) /* is not for registration */ + if ((flag & FUNC_NO_SELF) && /* Is staticmethod or classmethod. */ + (flag & FUNC_REGISTER) == false) /* Is not for registration. */ { - /* we may want to set the type of this later */ + /* We may want to set the type of this later. */ PyObject *func_py = pyrna_func_to_py(&func_ptr, func); PyObject_SetAttrString(newclass, RNA_function_identifier(func), func_py); Py_DECREF(func_py); @@ -6994,26 +7006,26 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) } } - /* done with rna instance */ + /* Done with RNA instance. */ } static PyObject *pyrna_srna_Subtype(StructRNA *srna); -/* return a borrowed reference */ +/* Return a borrowed reference. */ static PyObject *pyrna_srna_PyBase(StructRNA *srna) //, PyObject *bpy_types_dict) { - /* Assume RNA_struct_py_type_get(srna) was already checked */ + /* Assume RNA_struct_py_type_get(srna) was already checked. */ StructRNA *base; PyObject *py_base = NULL; - /* get the base type */ + /* Get the base type. */ base = RNA_struct_base(srna); if (base && base != srna) { - /* printf("debug subtype %s %p\n", RNA_struct_identifier(srna), srna); */ + // printf("debug subtype %s %p\n", RNA_struct_identifier(srna), srna); py_base = pyrna_srna_Subtype(base); //, bpy_types_dict); - Py_DECREF(py_base); /* srna owns, this is only to pass as an arg */ + Py_DECREF(py_base); /* Srna owns, this is only to pass as an arg. */ } if (py_base == NULL) { @@ -7023,8 +7035,8 @@ static PyObject *pyrna_srna_PyBase(StructRNA *srna) //, PyObject *bpy_types_dic return py_base; } -/* check if we have a native python subclass, use it when it exists - * return a borrowed reference */ +/* Check if we have a native Python subclass, use it when it exists + * return a borrowed reference. */ static PyObject *bpy_types_dict = NULL; static PyObject *pyrna_srna_ExternalType(StructRNA *srna) @@ -7041,18 +7053,18 @@ static PyObject *pyrna_srna_ExternalType(StructRNA *srna) CLOG_ERROR(BPY_LOG_RNA, "failed to find 'bpy_types' module"); return NULL; } - bpy_types_dict = PyModule_GetDict(bpy_types); /* borrow */ - Py_DECREF(bpy_types); /* fairly safe to assume the dict is kept */ + bpy_types_dict = PyModule_GetDict(bpy_types); /* Borrow. */ + Py_DECREF(bpy_types); /* Fairly safe to assume the dict is kept. */ } newclass = PyDict_GetItemString(bpy_types_dict, idname); - /* sanity check, could skip this unless in debug mode */ + /* Sanity check, could skip this unless in debug mode. */ if (newclass) { PyObject *base_compare = pyrna_srna_PyBase(srna); /* Can't do this because it gets superclasses values! */ // PyObject *slots = PyObject_GetAttrString(newclass, "__slots__"); - /* Can do this but faster not to. */ + /* Can do this, but faster not to. */ // PyObject *bases = PyObject_GetAttrString(newclass, "__bases__"); PyObject *tp_bases = ((PyTypeObject *)newclass)->tp_bases; PyObject *tp_slots = PyDict_GetItem(((PyTypeObject *)newclass)->tp_dict, @@ -7088,18 +7100,18 @@ static PyObject *pyrna_srna_Subtype(StructRNA *srna) { PyObject *newclass = NULL; - /* stupid/simple case */ + /* Stupid/simple case. */ if (srna == NULL) { - newclass = NULL; /* Nothing to do */ - } /* the class may have already been declared & allocated */ + newclass = NULL; /* Nothing to do. */ + } /* The class may have already been declared & allocated. */ else if ((newclass = RNA_struct_py_type_get(srna))) { Py_INCREF(newclass); - } /* check if bpy_types.py module has the class defined in it */ + } /* Check if bpy_types.py module has the class defined in it. */ else if ((newclass = pyrna_srna_ExternalType(srna))) { pyrna_subtype_set_rna(newclass, srna); Py_INCREF(newclass); } /* create a new class instance with the C api - * mainly for the purposing of matching the C/rna type hierarchy */ + * mainly for the purposing of matching the C/RNA type hierarchy */ else { /* subclass equivalents * - class myClass(myBase): @@ -7110,12 +7122,12 @@ static PyObject *pyrna_srna_Subtype(StructRNA *srna) * ) */ - /* Assume RNA_struct_py_type_get(srna) was already checked */ + /* Assume RNA_struct_py_type_get(srna) was already checked. */ PyObject *py_base = pyrna_srna_PyBase(srna); PyObject *metaclass; const char *idname = RNA_struct_identifier(srna); - /* remove __doc__ for now */ + /* Remove __doc__ for now. */ // const char *descr = RNA_struct_ui_description(srna); // if (!descr) descr = "(no docs)"; // "__doc__", descr @@ -7128,13 +7140,13 @@ static PyObject *pyrna_srna_Subtype(StructRNA *srna) metaclass = (PyObject *)&PyType_Type; } - /* always use O not N when calling, N causes refcount errors */ + /* Always use O not N when calling, N causes refcount errors. */ #if 0 newclass = PyObject_CallFunction( metaclass, "s(O) {sss()}", idname, py_base, "__module__", "bpy.types", "__slots__"); #else { - /* longhand of the call above */ + /* Longhand of the call above. */ PyObject *args, *item, *value; int ok; @@ -7168,14 +7180,14 @@ static PyObject *pyrna_srna_Subtype(StructRNA *srna) /* PyC_ObSpit("new class ref", newclass); */ if (newclass) { - /* srna owns one, and the other is owned by the caller */ + /* srna owns one, and the other is owned by the caller. */ pyrna_subtype_set_rna(newclass, srna); - /* XXX, adding this back segfaults blender on load. */ + /* XXX, adding this back segfaults Blender on load. */ // Py_DECREF(newclass); /* let srna own */ } else { - /* this should not happen */ + /* This should not happen. */ CLOG_ERROR(BPY_LOG_RNA, "failed to register '%s'", idname); PyErr_Print(); PyErr_Clear(); @@ -7185,7 +7197,7 @@ static PyObject *pyrna_srna_Subtype(StructRNA *srna) return newclass; } -/* use for subtyping so we know which srna is used for a PointerRNA */ +/* Use for subtyping so we know which srna is used for a PointerRNA. */ static StructRNA *srna_from_ptr(PointerRNA *ptr) { if (ptr->type == &RNA_Struct) { @@ -7196,7 +7208,7 @@ static StructRNA *srna_from_ptr(PointerRNA *ptr) } } -/* always returns a new ref, be sure to decref when done */ +/* Always returns a new ref, be sure to decref when done. */ static PyObject *pyrna_struct_Subtype(PointerRNA *ptr) { return pyrna_srna_Subtype(srna_from_ptr(ptr)); @@ -7207,8 +7219,8 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) { BPy_StructRNA *pyrna = NULL; - /* note: don't rely on this to return None since NULL data with a valid type can often crash */ - if (ptr->data == NULL && ptr->type == NULL) { /* Operator RNA has NULL data */ + /* Note: don't rely on this to return None since NULL data with a valid type can often crash. */ + if (ptr->data == NULL && ptr->type == NULL) { /* Operator RNA has NULL data. */ Py_RETURN_NONE; } @@ -7227,8 +7239,8 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) /* Existing users will need to use 'type_recast' method. */ Py_DECREF(pyrna); *instance = NULL; - /* Continue as if no instance was made */ -#if 0 /* no need to assign, will be written to next... */ + /* Continue as if no instance was made. */ +#if 0 /* No need to assign, will be written to next... */ pyrna = NULL; #endif } @@ -7239,7 +7251,7 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) if (tp) { pyrna = (BPy_StructRNA *)tp->tp_alloc(tp, 0); - Py_DECREF(tp); /* srna owns, cant hold a ref */ + Py_DECREF(tp); /* srna owns, can't hold a reference. */ } else { CLOG_WARN(BPY_LOG_RNA, "could not make type '%s'", RNA_struct_identifier(ptr->type)); @@ -7330,7 +7342,7 @@ PyObject *pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop) return (PyObject *)pyrna; } -/* utility func to be used by external modules, *sneaky!* */ +/* Utility func to be used by external modules, sneaky! */ PyObject *pyrna_id_CreatePyObject(ID *id) { if (id) { @@ -7362,12 +7374,12 @@ bool pyrna_id_CheckPyObject(PyObject *obj) void BPY_rna_init(void) { -#ifdef USE_MATHUTILS /* register mathutils callbacks, ok to run more than once. */ +#ifdef USE_MATHUTILS /* Register mathutils callbacks, ok to run more than once. */ mathutils_rna_array_cb_index = Mathutils_RegisterCallback(&mathutils_rna_array_cb); mathutils_rna_matrix_cb_index = Mathutils_RegisterCallback(&mathutils_rna_matrix_cb); #endif - /* for some reason MSVC complains of these */ + /* For some reason MSVC complains of these. */ #if defined(_MSC_VER) pyrna_struct_meta_idprop_Type.tp_base = &PyType_Type; @@ -7411,14 +7423,14 @@ void BPY_rna_init(void) #endif } -/* bpy.data from python */ +/* 'bpy.data' from Python. */ static PointerRNA *rna_module_ptr = NULL; PyObject *BPY_rna_module(void) { BPy_StructRNA *pyrna; PointerRNA ptr; - /* for now, return the base RNA type rather than a real module */ + /* For now, return the base RNA type rather than a real module. */ RNA_main_pointer_create(G_MAIN, &ptr); pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); @@ -7432,7 +7444,7 @@ void BPY_update_rna_module(void) #if 0 RNA_main_pointer_create(G_MAIN, rna_module_ptr); #else - rna_module_ptr->data = G_MAIN; /* just set data is enough */ + rna_module_ptr->data = G_MAIN; /* Just set data is enough. */ #endif } } @@ -7444,7 +7456,7 @@ PyObject *BPY_rna_doc(void) { PointerRNA ptr; - /* for now, return the base RNA type rather than a real module */ + /* For now, return the base RNA type rather than a real module. */ RNA_blender_rna_pointer_create(&ptr); return pyrna_struct_CreatePyObject(&ptr); @@ -7479,7 +7491,7 @@ static PyObject *pyrna_basetype_getattro(BPy_BaseTypeRNA *self, PyObject *pyname _PyUnicode_AsString(pyname)); return NULL; #endif - /* The error raised here will be displayed */ + /* The error raised here will be displayed. */ ret = PyObject_GenericGetAttr((PyObject *)self, pyname); } @@ -7495,7 +7507,7 @@ static struct PyMethodDef pyrna_basetype_methods[] = { {NULL, NULL, 0, NULL}, }; -/* used to call ..._keys() direct, but we need to filter out operator subclasses */ +/* Used to call ..._keys() direct, but we need to filter out operator subclasses. */ #if 0 static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self) { @@ -7504,9 +7516,9 @@ static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self) PyMethodDef *meth; # endif - list = pyrna_prop_collection_keys(self); /* like calling structs.keys(), avoids looping here */ + list = pyrna_prop_collection_keys(self); /* Like calling structs.keys(), avoids looping here. */ -# if 0 /* for now only contains __dir__ */ +# if 0 /* For now only contains __dir__. */ for (meth = pyrna_basetype_methods; meth->ml_name; meth++) { PyList_APPEND(list, PyUnicode_FromString(meth->ml_name)); } @@ -7552,11 +7564,11 @@ PyObject *BPY_rna_types(void) } } - /* static members for the base class */ - /* add __name__ since help() expects its */ + /* Static members for the base class. */ + /* Add __name__ since help() expects it. */ PyDict_SetItem(pyrna_basetype_Type.tp_dict, bpy_intern_str___name__, bpy_intern_str_bpy_types); - /* internal base types we have no other accessors for */ + /* Internal base types we have no other accessors for. */ { PyTypeObject *pyrna_types[] = { &pyrna_struct_meta_idprop_Type, @@ -7575,7 +7587,7 @@ PyObject *BPY_rna_types(void) self = (BPy_BaseTypeRNA *)PyObject_NEW(BPy_BaseTypeRNA, &pyrna_basetype_Type); - /* avoid doing this lookup for every getattr */ + /* Avoid doing this lookup for every getattr. */ RNA_blender_rna_pointer_create(&self->ptr); self->prop = RNA_struct_find_property(&self->ptr, "structs"); #ifdef USE_WEAKREFS @@ -7589,7 +7601,7 @@ StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *e BPy_StructRNA *py_srna = NULL; StructRNA *srna; - /* ack, PyObject_GetAttrString wont look up this types tp_dict first :/ */ + /* Unfortunately PyObject_GetAttrString wont look up this types tp_dict first :/ */ if (PyType_Check(self)) { py_srna = (BPy_StructRNA *)PyDict_GetItem(((PyTypeObject *)self)->tp_dict, bpy_intern_str_bl_rna); @@ -7637,8 +7649,8 @@ StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *e return srna; } -/* Orphan functions, not sure where they should go */ -/* get the srna for methods attached to types */ +/* Orphan functions, not sure where they should go. */ +/* Get the srna for methods attached to types. */ /* * Caller needs to raise error.*/ StructRNA *srna_from_self(PyObject *self, const char *error_prefix) @@ -7694,7 +7706,7 @@ static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item } py_srna_cobject = PyCapsule_New(srna, NULL, NULL); - /* not 100% nice :/, modifies the dict passed, should be ok */ + /* Not 100% nice :/, modifies the dict passed, should be ok. */ PyDict_SetItem(py_kw, bpy_intern_str_attr, key); args_fake = PyTuple_New(1); @@ -7719,14 +7731,14 @@ static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item if (py_ret) { Py_DECREF(py_ret); - Py_DECREF(args_fake); /* free's py_srna_cobject too */ + Py_DECREF(args_fake); /* Free's py_srna_cobject too. */ } else { - /* _must_ print before decreffing args_fake */ + /* _must_ print before decreffing args_fake. */ PyErr_Print(); PyErr_Clear(); - Py_DECREF(args_fake); /* free's py_srna_cobject too */ + Py_DECREF(args_fake); /* Free's py_srna_cobject too. */ // PyC_LineSpit(); PyErr_Format(PyExc_ValueError, @@ -7738,9 +7750,9 @@ static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item } } else { - /* Since this is a class dict, ignore args that can't be passed */ + /* Since this is a class dict, ignore args that can't be passed. */ - /* for testing only */ + /* For testing only. */ #if 0 PyC_ObSpit("Why doesn't this work??", item); PyErr_Print(); @@ -7780,12 +7792,12 @@ static int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict) if (!has_warning) { printf( "Warning: class %.200s " - "contains a properties which should be an annotation!\n", + "contains a property which should be an annotation!\n", RNA_struct_identifier(srna)); PyC_LineSpit(); has_warning = true; } - printf(" make annotation: %.200s.%.200s\n", + printf(" assign as a type annotation: %.200s.%.200s\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key)); } @@ -7805,7 +7817,7 @@ static int pyrna_deferred_register_class_recursive(StructRNA *srna, PyTypeObject const int len = PyTuple_GET_SIZE(py_class->tp_bases); int i, ret; - /* first scan base classes for registerable properties */ + /* First scan base classes for registerable properties. */ for (i = 0; i < len; i++) { PyTypeObject *py_superclass = (PyTypeObject *)PyTuple_GET_ITEM(py_class->tp_bases, i); @@ -7813,7 +7825,7 @@ static int pyrna_deferred_register_class_recursive(StructRNA *srna, PyTypeObject * 'object' is of course not worth looking into and * existing subclasses of RNA would cause a lot more dictionary * looping then is needed (SomeOperator would scan Operator.__dict__) - * which is harmless but not at all useful. + * which is harmless, but not at all useful. * * So only scan base classes which are not subclasses if blender types. * This best fits having 'mix-in' classes for operators and render engines. @@ -7828,9 +7840,9 @@ static int pyrna_deferred_register_class_recursive(StructRNA *srna, PyTypeObject } } - /* not register out own properties */ - return pyrna_deferred_register_props( - srna, py_class->tp_dict); /* getattr(..., "__dict__") returns a proxy */ + /* Not register out own properties. */ + /* getattr(..., "__dict__") returns a proxy. */ + return pyrna_deferred_register_props(srna, py_class->tp_dict); } int pyrna_deferred_register_class(StructRNA *srna, PyTypeObject *py_class) @@ -7860,7 +7872,7 @@ static int rna_function_arg_count(FunctionRNA *func, int *min_count) parm = (PropertyRNA *)link; if (!(RNA_parameter_flag(parm) & PARM_OUTPUT)) { if (!done_min_count && (RNA_parameter_flag(parm) & PARM_PYFUNC_OPTIONAL)) { - /* From now on, following parameters are optional in py func */ + /* From now on, the following parameters are optional in a Python function. */ if (min_count) { *min_count = count; } @@ -7907,7 +7919,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, } } - /* verify callback functions */ + /* Verify callback functions. */ lb = RNA_struct_type_functions(srna); i = 0; for (link = lb->first; link; link = link->next) { @@ -7915,7 +7927,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, const int flag = RNA_function_flag(func); /* TODO(campbell): this is used for classmethod's too, * even though class methods should have 'FUNC_USE_SELF_TYPE' set, see Operator.poll for eg. - * Keep this as-is since its working but we should be using + * Keep this as-is since it's working, but we should be using * 'FUNC_USE_SELF_TYPE' for many functions. */ const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE); @@ -7941,7 +7953,8 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, PyErr_Clear(); } else { - /* No need to keep a ref, the class owns it (technically we should keep a ref but...). */ + /* No need to keep a ref, the class owns it + * (technically we should keep a reference, but...). */ Py_DECREF(item); if (is_staticmethod) { @@ -7972,11 +7985,11 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, func_arg_count = rna_function_arg_count(func, &func_arg_min_count); - if (func_arg_count >= 0) { /* -1 if we don't care*/ + if (func_arg_count >= 0) { /* -1 if we don't care. */ arg_count = ((PyCodeObject *)PyFunction_GET_CODE(item))->co_argcount; /* note, the number of args we check for and the number of args we give to - * '@staticmethods' are different (quirk of python), + * '@staticmethods' are different (quirk of Python), * this is why rna_function_arg_count() doesn't return the value -1*/ if (is_staticmethod) { func_arg_count++; @@ -8012,7 +8025,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, } } - /* verify properties */ + /* Verify properties. */ lb = RNA_struct_type_properties(srna); for (link = lb->first; link; link = link->next) { const char *identifier; @@ -8029,7 +8042,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, if (item == NULL) { PyErr_Clear(); - /* Sneaky workaround to use the class name as the bl_idname */ + /* Sneaky workaround to use the class name as the bl_idname. */ #define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \ else if (STREQ(identifier, rna_attr)) \ @@ -8046,10 +8059,10 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, else { \ PyErr_Clear(); \ } \ - } /* intentionally allow else here */ + } /* Intentionally allow else here. */ if (false) { - } /* needed for macro */ + } /* Needed for macro. */ BPY_REPLACEMENT_STRING("bl_idname", bpy_intern_str___name__) BPY_REPLACEMENT_STRING("bl_description", bpy_intern_str___doc__) @@ -8083,7 +8096,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun return bpy_class_validate_recursive(dummyptr, dummyptr->type, py_data, have_function); } -/* TODO - multiple return values like with rna functions */ +/* TODO - multiple return values like with RNA functions. */ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms) { PyObject *args; @@ -8106,33 +8119,33 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param const bool is_readonly_init = !(RNA_struct_is_a(ptr->type, &RNA_Operator) || RNA_struct_is_a(ptr->type, &RNA_Gizmo)); // const char *func_id = RNA_function_identifier(func); /* UNUSED */ - /* testing, for correctness, not operator and not draw function */ + /* Testing, for correctness, not operator and not draw function. */ const bool is_readonly = !(RNA_function_flag(func) & FUNC_ALLOW_WRITE); #endif py_class = RNA_struct_py_type_get(ptr->type); - /* rare case. can happen when registering subclasses */ + /* Rare case. can happen when registering subclasses. */ if (py_class == NULL) { CLOG_WARN(BPY_LOG_RNA, - "unable to get Python class for rna struct '%.200s'", + "unable to get Python class for RNA struct '%.200s'", RNA_struct_identifier(ptr->type)); return -1; } /* XXX, this is needed because render engine calls without a context - * this should be supported at some point but at the moment its not! */ + * this should be supported at some point, but at the moment it's not! */ if (C == NULL) { C = BPy_GetContext(); } - /* annoying!, need to check if the screen gets set to NULL which is a + /* Annoying! We need to check if the screen gets set to NULL which is a * hint that the file was actually re-loaded. */ const bool is_valid_wm = (CTX_wm_manager(C) != NULL); bpy_context_set(C, &gilstate); if (!(is_staticmethod || is_classmethod)) { - /* some datatypes (operator, render engine) can store PyObjects for re-use */ + /* Some datatypes (operator, render engine) can store PyObjects for re-use. */ if (ptr->data) { void **instance = RNA_struct_instance(ptr); @@ -8143,19 +8156,19 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param } } } - /* end exception */ + /* End exception. */ if (py_class_instance == NULL) { py_srna = pyrna_struct_CreatePyObject(ptr); } if (py_class_instance) { - /* special case, instance is cached */ + /* Special case, instance is cached. */ } else if (py_srna == NULL) { py_class_instance = NULL; } - else if (py_srna == Py_None) { /* probably wont ever happen but possible */ + else if (py_srna == Py_None) { /* Probably wont ever happen, but possible. */ Py_DECREF(py_srna); py_class_instance = NULL; } @@ -8163,21 +8176,22 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param #if 1 /* Skip the code below and call init directly on the allocated 'py_srna' * otherwise __init__() always needs to take a second self argument, see pyrna_struct_new(). - * Although this is annoying to have to implement a part of pythons typeobject.c:type_call(). + * Although this is annoying to have to implement a part of Python's + * typeobject.c:type_call(). */ if (py_class->tp_init) { # ifdef USE_PEDANTIC_WRITE const int prev_write = rna_disallow_writes; rna_disallow_writes = is_readonly_init ? false : - true; /* only operators can write on __init__ */ + true; /* Only operators can write on __init__. */ # endif - /* true in most cases even when the class its self doesn't define an __init__ function. */ + /* True in most cases even when the class itself doesn't define an __init__ function. */ args = PyTuple_New(0); if (py_class->tp_init(py_srna, args, NULL) < 0) { Py_DECREF(py_srna); py_srna = NULL; - /* err set below */ + /* Err set below. */ } Py_DECREF(args); # ifdef USE_PEDANTIC_WRITE @@ -8197,8 +8211,8 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param Py_INCREF(py_class_instance); # endif /* - * This would work fine but means __init__ functions wouldn't run. - * none of blenders default scripts use __init__ but its nice to call it + * This would work fine, but means __init__ functions wouldn't run. + * None of Blender's default scripts use __init__ but it's nice to call it * for general correctness. just to note why this is here when it could be safely removed. */ args = PyTuple_New(1); @@ -8211,12 +8225,12 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param #endif if (py_class_instance == NULL) { - err = -1; /* so the error is not overridden below */ + err = -1; /* So the error is not overridden below. */ } } } - /* Initializing the class worked, now run its invoke function */ + /* Initializing the class worked, now run its invoke function. */ if (err != -1 && (is_staticmethod || is_classmethod || py_class_instance)) { PyObject *item = PyObject_GetAttrString((PyObject *)py_class, RNA_function_identifier(func)); @@ -8235,7 +8249,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param /* First arg is included in 'item'. */ args = PyTuple_New(rna_function_arg_count(func)); #endif - args = PyTuple_New(arg_count); /* first arg is included in 'item' */ + args = PyTuple_New(arg_count); /* First arg is included in 'item'. */ if (is_staticmethod) { i = 0; @@ -8251,11 +8265,11 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param RNA_parameter_list_begin(parms, &iter); - /* parse function parameters */ + /* Parse function parameters. */ for (; iter.valid; RNA_parameter_list_next(&iter)) { parm = iter.parm; - /* only useful for single argument returns, we'll need another list loop for multiple */ + /* Only useful for single argument returns, we'll need another list loop for multiple. */ if (RNA_parameter_flag(parm) & PARM_OUTPUT) { ret_len++; if (pret_single == NULL) { @@ -8301,7 +8315,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param } } else { - /* the error may be already set if the class instance couldn't be created */ + /* The error may be already set if the class instance couldn't be created. */ if (err != -1) { PyErr_Format(PyExc_RuntimeError, "could not create instance of %.200s to call callback function %.200s", @@ -8311,7 +8325,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param } } - if (ret == NULL) { /* covers py_class_instance failing too */ + if (ret == NULL) { /* Covers py_class_instance failing too. */ err = -1; } else { @@ -8362,11 +8376,11 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param RNA_parameter_list_begin(parms, &iter); - /* parse function parameters */ + /* Parse function parameters. */ for (i = 0; iter.valid; RNA_parameter_list_next(&iter)) { parm = iter.parm; - /* only useful for single argument returns, we'll need another list loop for multiple */ + /* Only useful for single argument returns, we'll need another list loop for multiple. */ if (RNA_parameter_flag(parm) & PARM_OUTPUT) { err = pyrna_py_to_prop( &funcptr, parm, iter.data, PyTuple_GET_ITEM(ret, i++), "calling class function:"); @@ -8384,7 +8398,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param if (err != 0) { ReportList *reports; - /* alert the user, else they wont know unless they see the console. */ + /* Alert the user, else they wont know unless they see the console. */ if ((!is_staticmethod) && (!is_classmethod) && (ptr->data) && (RNA_struct_is_a(ptr->type, &RNA_Operator)) && (is_valid_wm == (CTX_wm_manager(C) != NULL))) { @@ -8392,13 +8406,13 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param reports = op->reports; } else { - /* wont alert users but they can view in 'info' space */ + /* Wont alert users, but they can view in 'info' space. */ reports = CTX_wm_reports(C); } BPy_errors_to_report(reports); - /* also print in the console for py */ + /* Also print in the console for Python. */ PyErr_Print(); PyErr_Clear(); } @@ -8415,19 +8429,19 @@ static void bpy_class_free(void *pyob_ptr) gilstate = PyGILState_Ensure(); - /* breaks re-registering classes */ + /* Breaks re-registering classes. */ // PyDict_Clear(((PyTypeObject *)self)->tp_dict); - /* remove the rna attribute instead. */ + /* Remove the RNA attribute instead. */ PyDict_DelItem(((PyTypeObject *)self)->tp_dict, bpy_intern_str_bl_rna); if (PyErr_Occurred()) { PyErr_Clear(); } -#if 0 /* needs further investigation, too annoying so quiet for now */ +#if 0 /* Needs further investigation, too annoying so quiet for now. */ if (G.debug & G_DEBUG_PYTHON) { if (self->ob_refcnt > 1) { - PyC_ObSpit("zombie class - ref should be 1", self); + PyC_ObSpit("zombie class - reference should be 1", self); } } #endif @@ -8451,7 +8465,7 @@ void pyrna_alloc_types(void) gilstate = PyGILState_Ensure(); - /* avoid doing this lookup for every getattr */ + /* Avoid doing this lookup for every getattr. */ RNA_blender_rna_pointer_create(&ptr); prop = RNA_struct_find_property(&ptr, "structs"); @@ -8478,7 +8492,7 @@ void pyrna_free_types(void) PointerRNA ptr; PropertyRNA *prop; - /* avoid doing this lookup for every getattr */ + /* Avoid doing this lookup for every getattr. */ RNA_blender_rna_pointer_create(&ptr); prop = RNA_struct_find_property(&ptr, "structs"); @@ -8487,7 +8501,7 @@ void pyrna_free_types(void) void *py_ptr = RNA_struct_py_type_get(srna); if (py_ptr) { -#if 0 /* XXX - should be able to do this but makes python crash on exit */ +#if 0 /* XXX - should be able to do this, but makes Python crash on exit. */ bpy_class_free(py_ptr); #endif RNA_struct_py_type_set(srna, NULL); @@ -8498,9 +8512,9 @@ void pyrna_free_types(void) /* Note! MemLeak XXX * - * There is currently a bug where moving registering a python class does - * not properly manage refcounts from the python class, since the srna owns - * the python class this should not be so tricky but changing the references as + * There is currently a bug where moving the registration of a Python class does + * not properly manage reference-counts from the Python class. As the srna owns + * the Python class this should not be so tricky, but changing the references as * you'd expect when changing ownership crashes blender on exit so I had to comment out * the decref. This is not so bad because the leak only happens when re-registering (hold F8) * - Should still be fixed - Campbell @@ -8557,13 +8571,13 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class return NULL; } - /* warning: gets parent classes srna, only for the register function */ + /* Warning: gets parent classes srna, only for the register function. */ srna = pyrna_struct_as_srna(py_class, true, "register_class(...):"); if (srna == NULL) { return NULL; } - /* fails in cases, cant use this check but would like to :| */ + /* Fails in some cases, so can't use this check, but would like to :| */ #if 0 if (RNA_struct_py_type_get(srna)) { PyErr_Format(PyExc_ValueError, @@ -8575,21 +8589,21 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class } #endif - /* check that we have a register callback for this type */ + /* Check that we have a register callback for this type. */ reg = RNA_struct_register(srna); if (!reg) { PyErr_Format(PyExc_ValueError, "register_class(...): expected a subclass of a registerable " - "rna type (%.200s does not support registration)", + "RNA type (%.200s does not support registration)", RNA_struct_identifier(srna)); return NULL; } - /* get the context, so register callback can do necessary refreshes */ + /* Get the context, so register callback can do necessary refreshes. */ C = BPy_GetContext(); - /* call the register callback with reports & identifier */ + /* Call the register callback with reports & identifier. */ BKE_reports_init(&reports, RPT_STORE); identifier = ((PyTypeObject *)py_class)->tp_name; @@ -8613,18 +8627,19 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class } } - /* python errors validating are not converted into reports so the check above will fail. + /* Python errors validating are not converted into reports so the check above will fail. * the cause for returning NULL will be printed as an error */ if (srna_new == NULL) { return NULL; } - pyrna_subtype_set_rna(py_class, srna_new); /* takes a ref to py_class */ + /* Takes a reference to 'py_class'. */ + pyrna_subtype_set_rna(py_class, srna_new); - /* old srna still references us, keep the check in case registering somehow can free it */ + /* Old srna still references us, keep the check in case registering somehow can free it. */ if (RNA_struct_py_type_get(srna)) { RNA_struct_py_type_set(srna, NULL); - // Py_DECREF(py_class); // should be able to do this XXX since the old rna adds a new ref. + // Py_DECREF(py_class); /* Should be able to do this XXX since the old RNA adds a new ref. */ } /* Can't use this because it returns a dict proxy @@ -8635,7 +8650,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class return NULL; } - /* call classed register method () */ + /* Call classed register method. */ switch (_PyObject_LookupAttr(py_class, bpy_intern_str_register, &py_cls_meth)) { case 1: { PyObject *ret = PyObject_CallObject(py_cls_meth, NULL); @@ -8662,7 +8677,7 @@ static int pyrna_srna_contains_pointer_prop_srna(StructRNA *srna_props, PropertyRNA *prop; LinkData *link; - /* verify properties */ + /* Verify properties. */ const ListBase *lb = RNA_struct_type_properties(srna); for (link = lb->first; link; link = link->next) { @@ -8684,7 +8699,7 @@ static int pyrna_srna_contains_pointer_prop_srna(StructRNA *srna_props, PyDoc_STRVAR(pyrna_unregister_class_doc, ".. method:: unregister_class(cls)\n" "\n" - " Unload the python class from blender.\n" + " Unload the Python class from blender.\n" "\n" " If the class has an *unregister* class method it will be called\n" " before unregistering.\n"); @@ -8730,18 +8745,18 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla return NULL; } - /* check that we have a unregister callback for this type */ + /* Check that we have a unregister callback for this type. */ unreg = RNA_struct_unregister(srna); if (!unreg) { PyErr_SetString( PyExc_ValueError, "unregister_class(...): " - "expected a Type subclassed from a registerable rna type (no unregister supported)"); + "expected a Type subclassed from a registerable RNA type (no unregister supported)"); return NULL; } - /* call classed unregister method */ + /* Call classed unregister method. */ switch (_PyObject_LookupAttr(py_class, bpy_intern_str_unregister, &py_cls_meth)) { case 1: { PyObject *ret = PyObject_CallObject(py_cls_meth, NULL); @@ -8758,9 +8773,9 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla } } - /* should happen all the time but very slow */ + /* Should happen all the time, however it's very slow. */ if (G.debug & G_DEBUG_PYTHON) { - /* remove all properties using this class */ + /* Remove all properties using this class. */ StructRNA *srna_iter; PointerRNA ptr_rna; PropertyRNA *prop_rna; @@ -8769,7 +8784,7 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla RNA_blender_rna_pointer_create(&ptr_rna); prop_rna = RNA_struct_find_property(&ptr_rna, "structs"); - /* loop over all structs */ + /* Loop over all structs. */ RNA_PROP_BEGIN (&ptr_rna, itemptr, prop_rna) { srna_iter = itemptr.data; if (pyrna_srna_contains_pointer_prop_srna(srna_iter, srna, &prop_identifier)) { @@ -8789,11 +8804,11 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla } } - /* get the context, so register callback can do necessary refreshes */ + /* Get the context, so register callback can do necessary refreshes. */ C = BPy_GetContext(); - /* call unregister */ - unreg(CTX_data_main(C), srna); /* calls bpy_class_free, this decref's py_class */ + /* Call unregister. */ + unreg(CTX_data_main(C), srna); /* Calls bpy_class_free, this decref's py_class. */ PyDict_DelItem(((PyTypeObject *)py_class)->tp_dict, bpy_intern_str_bl_rna); if (PyErr_Occurred()) { @@ -8931,7 +8946,7 @@ void BPY_rna_register_cb(void) PyObject_SetAttrString(cls, pyrna_cb_methods[i].py_method.ml_name, classmethod); Py_DECREF(classmethod); - Py_DECREF(args); /* clears 'func' too */ + Py_DECREF(args); /* Clears 'func' too. */ Py_DECREF(cls); } } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index f20bc6b11fe..a95ccd65dff 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -3230,14 +3230,11 @@ void wm_event_do_handlers(bContext *C) } else { Scene *scene = WM_window_get_active_scene(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); + Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, false); + Scene *scene_eval = (depsgraph != NULL) ? DEG_get_evaluated_scene(depsgraph) : NULL; - CTX_wm_window_set(C, win); - CTX_data_scene_set(C, scene); - - Depsgraph *depsgraph = CTX_data_depsgraph(C); - Scene *scene_eval = DEG_get_evaluated_scene_if_exists(depsgraph); - - if (scene_eval) { + if (scene_eval != NULL) { const int is_playing_sound = BKE_sound_scene_playing(scene_eval); if (is_playing_sound != -1) { @@ -3263,10 +3260,6 @@ void wm_event_do_handlers(bContext *C) } } } - - CTX_data_scene_set(C, NULL); - CTX_wm_screen_set(C, NULL); - CTX_wm_window_set(C, NULL); } while ((event = win->queue.first)) { diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 0c525d6946c..fe93e39b085 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -2949,11 +2949,9 @@ static void wm_block_file_close_save(bContext *C, void *arg_block, void *arg_dat UI_popup_block_close(C, win, arg_block); if (save_images_when_file_is_closed) { - ReportList *reports = CTX_wm_reports(C); - if (!ED_image_save_all_modified(C, reports)) { + if (!ED_image_should_save_modified(C)) { execute_callback = false; } - WM_report_banner_show(); } Main *bmain = CTX_data_main(C); @@ -3059,10 +3057,10 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, struct ARegi 0, 0, ""); + } - LISTBASE_FOREACH (Report *, report, &reports.list) { - uiItemL(layout, report->message, ICON_ERROR); - } + LISTBASE_FOREACH (Report *, report, &reports.list) { + uiItemL(layout, report->message, ICON_ERROR); } BKE_reports_clear(&reports); diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index 11f9ef917fd..b79de4370d0 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -215,6 +215,7 @@ static void wm_gesture_draw_line(wmGesture *gt) immUniformArray4fv( "colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2); immUniform1f("dash_width", 8.0f); + immUniform1f("dash_factor", 0.5f); float xmin = (float)rect->xmin; float ymin = (float)rect->ymin; @@ -257,6 +258,7 @@ static void wm_gesture_draw_rect(wmGesture *gt) immUniformArray4fv( "colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2); immUniform1f("dash_width", 8.0f); + immUniform1f("dash_factor", 0.5f); imm_draw_box_wire_2d( shdr_pos, (float)rect->xmin, (float)rect->ymin, (float)rect->xmax, (float)rect->ymax); @@ -295,6 +297,7 @@ static void wm_gesture_draw_circle(wmGesture *gt) immUniformArray4fv( "colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2); immUniform1f("dash_width", 4.0f); + immUniform1f("dash_factor", 0.5f); imm_draw_circle_wire_2d(shdr_pos, (float)rect->xmin, (float)rect->ymin, (float)rect->xmax, 40); @@ -418,6 +421,7 @@ static void wm_gesture_draw_lasso(wmGesture *gt, bool filled) immUniformArray4fv( "colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2); immUniform1f("dash_width", 2.0f); + immUniform1f("dash_factor", 0.5f); immBegin((gt->type == WM_GESTURE_LASSO) ? GPU_PRIM_LINE_LOOP : GPU_PRIM_LINE_STRIP, numverts); @@ -451,6 +455,7 @@ static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt) immUniformArray4fv( "colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2); immUniform1f("dash_width", 8.0f); + immUniform1f("dash_factor", 0.5f); immBegin(GPU_PRIM_LINES, 4); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 842fa5394bd..4cbb56ec289 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1940,6 +1940,10 @@ void wm_window_lower(wmWindow *win) void wm_window_raise(wmWindow *win) { + /* Restore window if minimized */ + if (GHOST_GetWindowState(win->ghostwin) == GHOST_kWindowStateMinimized) { + GHOST_SetWindowState(win->ghostwin, GHOST_kWindowStateNormal); + } GHOST_SetWindowOrder(win->ghostwin, GHOST_kWindowOrderTop); } |