| 
									
										
										
										
											2019-04-29 12:55:29 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2018 Blender Foundation. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup depsgraph | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "intern/builder/deg_builder_cache.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_anim_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_animsys.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-07 18:17:12 +05:30
										 |  |  | namespace blender::deg { | 
					
						
							| 
									
										
										
										
											2019-04-29 12:55:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Animated property storage. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-28 14:50:13 +01:00
										 |  |  | AnimatedPropertyID::AnimatedPropertyID() : data(nullptr), property_rna(nullptr) | 
					
						
							| 
									
										
										
										
											2019-04-29 12:55:29 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AnimatedPropertyID::AnimatedPropertyID(const PointerRNA *pointer_rna, | 
					
						
							|  |  |  |                                        const PropertyRNA *property_rna) | 
					
						
							|  |  |  |     : AnimatedPropertyID(*pointer_rna, property_rna) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AnimatedPropertyID::AnimatedPropertyID(const PointerRNA &pointer_rna, | 
					
						
							|  |  |  |                                        const PropertyRNA *property_rna) | 
					
						
							|  |  |  |     : data(pointer_rna.data), property_rna(property_rna) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AnimatedPropertyID::AnimatedPropertyID(ID *id, StructRNA *type, const char *property_name) | 
					
						
							|  |  |  |     : data(id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   property_rna = RNA_struct_type_find_property(type, property_name); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AnimatedPropertyID::AnimatedPropertyID(ID * /*id*/, | 
					
						
							|  |  |  |                                        StructRNA *type, | 
					
						
							|  |  |  |                                        void *data, | 
					
						
							|  |  |  |                                        const char *property_name) | 
					
						
							|  |  |  |     : data(data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   property_rna = RNA_struct_type_find_property(type, property_name); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-10 15:23:22 +02:00
										 |  |  | bool operator==(const AnimatedPropertyID &a, const AnimatedPropertyID &b) | 
					
						
							| 
									
										
										
										
											2019-04-29 12:55:29 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-10 15:23:22 +02:00
										 |  |  |   return a.data == b.data && a.property_rna == b.property_rna; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | uint64_t AnimatedPropertyID::hash() const | 
					
						
							| 
									
										
										
										
											2020-06-10 15:23:22 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   uintptr_t ptr1 = (uintptr_t)data; | 
					
						
							|  |  |  |   uintptr_t ptr2 = (uintptr_t)property_rna; | 
					
						
							| 
									
										
										
										
											2020-08-07 18:24:59 +02:00
										 |  |  |   return static_cast<uint64_t>(((ptr1 >> 4) * 33) ^ (ptr2 >> 4)); | 
					
						
							| 
									
										
										
										
											2019-04-29 12:55:29 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct AnimatedPropertyCallbackData { | 
					
						
							|  |  |  |   PointerRNA pointer_rna; | 
					
						
							|  |  |  |   AnimatedPropertyStorage *animated_property_storage; | 
					
						
							|  |  |  |   DepsgraphBuilderCache *builder_cache; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void animated_property_cb(ID * /*id*/, FCurve *fcurve, void *data_v) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-01-28 14:50:13 +01:00
										 |  |  |   if (fcurve->rna_path == nullptr || fcurve->rna_path[0] == '\0') { | 
					
						
							| 
									
										
										
										
											2019-04-29 12:55:29 +02:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   AnimatedPropertyCallbackData *data = static_cast<AnimatedPropertyCallbackData *>(data_v); | 
					
						
							|  |  |  |   /* Resolve property. */ | 
					
						
							|  |  |  |   PointerRNA pointer_rna; | 
					
						
							| 
									
										
										
										
											2020-01-28 14:50:13 +01:00
										 |  |  |   PropertyRNA *property_rna = nullptr; | 
					
						
							| 
									
										
										
										
											2019-04-29 12:55:29 +02:00
										 |  |  |   if (!RNA_path_resolve_property( | 
					
						
							|  |  |  |           &data->pointer_rna, fcurve->rna_path, &pointer_rna, &property_rna)) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Get storage for the ID.
 | 
					
						
							|  |  |  |    * This is needed to deal with cases when nested datablock is animated by its parent. */ | 
					
						
							|  |  |  |   AnimatedPropertyStorage *animated_property_storage = data->animated_property_storage; | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |   if (pointer_rna.owner_id != data->pointer_rna.owner_id) { | 
					
						
							| 
									
										
										
										
											2019-04-29 12:55:29 +02:00
										 |  |  |     animated_property_storage = data->builder_cache->ensureAnimatedPropertyStorage( | 
					
						
							| 
									
										
										
										
											2019-08-23 09:52:12 +02:00
										 |  |  |         pointer_rna.owner_id); | 
					
						
							| 
									
										
										
										
											2019-04-29 12:55:29 +02:00
										 |  |  |   } | 
					
						
							|  |  |  |   /* Set the property as animated. */ | 
					
						
							|  |  |  |   animated_property_storage->tagPropertyAsAnimated(&pointer_rna, property_rna); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AnimatedPropertyStorage::AnimatedPropertyStorage() : is_fully_initialized(false) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimatedPropertyStorage::initializeFromID(DepsgraphBuilderCache *builder_cache, ID *id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   AnimatedPropertyCallbackData data; | 
					
						
							|  |  |  |   RNA_id_pointer_create(id, &data.pointer_rna); | 
					
						
							|  |  |  |   data.animated_property_storage = this; | 
					
						
							|  |  |  |   data.builder_cache = builder_cache; | 
					
						
							|  |  |  |   BKE_fcurves_id_cb(id, animated_property_cb, &data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimatedPropertyStorage::tagPropertyAsAnimated(const AnimatedPropertyID &property_id) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-10 15:23:22 +02:00
										 |  |  |   animated_properties_set.add(property_id); | 
					
						
							| 
									
										
										
										
											2019-04-29 12:55:29 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AnimatedPropertyStorage::tagPropertyAsAnimated(const PointerRNA *pointer_rna, | 
					
						
							|  |  |  |                                                     const PropertyRNA *property_rna) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   tagPropertyAsAnimated(AnimatedPropertyID(pointer_rna, property_rna)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool AnimatedPropertyStorage::isPropertyAnimated(const AnimatedPropertyID &property_id) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-10 15:23:22 +02:00
										 |  |  |   return animated_properties_set.contains(property_id); | 
					
						
							| 
									
										
										
										
											2019-04-29 12:55:29 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool AnimatedPropertyStorage::isPropertyAnimated(const PointerRNA *pointer_rna, | 
					
						
							|  |  |  |                                                  const PropertyRNA *property_rna) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return isPropertyAnimated(AnimatedPropertyID(pointer_rna, property_rna)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Builder cache itself. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DepsgraphBuilderCache::~DepsgraphBuilderCache() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-18 18:16:51 +02:00
										 |  |  |   for (AnimatedPropertyStorage *animated_property_storage : | 
					
						
							|  |  |  |        animated_property_storage_map_.values()) { | 
					
						
							| 
									
										
										
										
											2020-07-03 12:22:16 +02:00
										 |  |  |     delete animated_property_storage; | 
					
						
							| 
									
										
										
										
											2019-04-29 12:55:29 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AnimatedPropertyStorage *DepsgraphBuilderCache::ensureAnimatedPropertyStorage(ID *id) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-18 18:16:51 +02:00
										 |  |  |   return animated_property_storage_map_.lookup_or_add_cb( | 
					
						
							| 
									
										
										
										
											2020-07-03 12:22:16 +02:00
										 |  |  |       id, []() { return new AnimatedPropertyStorage(); }); | 
					
						
							| 
									
										
										
										
											2019-04-29 12:55:29 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AnimatedPropertyStorage *DepsgraphBuilderCache::ensureInitializedAnimatedPropertyStorage(ID *id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   AnimatedPropertyStorage *animated_property_storage = ensureAnimatedPropertyStorage(id); | 
					
						
							|  |  |  |   if (!animated_property_storage->is_fully_initialized) { | 
					
						
							|  |  |  |     animated_property_storage->initializeFromID(this, id); | 
					
						
							|  |  |  |     animated_property_storage->is_fully_initialized = true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return animated_property_storage; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-07 18:17:12 +05:30
										 |  |  | }  // namespace blender::deg
 |