Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/pointcache.c
| Show First 20 Lines • Show All 1,859 Lines • ▼ Show 20 Lines | void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, Object *ob, RigidBodyWorld *rbw) | ||||
| pid->stack_index = pid->cache->index; | pid->stack_index = pid->cache->index; | ||||
| pid->default_step = 1; | pid->default_step = 1; | ||||
| pid->max_step = 1; | pid->max_step = 1; | ||||
| pid->file_type = PTCACHE_FILE_PTCACHE; | pid->file_type = PTCACHE_FILE_PTCACHE; | ||||
| } | } | ||||
| static int ptcache_sim_particle_totpoint(void *state_v, int UNUSED(cfra)) | static int ptcache_sim_particles_totpoint(void *state_v, int UNUSED(cfra)) | ||||
| { | { | ||||
| ParticleSimulationState *state = (ParticleSimulationState *)state_v; | UNUSED_VARS(state_v); | ||||
| return state->tot_particles; | /* All actual data is stored in extra data. | ||||
| * Just don't return 0 so that this data is not skipped. */ | |||||
| return 1; | |||||
| } | } | ||||
| static void ptcache_sim_particle_error(void *UNUSED(state_v), const char *UNUSED(message)) | static void ptcache_sim_particles_error(void *UNUSED(state_v), const char *UNUSED(message)) | ||||
| { | { | ||||
| } | } | ||||
| static int ptcache_sim_particle_write(int index, void *state_v, void **data, int UNUSED(cfra)) | static int ptcache_sim_particle_point_write(int UNUSED(index), | ||||
| void *UNUSED(state_v), | |||||
| void **UNUSED(data), | |||||
| int UNUSED(cfra)) | |||||
| { | |||||
| return 0; | |||||
| } | |||||
| static void ptcache_sim_particle_point_read(int UNUSED(index), | |||||
| void *UNUSED(state_v), | |||||
| void **UNUSED(data), | |||||
| float UNUSED(cfra), | |||||
| float *UNUSED(old_data)) | |||||
| { | { | ||||
| ParticleSimulationState *state = (ParticleSimulationState *)state_v; | } | ||||
| const float *positions = (const float *)CustomData_get_layer_named( | static unsigned int ptcache_get_array_size_in_bytes(unsigned int totdata, int data_type) | ||||
| &state->attributes, CD_LOCATION, "Position"); | { | ||||
| const char *struct_name; | |||||
| int struct_num; | |||||
| CustomData_file_write_info(data_type, &struct_name, &struct_num); | |||||
| int struct_size = CustomData_sizeof(data_type); | |||||
| int size_in_bytes = struct_num * struct_size * totdata; | |||||
| return size_in_bytes; | |||||
| } | |||||
| PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, positions + (index * 3)); | static void ptcache_sim_particles_write(void *state_v, PTCacheMem *pm, int UNUSED(cfra)) | ||||
| { | |||||
| ParticleSimulationState *state = state_v; | |||||
| return 1; | for (int layer_index = 0; layer_index < state->attributes.totlayer; layer_index++) { | ||||
| CustomDataLayer *layer = &state->attributes.layers[layer_index]; | |||||
| BLI_assert(layer->name != NULL); | |||||
| PTCacheArray *array = MEM_callocN(sizeof(PTCacheArray), AT); | |||||
| array->totdata = state->tot_particles; | |||||
| array->data_type = layer->type; | |||||
| array->identifier = BLI_strdup(layer->name); | |||||
| unsigned int size_in_bytes = ptcache_get_array_size_in_bytes(array->totdata, array->data_type); | |||||
| array->data = MEM_mallocN(size_in_bytes, AT); | |||||
| memcpy(array->data, layer->data, size_in_bytes); | |||||
| BLI_addtail(&pm->arrays, array); | |||||
| } | } | ||||
| static void ptcache_sim_particle_read( | } | ||||
| int index, void *state_v, void **data, float UNUSED(cfra), float *UNUSED(old_data)) | |||||
| static void ptcache_sim_particles_read(void *state_v, PTCacheMem *pm, float UNUSED(cfra)) | |||||
| { | { | ||||
| ParticleSimulationState *state = (ParticleSimulationState *)state_v; | ParticleSimulationState *state = state_v; | ||||
| BLI_assert(index < state->tot_particles); | CustomData_free(&state->attributes, state->tot_particles); | ||||
| float *positions = (float *)CustomData_get_layer_named( | state->tot_particles = 0; | ||||
| &state->attributes, CD_LOCATION, "Position"); | |||||
| PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, 0, positions + (index * 3)); | LISTBASE_FOREACH (const PTCacheArray *, array, &pm->arrays) { | ||||
| if (array->totdata != state->tot_particles) { | |||||
| state->tot_particles = array->totdata; | |||||
| CustomData_realloc(&state->attributes, array->totdata); | |||||
| } | |||||
| unsigned int size_in_bytes = ptcache_get_array_size_in_bytes(array->totdata, array->data_type); | |||||
| void *data = MEM_mallocN(size_in_bytes, AT); | |||||
| memcpy(data, array->data, size_in_bytes); | |||||
| CustomData_add_layer_named( | |||||
| &state->attributes, array->data_type, CD_ASSIGN, data, array->totdata, array->identifier); | |||||
| } | |||||
| } | } | ||||
| void BKE_ptcache_id_from_sim_particles(PTCacheID *pid, ParticleSimulationState *state) | void BKE_ptcache_id_from_sim_particles(PTCacheID *pid, ParticleSimulationState *state) | ||||
| { | { | ||||
| memset(pid, 0, sizeof(PTCacheID)); | memset(pid, 0, sizeof(PTCacheID)); | ||||
| ParticleSimulationState *state_orig; | ParticleSimulationState *state_orig; | ||||
| if (state->head.orig_state != NULL) { | if (state->head.orig_state != NULL) { | ||||
| state_orig = (ParticleSimulationState *)state->head.orig_state; | state_orig = (ParticleSimulationState *)state->head.orig_state; | ||||
| } | } | ||||
| else { | else { | ||||
| state_orig = state; | state_orig = state; | ||||
| } | } | ||||
| pid->calldata = state; | pid->calldata = state; | ||||
| pid->type = PTCACHE_TYPE_SIM_PARTICLES; | pid->type = PTCACHE_TYPE_SIM_PARTICLES; | ||||
| pid->cache = state_orig->point_cache; | pid->cache = state_orig->point_cache; | ||||
| pid->cache_ptr = &state_orig->point_cache; | pid->cache_ptr = &state_orig->point_cache; | ||||
| pid->ptcaches = &state_orig->ptcaches; | pid->ptcaches = &state_orig->ptcaches; | ||||
| pid->totpoint = ptcache_sim_particle_totpoint; | pid->totpoint = ptcache_sim_particles_totpoint; | ||||
| pid->totwrite = ptcache_sim_particle_totpoint; | pid->totwrite = ptcache_sim_particles_totpoint; | ||||
| pid->error = ptcache_sim_particle_error; | pid->error = ptcache_sim_particles_error; | ||||
| pid->write_point = ptcache_sim_particle_write; | |||||
| pid->read_point = ptcache_sim_particle_read; | |||||
| pid->interpolate_point = NULL; | |||||
| pid->write_stream = NULL; | |||||
| pid->read_stream = NULL; | |||||
| pid->write_openvdb_stream = NULL; | |||||
| pid->read_openvdb_stream = NULL; | |||||
| pid->write_extra_data = NULL; | pid->write_point = ptcache_sim_particle_point_write; | ||||
| pid->read_extra_data = NULL; | pid->read_point = ptcache_sim_particle_point_read; | ||||
| pid->interpolate_extra_data = NULL; | |||||
| pid->write_header = NULL; | pid->write_extra_data = ptcache_sim_particles_write; | ||||
| pid->read_header = NULL; | pid->read_extra_data = ptcache_sim_particles_read; | ||||
| pid->data_types = 1 << BPHYS_DATA_LOCATION; | |||||
| pid->info_types = 0; | |||||
| pid->stack_index = 0; | |||||
| pid->default_step = 1; | pid->default_step = 1; | ||||
| pid->max_step = 1; | pid->max_step = 1; | ||||
| pid->file_type = PTCACHE_FILE_PTCACHE; | pid->file_type = PTCACHE_FILE_PTCACHE; | ||||
| } | } | ||||
| /** | /** | ||||
| * \param ob: Optional, may be NULL. | * \param ob: Optional, may be NULL. | ||||
| ▲ Show 20 Lines • Show All 732 Lines • ▼ Show 20 Lines | for (; extra; extra = extra->next) { | ||||
| MEM_freeN(extra->data); | MEM_freeN(extra->data); | ||||
| } | } | ||||
| } | } | ||||
| BLI_freelistN(&pm->extradata); | BLI_freelistN(&pm->extradata); | ||||
| } | } | ||||
| } | } | ||||
| static void ptcache_arrays_free(PTCacheMem *pm) | |||||
| { | |||||
| LISTBASE_FOREACH (PTCacheArray *, array, &pm->arrays) { | |||||
| MEM_freeN(array->identifier); | |||||
| MEM_freeN(array->data); | |||||
| } | |||||
| BLI_freelistN(&pm->arrays); | |||||
| } | |||||
| static void ptcache_mem_clear(PTCacheMem *pm) | static void ptcache_mem_clear(PTCacheMem *pm) | ||||
| { | { | ||||
| ptcache_data_free(pm); | ptcache_data_free(pm); | ||||
| ptcache_extra_free(pm); | ptcache_extra_free(pm); | ||||
| ptcache_arrays_free(pm); | |||||
| } | } | ||||
| static int ptcache_old_elemsize(PTCacheID *pid) | static int ptcache_old_elemsize(PTCacheID *pid) | ||||
| { | { | ||||
| if (pid->type == PTCACHE_TYPE_SOFTBODY) { | if (pid->type == PTCACHE_TYPE_SOFTBODY) { | ||||
| return 6 * sizeof(float); | return 6 * sizeof(float); | ||||
| } | } | ||||
| else if (pid->type == PTCACHE_TYPE_PARTICLES) { | else if (pid->type == PTCACHE_TYPE_PARTICLES) { | ||||
| ▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | else if (pid->cache->mem_cache.first) { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static PTCacheMem *ptcache_disk_frame_to_mem(PTCacheID *pid, int cfra) | static PTCacheMem *ptcache_disk_frame_to_mem(PTCacheID *pid, int cfra) | ||||
| { | { | ||||
| PTCacheFile *pf = ptcache_file_open(pid, PTCACHE_FILE_READ, cfra); | PTCacheFile *pf = ptcache_file_open(pid, PTCACHE_FILE_READ, cfra); | ||||
| PTCacheMem *pm = NULL; | PTCacheMem *pm = NULL; | ||||
| unsigned int i, error = 0; | unsigned int error = 0; | ||||
| if (pf == NULL) { | if (pf == NULL) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| if (!ptcache_file_header_begin_read(pf)) { | if (!ptcache_file_header_begin_read(pf)) { | ||||
| error = 1; | error = 1; | ||||
| } | } | ||||
| if (!error && (pf->type != pid->type || !pid->read_header(pf))) { | if (!error && (pf->type != pid->type || !pid->read_header(pf))) { | ||||
| error = 1; | error = 1; | ||||
| } | } | ||||
| if (!error) { | if (!error) { | ||||
| pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem"); | pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem"); | ||||
| pm->totpoint = pf->totpoint; | pm->totpoint = pf->totpoint; | ||||
| pm->data_types = pf->data_types; | pm->data_types = pf->data_types; | ||||
| pm->frame = pf->frame; | pm->frame = pf->frame; | ||||
| ptcache_data_alloc(pm); | ptcache_data_alloc(pm); | ||||
| if (pf->flag & PTCACHE_TYPEFLAG_COMPRESS) { | if (pf->flag & PTCACHE_TYPEFLAG_COMPRESS) { | ||||
| for (i = 0; i < BPHYS_TOT_DATA; i++) { | for (int i = 0; i < BPHYS_TOT_DATA; i++) { | ||||
| unsigned int out_len = pm->totpoint * ptcache_data_size[i]; | unsigned int out_len = pm->totpoint * ptcache_data_size[i]; | ||||
| if (pf->data_types & (1 << i)) { | if (pf->data_types & (1 << i)) { | ||||
| ptcache_file_compressed_read(pf, (unsigned char *)(pm->data[i]), out_len); | ptcache_file_compressed_read(pf, (unsigned char *)(pm->data[i]), out_len); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| BKE_ptcache_mem_pointers_init(pm); | BKE_ptcache_mem_pointers_init(pm); | ||||
| ptcache_file_pointers_init(pf); | ptcache_file_pointers_init(pf); | ||||
| for (i = 0; i < pm->totpoint; i++) { | for (int i = 0; i < pm->totpoint; i++) { | ||||
| if (!ptcache_file_data_read(pf)) { | if (!ptcache_file_data_read(pf)) { | ||||
| error = 1; | error = 1; | ||||
| break; | break; | ||||
| } | } | ||||
| ptcache_data_copy(pf->cur, pm->cur); | ptcache_data_copy(pf->cur, pm->cur); | ||||
| BKE_ptcache_mem_pointers_incr(pm); | BKE_ptcache_mem_pointers_incr(pm); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (!error && pf->flag & PTCACHE_TYPEFLAG_EXTRADATA) { | if (error) { | ||||
| /* pass */ | |||||
| } | |||||
| else if (pf->flag & PTCACHE_TYPEFLAG_EXTRADATA) { | |||||
| BLI_assert((pf->flag & PTCACHE_TYPEFLAG_ARRAYS) == 0); | |||||
| unsigned int extratype = 0; | unsigned int extratype = 0; | ||||
| while (ptcache_file_read(pf, &extratype, 1, sizeof(unsigned int))) { | while (ptcache_file_read(pf, &extratype, 1, sizeof(unsigned int))) { | ||||
| PTCacheExtra *extra = MEM_callocN(sizeof(PTCacheExtra), "Pointcache extradata"); | PTCacheExtra *extra = MEM_callocN(sizeof(PTCacheExtra), "Pointcache extradata"); | ||||
| extra->type = extratype; | extra->type = extratype; | ||||
| ptcache_file_read(pf, &extra->totdata, 1, sizeof(unsigned int)); | ptcache_file_read(pf, &extra->totdata, 1, sizeof(unsigned int)); | ||||
| extra->data = MEM_callocN(extra->totdata * ptcache_extra_datasize[extra->type], | extra->data = MEM_callocN(extra->totdata * ptcache_extra_datasize[extra->type], | ||||
| "Pointcache extradata->data"); | "Pointcache extradata->data"); | ||||
| if (pf->flag & PTCACHE_TYPEFLAG_COMPRESS) { | if (pf->flag & PTCACHE_TYPEFLAG_COMPRESS) { | ||||
| ptcache_file_compressed_read(pf, | ptcache_file_compressed_read(pf, | ||||
| (unsigned char *)(extra->data), | (unsigned char *)(extra->data), | ||||
| extra->totdata * ptcache_extra_datasize[extra->type]); | extra->totdata * ptcache_extra_datasize[extra->type]); | ||||
| } | } | ||||
| else { | else { | ||||
| ptcache_file_read(pf, extra->data, extra->totdata, ptcache_extra_datasize[extra->type]); | ptcache_file_read(pf, extra->data, extra->totdata, ptcache_extra_datasize[extra->type]); | ||||
| } | } | ||||
| BLI_addtail(&pm->extradata, extra); | BLI_addtail(&pm->extradata, extra); | ||||
| } | } | ||||
| } | } | ||||
| else if (pf->flag & PTCACHE_TYPEFLAG_ARRAYS) { | |||||
| /* This has not been tested yet. */ | |||||
| unsigned int totarrays; | |||||
| ptcache_file_read(pf, &totarrays, 1, sizeof(unsigned int)); | |||||
| for (int i = 0; i < totarrays; i++) { | |||||
| PTCacheArray *array = MEM_callocN(sizeof(PTCacheArray), "Pointcache array"); | |||||
| ptcache_file_read(pf, &array->data_type, 1, sizeof(int)); | |||||
| ptcache_file_read(pf, &array->totdata, 1, sizeof(unsigned int)); | |||||
| unsigned int identifier_length; | |||||
| ptcache_file_read(pf, &identifier_length, 1, sizeof(unsigned int)); | |||||
| array->identifier = MEM_callocN(identifier_length, AT); | |||||
| ptcache_file_read(pf, array->identifier, 1, identifier_length); | |||||
| unsigned int size_in_bytes = ptcache_get_array_size_in_bytes(array->totdata, | |||||
| array->data_type); | |||||
| array->data = MEM_mallocN(size_in_bytes, AT); | |||||
| ptcache_file_read(pf, array->data, size_in_bytes, 1); | |||||
| BLI_addtail(&pm->arrays, array); | |||||
| } | |||||
| } | |||||
| if (error && pm) { | if (error && pm) { | ||||
| ptcache_mem_clear(pm); | ptcache_mem_clear(pm); | ||||
| MEM_freeN(pm); | MEM_freeN(pm); | ||||
| pm = NULL; | pm = NULL; | ||||
| } | } | ||||
| ptcache_file_close(pf); | ptcache_file_close(pf); | ||||
| Show All 24 Lines | static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm) | ||||
| pf->totpoint = pm->totpoint; | pf->totpoint = pm->totpoint; | ||||
| pf->type = pid->type; | pf->type = pid->type; | ||||
| pf->flag = 0; | pf->flag = 0; | ||||
| if (pm->extradata.first) { | if (pm->extradata.first) { | ||||
| pf->flag |= PTCACHE_TYPEFLAG_EXTRADATA; | pf->flag |= PTCACHE_TYPEFLAG_EXTRADATA; | ||||
| } | } | ||||
| if (pm->arrays.first) { | |||||
| pf->flag |= PTCACHE_TYPEFLAG_ARRAYS; | |||||
| } | |||||
| if (pid->cache->compression) { | if (pid->cache->compression) { | ||||
| pf->flag |= PTCACHE_TYPEFLAG_COMPRESS; | pf->flag |= PTCACHE_TYPEFLAG_COMPRESS; | ||||
| } | } | ||||
| if (!ptcache_file_header_begin_write(pf) || !pid->write_header(pf)) { | if (!ptcache_file_header_begin_write(pf) || !pid->write_header(pf)) { | ||||
| error = 1; | error = 1; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | for (; extra; extra = extra->next) { | ||||
| MEM_freeN(out); | MEM_freeN(out); | ||||
| } | } | ||||
| else { | else { | ||||
| ptcache_file_write(pf, extra->data, extra->totdata, ptcache_extra_datasize[extra->type]); | ptcache_file_write(pf, extra->data, extra->totdata, ptcache_extra_datasize[extra->type]); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (!error && pm->arrays.first) { | |||||
| /* This has not been tested yet. */ | |||||
| int totarrays = BLI_listbase_count(&pm->arrays); | |||||
| ptcache_file_write(pf, &totarrays, 1, sizeof(int)); | |||||
| LISTBASE_FOREACH (PTCacheArray *, array, &pm->arrays) { | |||||
| ptcache_file_write(pf, &array->data_type, 1, sizeof(int)); | |||||
| ptcache_file_write(pf, &array->totdata, 1, sizeof(unsigned int)); | |||||
| unsigned int identifier_length = strlen(array->identifier) + 1; | |||||
| ptcache_file_write(pf, &identifier_length, 1, sizeof(unsigned int)); | |||||
| ptcache_file_write(pf, array->identifier, 1, identifier_length); | |||||
| unsigned int size_in_bytes = ptcache_get_array_size_in_bytes(array->totdata, | |||||
| array->data_type); | |||||
| ptcache_file_write(pf, array->data, size_in_bytes, 1); | |||||
| } | |||||
| } | |||||
| ptcache_file_close(pf); | ptcache_file_close(pf); | ||||
| if (error && G.debug & G_DEBUG) { | if (error && G.debug & G_DEBUG) { | ||||
| printf("Error writing to disk cache\n"); | printf("Error writing to disk cache\n"); | ||||
| } | } | ||||
| return error == 0; | return error == 0; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 114 Lines • ▼ Show 20 Lines | for (i = 0; i < totpoint; i++) { | ||||
| index = pm->cur[BPHYS_DATA_INDEX]; | index = pm->cur[BPHYS_DATA_INDEX]; | ||||
| } | } | ||||
| pid->read_point(*index, pid->calldata, pm->cur, (float)pm->frame, NULL); | pid->read_point(*index, pid->calldata, pm->cur, (float)pm->frame, NULL); | ||||
| BKE_ptcache_mem_pointers_incr(pm); | BKE_ptcache_mem_pointers_incr(pm); | ||||
| } | } | ||||
| if (pid->read_extra_data && pm->extradata.first) { | if (pid->read_extra_data && (pm->extradata.first || pm->arrays.first)) { | ||||
| pid->read_extra_data(pid->calldata, pm, (float)pm->frame); | pid->read_extra_data(pid->calldata, pm, (float)pm->frame); | ||||
| } | } | ||||
| /* clean up temporary memory cache */ | /* clean up temporary memory cache */ | ||||
| if (pid->cache->flag & PTCACHE_DISK_CACHE) { | if (pid->cache->flag & PTCACHE_DISK_CACHE) { | ||||
| ptcache_mem_clear(pm); | ptcache_mem_clear(pm); | ||||
| MEM_freeN(pm); | MEM_freeN(pm); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 350 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /* writes cache to disk or memory */ | /* writes cache to disk or memory */ | ||||
| int BKE_ptcache_write(PTCacheID *pid, unsigned int cfra) | int BKE_ptcache_write(PTCacheID *pid, unsigned int cfra) | ||||
| { | { | ||||
| PointCache *cache = pid->cache; | PointCache *cache = pid->cache; | ||||
| int totpoint = pid->totpoint(pid->calldata, cfra); | int totpoint = pid->totpoint(pid->calldata, cfra); | ||||
| int overwrite = 0, error = 0; | int overwrite = 0, error = 0; | ||||
| if (pid->type != PTCACHE_TYPE_SIM_PARTICLES) { | |||||
| if (totpoint == 0 || (cfra ? pid->data_types == 0 : pid->info_types == 0)) { | if (totpoint == 0 || (cfra ? pid->data_types == 0 : pid->info_types == 0)) { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| } | |||||
| if (ptcache_write_needed(pid, cfra, &overwrite) == 0) { | if (ptcache_write_needed(pid, cfra, &overwrite) == 0) { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| if (pid->file_type == PTCACHE_FILE_OPENVDB && pid->write_openvdb_stream) { | if (pid->file_type == PTCACHE_FILE_OPENVDB && pid->write_openvdb_stream) { | ||||
| ptcache_write_openvdb_stream(pid, cfra); | ptcache_write_openvdb_stream(pid, cfra); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 1,264 Lines • Show Last 20 Lines | |||||