Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/object.c
| Show First 20 Lines • Show All 305 Lines • ▼ Show 20 Lines | static void object_free_data(ID *id) | ||||
| BKE_sculptsession_free(ob); | BKE_sculptsession_free(ob); | ||||
| BLI_freelistN(&ob->pc_ids); | BLI_freelistN(&ob->pc_ids); | ||||
| /* Free runtime curves data. */ | /* Free runtime curves data. */ | ||||
| if (ob->runtime.curve_cache) { | if (ob->runtime.curve_cache) { | ||||
| BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev); | BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev); | ||||
| if (ob->runtime.curve_cache->path) { | if (ob->runtime.curve_cache->anim_path_accum_length) { | ||||
| free_path(ob->runtime.curve_cache->path); | MEM_freeN((void *)ob->runtime.curve_cache->anim_path_accum_length); | ||||
| } | } | ||||
| MEM_freeN(ob->runtime.curve_cache); | MEM_freeN(ob->runtime.curve_cache); | ||||
| ob->runtime.curve_cache = NULL; | ob->runtime.curve_cache = NULL; | ||||
| } | } | ||||
| BKE_previewimg_free(&ob->preview); | BKE_previewimg_free(&ob->preview); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 859 Lines • ▼ Show 20 Lines | void BKE_object_free_softbody(Object *ob) | ||||
| sbFree(ob); | sbFree(ob); | ||||
| } | } | ||||
| void BKE_object_free_curve_cache(Object *ob) | void BKE_object_free_curve_cache(Object *ob) | ||||
| { | { | ||||
| if (ob->runtime.curve_cache) { | if (ob->runtime.curve_cache) { | ||||
| BKE_displist_free(&ob->runtime.curve_cache->disp); | BKE_displist_free(&ob->runtime.curve_cache->disp); | ||||
| BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev); | BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev); | ||||
| if (ob->runtime.curve_cache->path) { | if (ob->runtime.curve_cache->anim_path_accum_length) { | ||||
| free_path(ob->runtime.curve_cache->path); | MEM_freeN((void *)ob->runtime.curve_cache->anim_path_accum_length); | ||||
| } | } | ||||
| BKE_nurbList_free(&ob->runtime.curve_cache->deformed_nurbs); | BKE_nurbList_free(&ob->runtime.curve_cache->deformed_nurbs); | ||||
| MEM_freeN(ob->runtime.curve_cache); | MEM_freeN(ob->runtime.curve_cache); | ||||
| ob->runtime.curve_cache = NULL; | ob->runtime.curve_cache = NULL; | ||||
| } | } | ||||
| } | } | ||||
| void BKE_object_free_modifiers(Object *ob, const int flag) | void BKE_object_free_modifiers(Object *ob, const int flag) | ||||
| ▲ Show 20 Lines • Show All 130 Lines • ▼ Show 20 Lines | bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type) | ||||
| /* Only geometry objects should be able to get modifiers T25291. */ | /* Only geometry objects should be able to get modifiers T25291. */ | ||||
| if (ob->type == OB_HAIR) { | if (ob->type == OB_HAIR) { | ||||
| return (mti->modifyHair != NULL) || (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly); | return (mti->modifyHair != NULL) || (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly); | ||||
| } | } | ||||
| if (ob->type == OB_POINTCLOUD) { | if (ob->type == OB_POINTCLOUD) { | ||||
| return (mti->modifyGeometrySet != NULL); | return (mti->modifyGeometrySet != NULL); | ||||
| } | } | ||||
| if (ob->type == OB_VOLUME) { | if (ob->type == OB_VOLUME) { | ||||
| return (mti->modifyVolume != NULL); | return (mti->modifyVolume != NULL) || (mti->modifyGeometrySet != NULL); | ||||
| } | } | ||||
| if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { | if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { | ||||
| if (ob->type == OB_LATTICE && (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly) == 0) { | if (ob->type == OB_LATTICE && (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly) == 0) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (!((mti->flags & eModifierTypeFlag_AcceptsCVs) || | if (!((mti->flags & eModifierTypeFlag_AcceptsCVs) || | ||||
| (ob->type == OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh)))) { | (ob->type == OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh)))) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| static bool object_modifier_type_copy_check(ModifierType md_type) | static bool object_modifier_type_copy_check(ModifierType md_type) | ||||
| { | { | ||||
| return !ELEM(md_type, eModifierType_Hook, eModifierType_Collision); | return !ELEM(md_type, eModifierType_Hook, eModifierType_Collision); | ||||
| } | } | ||||
| /** Find a `psys` matching given `psys_src` in `ob_dst` (i.e. sharing the same ParticleSettings | /** | ||||
| * ID), or add one, and return valid `psys` from `ob_dst`. | * Find a `psys` matching given `psys_src` in `ob_dst` (i.e. sharing the same ParticleSettings ID), | ||||
| * or add one, and return valid `psys` from `ob_dst`. | |||||
| * | * | ||||
| * \note Order handling is fairly weak here. This code assumes that it is called **before** the | * \note Order handling is fairly weak here. This code assumes that it is called **before** the | ||||
| * modifier using the psys is actually copied, and that this copied modifier will be added at the | * modifier using the psys is actually copied, and that this copied modifier will be added at the | ||||
| * end of the stack. That way we can be sure that the particle modifier will be before the one | * end of the stack. That way we can be sure that the particle modifier will be before the one | ||||
| * using its particle system in the stack. | * using its particle system in the stack. | ||||
| */ | */ | ||||
| static ParticleSystem *object_copy_modifier_particle_system_ensure(Main *bmain, | static ParticleSystem *object_copy_modifier_particle_system_ensure(Main *bmain, | ||||
| Scene *scene, | Scene *scene, | ||||
| Show All 15 Lines | static ParticleSystem *object_copy_modifier_particle_system_ensure(Main *bmain, | ||||
| if (psys_dst == NULL) { | if (psys_dst == NULL) { | ||||
| ModifierData *md = object_copy_particle_system(bmain, scene, ob_dst, psys_src); | ModifierData *md = object_copy_particle_system(bmain, scene, ob_dst, psys_src); | ||||
| psys_dst = ((ParticleSystemModifierData *)md)->psys; | psys_dst = ((ParticleSystemModifierData *)md)->psys; | ||||
| } | } | ||||
| return psys_dst; | return psys_dst; | ||||
| } | } | ||||
| /** Copy a single modifier. | /** | ||||
| * Copy a single modifier. | |||||
| * | * | ||||
| * \note **Do not** use this function to copy a whole modifier stack (see note below too). Use | * \note **Do not** use this function to copy a whole modifier stack (see note below too). Use | ||||
| * `BKE_object_modifier_stack_copy` instead. | * `BKE_object_modifier_stack_copy` instead. | ||||
| * | * | ||||
| * \note Complex modifiers relaying on other data (like e.g. dynamic paint or fluid using particle | * \note Complex modifiers relaying on other data (like e.g. dynamic paint or fluid using particle | ||||
| * systems) are not always 100% 'correctly' copied here, since we have to use heuristics to decide | * systems) are not always 100% 'correctly' copied here, since we have to use heuristics to decide | ||||
| * which particle system to use or add in `ob_dst`, and it's placement in the stack, etc. If used | * which particle system to use or add in `ob_dst`, and it's placement in the stack, etc. If used | ||||
| * more than once, this function should preferably be called in stack order. */ | * more than once, this function should preferably be called in stack order. | ||||
| */ | |||||
| bool BKE_object_copy_modifier( | bool BKE_object_copy_modifier( | ||||
| Main *bmain, Scene *scene, Object *ob_dst, const Object *ob_src, ModifierData *md_src) | Main *bmain, Scene *scene, Object *ob_dst, const Object *ob_src, ModifierData *md_src) | ||||
| { | { | ||||
| BLI_assert(ob_dst->type != OB_GPENCIL); | BLI_assert(ob_dst->type != OB_GPENCIL); | ||||
| const ModifierTypeInfo *mti = BKE_modifier_get_info(md_src->type); | const ModifierTypeInfo *mti = BKE_modifier_get_info(md_src->type); | ||||
| if (!object_modifier_type_copy_check(md_src->type)) { | if (!object_modifier_type_copy_check(md_src->type)) { | ||||
| /* We never allow copying those modifiers here. */ | /* We never allow copying those modifiers here. */ | ||||
| ▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | else { | ||||
| BKE_modifier_unique_name(&ob_dst->modifiers, md_dst); | BKE_modifier_unique_name(&ob_dst->modifiers, md_dst); | ||||
| } | } | ||||
| BKE_object_modifier_set_active(ob_dst, md_dst); | BKE_object_modifier_set_active(ob_dst, md_dst); | ||||
| return true; | return true; | ||||
| } | } | ||||
| /** Copy a single GPencil modifier. | /** | ||||
| * Copy a single GPencil modifier. | |||||
| * | * | ||||
| * \note **Do not** use this function to copy a whole modifier stack. Use | * \note **Do not** use this function to copy a whole modifier stack. Use | ||||
| * `BKE_object_modifier_stack_copy` instead. */ | * `BKE_object_modifier_stack_copy` instead. | ||||
| */ | |||||
| bool BKE_object_copy_gpencil_modifier(struct Object *ob_dst, GpencilModifierData *gmd_src) | bool BKE_object_copy_gpencil_modifier(struct Object *ob_dst, GpencilModifierData *gmd_src) | ||||
| { | { | ||||
| BLI_assert(ob_dst->type == OB_GPENCIL); | BLI_assert(ob_dst->type == OB_GPENCIL); | ||||
| GpencilModifierData *gmd_dst = BKE_gpencil_modifier_new(gmd_src->type); | GpencilModifierData *gmd_dst = BKE_gpencil_modifier_new(gmd_src->type); | ||||
| BLI_strncpy(gmd_dst->name, gmd_src->name, sizeof(gmd_dst->name)); | BLI_strncpy(gmd_dst->name, gmd_src->name, sizeof(gmd_dst->name)); | ||||
| const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(gmd_src->type); | const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(gmd_src->type); | ||||
| ▲ Show 20 Lines • Show All 236 Lines • ▼ Show 20 Lines | if (ob->runtime.gpd_eval != NULL) { | ||||
| BKE_gpencil_eval_delete(ob->runtime.gpd_eval); | BKE_gpencil_eval_delete(ob->runtime.gpd_eval); | ||||
| ob->runtime.gpd_eval = NULL; | ob->runtime.gpd_eval = NULL; | ||||
| } | } | ||||
| if (ob->runtime.geometry_set_eval != NULL) { | if (ob->runtime.geometry_set_eval != NULL) { | ||||
| BKE_geometry_set_free(ob->runtime.geometry_set_eval); | BKE_geometry_set_free(ob->runtime.geometry_set_eval); | ||||
| ob->runtime.geometry_set_eval = NULL; | ob->runtime.geometry_set_eval = NULL; | ||||
| } | } | ||||
| if (ob->runtime.geometry_set_previews != NULL) { | |||||
| BLI_ghash_free(ob->runtime.geometry_set_previews, NULL, (GHashValFreeFP)BKE_geometry_set_free); | |||||
| ob->runtime.geometry_set_previews = NULL; | |||||
| } | |||||
| } | } | ||||
| void BKE_object_free_caches(Object *object) | void BKE_object_free_caches(Object *object) | ||||
| { | { | ||||
| short update_flag = 0; | short update_flag = 0; | ||||
| /* Free particle system caches holding paths. */ | /* Free particle system caches holding paths. */ | ||||
| if (object->particlesystem.first) { | if (object->particlesystem.first) { | ||||
| Show All 34 Lines | void BKE_object_free_caches(Object *object) | ||||
| * scene update routines are back to its business the object will be | * scene update routines are back to its business the object will be | ||||
| * guaranteed to be in a known state. | * guaranteed to be in a known state. | ||||
| */ | */ | ||||
| if (update_flag != 0) { | if (update_flag != 0) { | ||||
| DEG_id_tag_update(&object->id, update_flag); | DEG_id_tag_update(&object->id, update_flag); | ||||
| } | } | ||||
| } | } | ||||
| /* Can be called from multiple threads. */ | |||||
| void BKE_object_preview_geometry_set_add(Object *ob, | |||||
| const uint64_t key, | |||||
| struct GeometrySet *geometry_set) | |||||
| { | |||||
| static ThreadMutex mutex = BLI_MUTEX_INITIALIZER; | |||||
| BLI_mutex_lock(&mutex); | |||||
| if (ob->runtime.geometry_set_previews == NULL) { | |||||
| ob->runtime.geometry_set_previews = BLI_ghash_int_new(__func__); | |||||
| } | |||||
| BLI_ghash_reinsert(ob->runtime.geometry_set_previews, | |||||
| POINTER_FROM_UINT(key), | |||||
| geometry_set, | |||||
| NULL, | |||||
| (GHashValFreeFP)BKE_geometry_set_free); | |||||
| BLI_mutex_unlock(&mutex); | |||||
| } | |||||
| /** | /** | ||||
| * Actual check for internal data, not context or flags. | * Actual check for internal data, not context or flags. | ||||
| */ | */ | ||||
| bool BKE_object_is_in_editmode(const Object *ob) | bool BKE_object_is_in_editmode(const Object *ob) | ||||
| { | { | ||||
| if (ob->data == NULL) { | if (ob->data == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 1,422 Lines • ▼ Show 20 Lines | static bool ob_parcurve(Object *ob, Object *par, float r_mat[4][4]) | ||||
| * cause a threading conflicts. | * cause a threading conflicts. | ||||
| * | * | ||||
| * TODO(sergey): Some of the legit looking cases like T56619 need to be | * TODO(sergey): Some of the legit looking cases like T56619 need to be | ||||
| * looked into, and maybe curve cache (and other dependencies) are to be | * looked into, and maybe curve cache (and other dependencies) are to be | ||||
| * evaluated prior to conversion. */ | * evaluated prior to conversion. */ | ||||
| if (par->runtime.curve_cache == NULL) { | if (par->runtime.curve_cache == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (par->runtime.curve_cache->path == NULL) { | if (par->runtime.curve_cache->anim_path_accum_length == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* ctime is now a proper var setting of Curve which gets set by Animato like any other var | /* ctime is now a proper var setting of Curve which gets set by Animato like any other var | ||||
| * that's animated, but this will only work if it actually is animated. | * that's animated, but this will only work if it actually is animated. | ||||
| * | * | ||||
| * We divide the curve-time calculated in the previous step by the length of the path, | * We divide the curve-time calculated in the previous step by the length of the path, | ||||
| * to get a time factor, which then gets clamped to lie within 0.0 - 1.0 range. | * to get a time factor, which then gets clamped to lie within 0.0 - 1.0 range. | ||||
| */ | */ | ||||
| if (cu->pathlen) { | if (cu->pathlen) { | ||||
| ctime = cu->ctime / cu->pathlen; | ctime = cu->ctime / cu->pathlen; | ||||
| } | } | ||||
| else { | else { | ||||
| ctime = cu->ctime; | ctime = cu->ctime; | ||||
| } | } | ||||
| CLAMP(ctime, 0.0f, 1.0f); | |||||
| unit_m4(r_mat); | unit_m4(r_mat); | ||||
| /* vec: 4 items! */ | /* vec: 4 items! */ | ||||
| if (where_on_path(par, ctime, vec, dir, (cu->flag & CU_FOLLOW) ? quat : NULL, &radius, NULL)) { | if (BKE_where_on_path( | ||||
| par, ctime, vec, dir, (cu->flag & CU_FOLLOW) ? quat : NULL, &radius, NULL)) { | |||||
| if (cu->flag & CU_FOLLOW) { | if (cu->flag & CU_FOLLOW) { | ||||
| quat_apply_track(quat, ob->trackflag, ob->upflag); | quat_apply_track(quat, ob->trackflag, ob->upflag); | ||||
| normalize_qt(quat); | normalize_qt(quat); | ||||
| quat_to_mat4(r_mat, quat); | quat_to_mat4(r_mat, quat); | ||||
| } | } | ||||
| if (cu->flag & CU_PATH_RADIUS) { | if (cu->flag & CU_PATH_RADIUS) { | ||||
| float tmat[4][4], rmat[4][4]; | float tmat[4][4], rmat[4][4]; | ||||
| scale_m4_fl(tmat, radius); | scale_m4_fl(tmat, radius); | ||||
| ▲ Show 20 Lines • Show All 826 Lines • ▼ Show 20 Lines | |||||
| bool BKE_object_minmax_dupli(Depsgraph *depsgraph, | bool BKE_object_minmax_dupli(Depsgraph *depsgraph, | ||||
| Scene *scene, | Scene *scene, | ||||
| Object *ob, | Object *ob, | ||||
| float r_min[3], | float r_min[3], | ||||
| float r_max[3], | float r_max[3], | ||||
| const bool use_hidden) | const bool use_hidden) | ||||
| { | { | ||||
| bool ok = false; | bool ok = false; | ||||
| if ((ob->transflag & OB_DUPLI) == 0) { | if ((ob->transflag & OB_DUPLI) == 0 && ob->runtime.geometry_set_eval == NULL) { | ||||
| return ok; | return ok; | ||||
| } | } | ||||
| DupliObject *dob; | DupliObject *dob; | ||||
| ListBase *lb = object_duplilist(depsgraph, scene, ob); | ListBase *lb = object_duplilist(depsgraph, scene, ob); | ||||
| for (dob = lb->first; dob; dob = dob->next) { | for (dob = lb->first; dob; dob = dob->next) { | ||||
| if ((use_hidden == false) && (dob->no_draw != 0)) { | if ((use_hidden == false) && (dob->no_draw != 0)) { | ||||
| /* pass */ | /* pass */ | ||||
| ▲ Show 20 Lines • Show All 1,563 Lines • Show Last 20 Lines | |||||