Fluid: Fix that maps old smoke and fluid modifiers to new manta modifier

This commit is contained in:
Sebastián Barschkis 2019-12-17 18:00:27 +01:00
parent 0b60fb5ec2
commit a04573f4aa
6 changed files with 272 additions and 69 deletions

View File

@ -27,7 +27,7 @@
* \note Use #STRINGIFY() rather than defining with quotes.
*/
#define BLENDER_VERSION 282
#define BLENDER_SUBVERSION 5
#define BLENDER_SUBVERSION 6
/** Several breakages with 280, e.g. collections vs layers. */
#define BLENDER_MINVERSION 280
#define BLENDER_MINSUBVERSION 0

View File

@ -66,4 +66,23 @@ void BKE_fluid_particle_system_create(struct Main *bmain,
const int psys_type);
void BKE_fluid_particle_system_destroy(struct Object *ob, const int particle_type);
void BKE_fluid_cachetype_mesh_set(struct FluidDomainSettings *settings, int cache_mesh_format);
void BKE_fluid_cachetype_data_set(struct FluidDomainSettings *settings, int cache_data_format);
void BKE_fluid_cachetype_particle_set(struct FluidDomainSettings *settings,
int cache_particle_format);
void BKE_fluid_cachetype_noise_set(struct FluidDomainSettings *settings, int cache_noise_format);
void BKE_fluid_collisionextents_set(struct FluidDomainSettings *settings, int value, bool clear);
void BKE_fluid_particles_set(struct FluidDomainSettings *settings, int value, bool clear);
void BKE_fluid_domain_type_set(struct Object *object,
struct FluidDomainSettings *settings,
int type);
void BKE_fluid_flow_type_set(struct Object *object, struct FluidFlowSettings *settings, int type);
void BKE_fluid_effector_type_set(struct Object *object,
struct FluidEffectorSettings *settings,
int type);
void BKE_fluid_flow_behavior_set(struct Object *object,
struct FluidFlowSettings *settings,
int behavior);
#endif /* __BKE_FLUID_H__ */

View File

@ -4803,4 +4803,121 @@ void BKE_fluid_particle_system_destroy(struct Object *ob, const int particle_typ
}
}
void BKE_fluid_cachetype_mesh_set(FluidDomainSettings *settings, int cache_mesh_format)
{
if (cache_mesh_format == settings->cache_mesh_format) {
return;
}
/* TODO(sebbas): Clear old caches. */
settings->cache_mesh_format = cache_mesh_format;
}
void BKE_fluid_cachetype_data_set(FluidDomainSettings *settings, int cache_data_format)
{
if (cache_data_format == settings->cache_data_format) {
return;
}
/* TODO(sebbas): Clear old caches. */
settings->cache_data_format = cache_data_format;
}
void BKE_fluid_cachetype_particle_set(FluidDomainSettings *settings, int cache_particle_format)
{
if (cache_particle_format == settings->cache_particle_format) {
return;
}
/* TODO(sebbas): Clear old caches. */
settings->cache_particle_format = cache_particle_format;
}
void BKE_fluid_cachetype_noise_set(FluidDomainSettings *settings, int cache_noise_format)
{
if (cache_noise_format == settings->cache_noise_format) {
return;
}
/* TODO(sebbas): Clear old caches. */
settings->cache_noise_format = cache_noise_format;
}
void BKE_fluid_collisionextents_set(FluidDomainSettings *settings, int value, bool clear)
{
if (clear) {
settings->border_collisions &= value;
}
else {
settings->border_collisions |= value;
}
}
void BKE_fluid_particles_set(FluidDomainSettings *settings, int value, bool clear)
{
if (clear) {
settings->particle_type &= ~value;
}
else {
settings->border_collisions |= value;
}
}
void BKE_fluid_domain_type_set(Object *object, FluidDomainSettings *settings, int type)
{
/* Set common values for liquid/smoke domain: cache type,
* border collision and viewport draw-type. */
if (type == FLUID_DOMAIN_TYPE_GAS) {
BKE_fluid_cachetype_mesh_set(settings, FLUID_DOMAIN_FILE_BIN_OBJECT);
BKE_fluid_cachetype_data_set(settings, FLUID_DOMAIN_FILE_UNI);
BKE_fluid_cachetype_particle_set(settings, FLUID_DOMAIN_FILE_UNI);
BKE_fluid_cachetype_noise_set(settings, FLUID_DOMAIN_FILE_UNI);
BKE_fluid_collisionextents_set(settings, FLUID_DOMAIN_BORDER_FRONT, 1);
BKE_fluid_collisionextents_set(settings, FLUID_DOMAIN_BORDER_BACK, 1);
BKE_fluid_collisionextents_set(settings, FLUID_DOMAIN_BORDER_RIGHT, 1);
BKE_fluid_collisionextents_set(settings, FLUID_DOMAIN_BORDER_LEFT, 1);
BKE_fluid_collisionextents_set(settings, FLUID_DOMAIN_BORDER_TOP, 1);
BKE_fluid_collisionextents_set(settings, FLUID_DOMAIN_BORDER_BOTTOM, 1);
object->dt = OB_WIRE;
}
else if (type == FLUID_DOMAIN_TYPE_LIQUID) {
BKE_fluid_cachetype_mesh_set(settings, FLUID_DOMAIN_FILE_BIN_OBJECT);
BKE_fluid_cachetype_data_set(settings, FLUID_DOMAIN_FILE_UNI);
BKE_fluid_cachetype_particle_set(settings, FLUID_DOMAIN_FILE_UNI);
BKE_fluid_cachetype_noise_set(settings, FLUID_DOMAIN_FILE_UNI);
BKE_fluid_collisionextents_set(settings, FLUID_DOMAIN_BORDER_FRONT, 0);
BKE_fluid_collisionextents_set(settings, FLUID_DOMAIN_BORDER_BACK, 0);
BKE_fluid_collisionextents_set(settings, FLUID_DOMAIN_BORDER_RIGHT, 0);
BKE_fluid_collisionextents_set(settings, FLUID_DOMAIN_BORDER_LEFT, 0);
BKE_fluid_collisionextents_set(settings, FLUID_DOMAIN_BORDER_TOP, 0);
BKE_fluid_collisionextents_set(settings, FLUID_DOMAIN_BORDER_BOTTOM, 0);
BKE_fluid_particles_set(settings, FLUID_DOMAIN_PARTICLE_FLIP, 0);
object->dt = OB_SOLID;
}
/* Set actual domain type. */
settings->type = type;
}
void BKE_fluid_flow_behavior_set(Object *UNUSED(object), FluidFlowSettings *settings, int behavior)
{
settings->behavior = behavior;
}
void BKE_fluid_flow_type_set(Object *object, FluidFlowSettings *settings, int type)
{
/* By default, liquid flow objects should behave like their geometry (geomtery behavior),
* gas flow objects should continously produce smoke (inflow behavior). */
if (type == FLUID_FLOW_TYPE_LIQUID) {
BKE_fluid_flow_behavior_set(object, settings, FLUID_FLOW_BEHAVIOR_GEOMETRY);
}
else {
BKE_fluid_flow_behavior_set(object, settings, FLUID_FLOW_BEHAVIOR_INFLOW);
}
/* Set actual flow type. */
settings->type = type;
}
void BKE_fluid_effector_type_set(Object *UNUSED(object), FluidEffectorSettings *settings, int type)
{
settings->type = type;
}
#endif /* WITH_FLUID */

View File

@ -113,6 +113,7 @@
#include "BKE_curve.h"
#include "BKE_effect.h"
#include "BKE_fcurve.h"
#include "BKE_fluid.h"
#include "BKE_global.h" // for G
#include "BKE_gpencil_modifier.h"
#include "BKE_idcode.h"
@ -239,7 +240,7 @@
/* local prototypes */
static void read_libraries(FileData *basefd, ListBase *mainlist);
static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
static void direct_link_modifiers(FileData *fd, ListBase *lb, const Object *ob);
static void direct_link_modifiers(FileData *fd, ListBase *lb, Object *ob);
static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name);
static BHead *find_bhead_from_idname(FileData *fd, const char *idname);
@ -5485,7 +5486,118 @@ static void direct_link_pose(FileData *fd, bPose *pose)
}
}
static void direct_link_modifiers(FileData *fd, ListBase *lb, const Object *ob)
/* TODO(sergey): Find a more better place for this.
*
* Unfortunately, this can not be done as a regular do_versions() since the modifier type is
* set to NONE, so the do_versions code wouldn't know where the modifier came from.
*
* Most bestest approach seems to have the functionality in versioning_280 but still call the
* function from direct_link_modifiers(). */
/* Domain, inflow, ... */
static void modifier_ensure_type(FluidModifierData *fluid_modifier_data, int type)
{
fluid_modifier_data->type = type;
BKE_fluid_modifier_free(fluid_modifier_data);
BKE_fluid_modifier_create_type_data(fluid_modifier_data);
}
/* NOTE: The old_modifier_data is NOT linked. This means that in ordet to access subdata
* pointers newdataadr is to be used. */
static ModifierData *modifier_replace_with_fluid(FileData *fd,
Object *object,
ListBase *modifiers,
ModifierData *old_modifier_data)
{
ModifierData *new_modifier_data = modifier_new(eModifierType_Fluid);
FluidModifierData *fluid_modifier_data = (FluidModifierData *)new_modifier_data;
if (old_modifier_data->type == eModifierType_Fluidsim) {
FluidsimModifierData *old_fluidsim_modifier_data = (FluidsimModifierData *)old_modifier_data;
FluidsimSettings *old_fluidsim_settings = newdataadr(fd, old_fluidsim_modifier_data->fss);
switch (old_fluidsim_settings->type) {
case OB_FLUIDSIM_ENABLE:
modifier_ensure_type(fluid_modifier_data, 0);
break;
case OB_FLUIDSIM_DOMAIN:
modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_DOMAIN);
BKE_fluid_domain_type_set(object, fluid_modifier_data->domain, FLUID_DOMAIN_TYPE_LIQUID);
break;
case OB_FLUIDSIM_FLUID:
modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_FLOW);
BKE_fluid_flow_type_set(object, fluid_modifier_data->flow, FLUID_FLOW_TYPE_LIQUID);
/* No need to emit liquid far away from surface. */
fluid_modifier_data->flow->surface_distance = 0.0f;
break;
case OB_FLUIDSIM_OBSTACLE:
modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_EFFEC);
BKE_fluid_effector_type_set(
object, fluid_modifier_data->effector, FLUID_EFFECTOR_TYPE_COLLISION);
break;
case OB_FLUIDSIM_INFLOW:
modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_FLOW);
BKE_fluid_flow_type_set(object, fluid_modifier_data->flow, FLUID_FLOW_TYPE_LIQUID);
BKE_fluid_flow_behavior_set(object, fluid_modifier_data->flow, FLUID_FLOW_BEHAVIOR_INFLOW);
/* No need to emit liquid far away from surface. */
fluid_modifier_data->flow->surface_distance = 0.0f;
break;
case OB_FLUIDSIM_OUTFLOW:
modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_FLOW);
BKE_fluid_flow_type_set(object, fluid_modifier_data->flow, FLUID_FLOW_TYPE_LIQUID);
BKE_fluid_flow_behavior_set(
object, fluid_modifier_data->flow, FLUID_FLOW_BEHAVIOR_OUTFLOW);
break;
case OB_FLUIDSIM_PARTICLE:
/* "Particle" type objects not being used by Mantaflow fluid simulations.
* Skip this object, secondary particles can only be enabled through the domain object. */
break;
case OB_FLUIDSIM_CONTROL:
/* "Control" type objects not being used by Mantaflow fluid simulations.
* Use guiding type instead which is similar. */
modifier_ensure_type(fluid_modifier_data, MOD_FLUID_TYPE_EFFEC);
BKE_fluid_effector_type_set(
object, fluid_modifier_data->effector, FLUID_EFFECTOR_TYPE_GUIDE);
break;
}
}
else if (old_modifier_data->type == eModifierType_Smoke) {
SmokeModifierData *old_smoke_modifier_data = (SmokeModifierData *)old_modifier_data;
modifier_ensure_type(fluid_modifier_data, old_smoke_modifier_data->type);
if (fluid_modifier_data->type == MOD_FLUID_TYPE_DOMAIN) {
BKE_fluid_domain_type_set(object, fluid_modifier_data->domain, FLUID_DOMAIN_TYPE_GAS);
}
else if (fluid_modifier_data->type == MOD_FLUID_TYPE_FLOW) {
BKE_fluid_flow_type_set(object, fluid_modifier_data->flow, FLUID_FLOW_TYPE_SMOKE);
}
else if (fluid_modifier_data->type == MOD_FLUID_TYPE_EFFEC) {
BKE_fluid_effector_type_set(
object, fluid_modifier_data->effector, FLUID_EFFECTOR_TYPE_COLLISION);
}
}
/* Replace modifier data in the stack. */
new_modifier_data->next = old_modifier_data->next;
new_modifier_data->prev = old_modifier_data->prev;
if (new_modifier_data->prev != NULL) {
new_modifier_data->prev->next = new_modifier_data;
}
if (new_modifier_data->next != NULL) {
new_modifier_data->next->prev = new_modifier_data;
}
if (modifiers->first == old_modifier_data) {
modifiers->first = new_modifier_data;
}
if (modifiers->last == old_modifier_data) {
modifiers->last = new_modifier_data;
}
/* Free old modifier data. */
MEM_freeN(old_modifier_data);
return new_modifier_data;
}
static void direct_link_modifiers(FileData *fd, ListBase *lb, Object *ob)
{
ModifierData *md;
@ -5495,6 +5607,10 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb, const Object *ob)
md->error = NULL;
md->runtime = NULL;
/* Modifier data has been allocated as a part of data migration process and
* no reading of nested fields from file is needed. */
bool is_allocated = false;
if (md->type == eModifierType_Fluidsim) {
blo_reportf_wrap(
fd->reports,
@ -5503,6 +5619,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb, const Object *ob)
"Possible data loss when saving this file! %s modifier is deprecated (Object: %s)."),
md->name,
ob->id.name + 2);
md = modifier_replace_with_fluid(fd, ob, lb, md);
is_allocated = true;
}
else if (md->type == eModifierType_Smoke) {
blo_reportf_wrap(
@ -5512,13 +5630,18 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb, const Object *ob)
"Possible data loss when saving this file! %s modifier is deprecated (Object: %s)."),
md->name,
ob->id.name + 2);
md = modifier_replace_with_fluid(fd, ob, lb, md);
is_allocated = true;
}
/* if modifiers disappear, or for upward compatibility */
if (NULL == modifierType_getInfo(md->type)) {
md->type = eModifierType_None;
}
if (md->type == eModifierType_Subsurf) {
if (is_allocated) {
/* All the fields has been properly allocated. */
}
else if (md->type == eModifierType_Subsurf) {
SubsurfModifierData *smd = (SubsurfModifierData *)md;
smd->emCache = smd->mCache = NULL;

View File

@ -991,6 +991,10 @@ typedef struct FluidsimModifierData {
/* DEPRECATED, only used for versioning. */
typedef struct SmokeModifierData {
ModifierData modifier;
/** Domain, inflow, outflow, .... */
int type;
int _pad;
} SmokeModifierData;
typedef struct ShrinkwrapModifierData {

View File

@ -407,41 +407,25 @@ static void rna_Fluid_combined_export_update(Main *bmain, Scene *scene, PointerR
static void rna_Fluid_cachetype_mesh_set(struct PointerRNA *ptr, int value)
{
FluidDomainSettings *settings = (FluidDomainSettings *)ptr->data;
if (value != settings->cache_mesh_format) {
/* TODO (sebbas): Clear old caches. */
settings->cache_mesh_format = value;
}
BKE_fluid_cachetype_mesh_set(settings, value);
}
static void rna_Fluid_cachetype_data_set(struct PointerRNA *ptr, int value)
{
FluidDomainSettings *settings = (FluidDomainSettings *)ptr->data;
if (value != settings->cache_data_format) {
/* TODO (sebbas): Clear old caches. */
settings->cache_data_format = value;
}
BKE_fluid_cachetype_data_set(settings, value);
}
static void rna_Fluid_cachetype_particle_set(struct PointerRNA *ptr, int value)
{
FluidDomainSettings *settings = (FluidDomainSettings *)ptr->data;
if (value != settings->cache_particle_format) {
/* TODO (sebbas): Clear old caches. */
settings->cache_particle_format = value;
}
BKE_fluid_cachetype_particle_set(settings, value);
}
static void rna_Fluid_cachetype_noise_set(struct PointerRNA *ptr, int value)
{
FluidDomainSettings *settings = (FluidDomainSettings *)ptr->data;
if (value != settings->cache_noise_format) {
/* TODO (sebbas): Clear old caches. */
settings->cache_noise_format = value;
}
BKE_fluid_cachetype_noise_set(settings, value);
}
static void rna_Fluid_cachetype_set(struct PointerRNA *ptr, int value)
@ -558,17 +542,6 @@ static const EnumPropertyItem *rna_Fluid_cachetype_particle_itemf(bContext *UNUS
return item;
}
static void rna_Fluid_collisionextents_set(struct PointerRNA *ptr, int value, bool clear)
{
FluidDomainSettings *settings = (FluidDomainSettings *)ptr->data;
if (clear) {
settings->border_collisions &= value;
}
else {
settings->border_collisions |= value;
}
}
static void rna_Fluid_cache_directory_set(struct PointerRNA *ptr, const char *value)
{
FluidDomainSettings *settings = (FluidDomainSettings *)ptr->data;
@ -588,40 +561,7 @@ static void rna_Fluid_domaintype_set(struct PointerRNA *ptr, int value)
{
FluidDomainSettings *settings = (FluidDomainSettings *)ptr->data;
Object *ob = (Object *)ptr->owner_id;
if (value != settings->type) {
/* Set common values for liquid/smoke domain: cache type,
* border collision and viewport draw-type. */
if (value == FLUID_DOMAIN_TYPE_GAS) {
rna_Fluid_cachetype_mesh_set(ptr, FLUID_DOMAIN_FILE_BIN_OBJECT);
rna_Fluid_cachetype_data_set(ptr, FLUID_DOMAIN_FILE_UNI);
rna_Fluid_cachetype_particle_set(ptr, FLUID_DOMAIN_FILE_UNI);
rna_Fluid_cachetype_noise_set(ptr, FLUID_DOMAIN_FILE_UNI);
rna_Fluid_collisionextents_set(ptr, FLUID_DOMAIN_BORDER_FRONT, 1);
rna_Fluid_collisionextents_set(ptr, FLUID_DOMAIN_BORDER_BACK, 1);
rna_Fluid_collisionextents_set(ptr, FLUID_DOMAIN_BORDER_RIGHT, 1);
rna_Fluid_collisionextents_set(ptr, FLUID_DOMAIN_BORDER_LEFT, 1);
rna_Fluid_collisionextents_set(ptr, FLUID_DOMAIN_BORDER_TOP, 1);
rna_Fluid_collisionextents_set(ptr, FLUID_DOMAIN_BORDER_BOTTOM, 1);
ob->dt = OB_WIRE;
}
else if (value == FLUID_DOMAIN_TYPE_LIQUID) {
rna_Fluid_cachetype_mesh_set(ptr, FLUID_DOMAIN_FILE_BIN_OBJECT);
rna_Fluid_cachetype_data_set(ptr, FLUID_DOMAIN_FILE_UNI);
rna_Fluid_cachetype_particle_set(ptr, FLUID_DOMAIN_FILE_UNI);
rna_Fluid_cachetype_noise_set(ptr, FLUID_DOMAIN_FILE_UNI);
rna_Fluid_collisionextents_set(ptr, FLUID_DOMAIN_BORDER_FRONT, 0);
rna_Fluid_collisionextents_set(ptr, FLUID_DOMAIN_BORDER_BACK, 0);
rna_Fluid_collisionextents_set(ptr, FLUID_DOMAIN_BORDER_RIGHT, 0);
rna_Fluid_collisionextents_set(ptr, FLUID_DOMAIN_BORDER_LEFT, 0);
rna_Fluid_collisionextents_set(ptr, FLUID_DOMAIN_BORDER_TOP, 0);
rna_Fluid_collisionextents_set(ptr, FLUID_DOMAIN_BORDER_BOTTOM, 0);
ob->dt = OB_SOLID;
}
/* Set actual domain type */
settings->type = value;
}
BKE_fluid_domain_type_set(ob, settings, value);
}
static char *rna_FluidDomainSettings_path(PointerRNA *ptr)