2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2009-01-24 13:45:24 +00: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,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2009-01-24 13:45:24 +00:00
|
|
|
*
|
|
|
|
|
* The Original Code is Copyright (C) Blender Foundation
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*/
|
|
|
|
|
|
2019-12-17 09:20:32 +11:00
|
|
|
/** \file
|
2020-03-20 12:23:04 +11:00
|
|
|
* \ingroup edphys
|
2011-02-27 20:29:51 +00:00
|
|
|
*/
|
|
|
|
|
|
2009-01-24 13:45:24 +00:00
|
|
|
#include <math.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
|
|
/* types */
|
2010-03-25 06:27:25 +00:00
|
|
|
#include "DNA_action_types.h"
|
|
|
|
|
#include "DNA_object_types.h"
|
2009-01-24 13:45:24 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
#include "BLI_blenlib.h"
|
|
|
|
|
#include "BLI_math.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_path_util.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2009-01-24 13:45:24 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
#include "BLT_translation.h"
|
|
|
|
|
|
2009-01-24 13:45:24 +00:00
|
|
|
#include "BKE_context.h"
|
|
|
|
|
#include "BKE_customdata.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_fluid.h"
|
|
|
|
|
#include "BKE_global.h"
|
2019-12-16 15:46:47 +01:00
|
|
|
#include "BKE_main.h"
|
2009-07-02 19:41:31 +00:00
|
|
|
#include "BKE_modifier.h"
|
2009-01-24 13:45:24 +00:00
|
|
|
#include "BKE_object.h"
|
2009-07-02 19:41:31 +00:00
|
|
|
#include "BKE_report.h"
|
|
|
|
|
#include "BKE_scene.h"
|
2019-12-16 15:46:47 +01:00
|
|
|
#include "BKE_screen.h"
|
2009-01-24 13:45:24 +00:00
|
|
|
|
2017-07-21 11:53:13 +02:00
|
|
|
#include "DEG_depsgraph.h"
|
|
|
|
|
|
2020-05-22 13:43:53 +02:00
|
|
|
#include "ED_object.h"
|
2.5
Smaller jobs, all in one commit!
- Moved object_do_update out of view3d drawing, into
the event system (currently after notifiers).
Depsgraph calls for setting update flags will have to
keep track of each Screen's needs, so a UI showing only
a Sequencer doesn't do objects.
- Added button in "Properties region" in 3D window to set
or disable 4-split, including the 3 options it has.
(lock, box, clip)
- Restored legacy code for UI, to make things work like
bone rename, autocomplete.
- Node editor now shows Curves widgets again
- Bugfix: composite job increased Viewer user id count
- Bugfix: Node editor, not "Enable nodes" still called
a Job, which didn't do anything
- Various code cleaning, unused vars and prototypes.
2009-02-11 16:54:55 +00:00
|
|
|
#include "ED_screen.h"
|
2019-12-16 15:46:47 +01:00
|
|
|
#include "PIL_time.h"
|
2009-01-24 13:45:24 +00:00
|
|
|
|
2011-03-23 01:50:14 +00:00
|
|
|
#include "WM_api.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "WM_types.h"
|
2009-07-02 19:41:31 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
#include "manta_fluid_API.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "physics_intern.h" // own include
|
2019-12-16 15:46:47 +01:00
|
|
|
|
|
|
|
|
#include "DNA_fluid_types.h"
|
|
|
|
|
#include "DNA_mesh_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_scene_types.h"
|
2019-12-16 15:46:47 +01:00
|
|
|
|
|
|
|
|
#define FLUID_JOB_BAKE_ALL "FLUID_OT_bake_all"
|
|
|
|
|
#define FLUID_JOB_BAKE_DATA "FLUID_OT_bake_data"
|
|
|
|
|
#define FLUID_JOB_BAKE_NOISE "FLUID_OT_bake_noise"
|
|
|
|
|
#define FLUID_JOB_BAKE_MESH "FLUID_OT_bake_mesh"
|
|
|
|
|
#define FLUID_JOB_BAKE_PARTICLES "FLUID_OT_bake_particles"
|
2019-12-17 14:00:19 +11:00
|
|
|
#define FLUID_JOB_BAKE_GUIDES "FLUID_OT_bake_guides"
|
2019-12-16 15:46:47 +01:00
|
|
|
#define FLUID_JOB_FREE_ALL "FLUID_OT_free_all"
|
|
|
|
|
#define FLUID_JOB_FREE_DATA "FLUID_OT_free_data"
|
|
|
|
|
#define FLUID_JOB_FREE_NOISE "FLUID_OT_free_noise"
|
|
|
|
|
#define FLUID_JOB_FREE_MESH "FLUID_OT_free_mesh"
|
|
|
|
|
#define FLUID_JOB_FREE_PARTICLES "FLUID_OT_free_particles"
|
2019-12-17 14:00:19 +11:00
|
|
|
#define FLUID_JOB_FREE_GUIDES "FLUID_OT_free_guides"
|
2019-12-16 15:46:47 +01:00
|
|
|
#define FLUID_JOB_BAKE_PAUSE "FLUID_OT_pause_bake"
|
|
|
|
|
|
|
|
|
|
typedef struct FluidJob {
|
|
|
|
|
/* from wmJob */
|
|
|
|
|
void *owner;
|
|
|
|
|
short *stop, *do_update;
|
|
|
|
|
float *progress;
|
|
|
|
|
const char *type;
|
|
|
|
|
const char *name;
|
Sorry, three commits in one, became difficult to untangle..
Editors Modules
* render/ module added in editors, moved the preview render code there and
also shading related operators.
* physics/ module made more consistent with other modules. renaming files,
making a single physics_ops.c for operators and keymaps. Also move all
particle related operators here now.
* space_buttons/ now should have only operators relevant to the buttons
specificially.
Updates & Notifiers
* Material/Texture/World/Lamp can now be passed to DAG_id_flush_update,
which will go back to a callback in editors. Eventually these should
be in the depsgraph itself, but for now this gives a unified call for
doing updates.
* GLSL materials are now refreshed on changes. There's still various
cases missing,
* Preview icons now hook into this system, solving various update cases
that were missed before.
* Also fixes issue in my last commit, where some preview would not render,
problem is avoided in the new system.
Icon Rendering
* On systems with support for non-power of two textures, an OpenGL texture
is now used instead of glDrawPixels. This avoids problems with icons get
clipped on region borders. On my Linux desktop, this gives an 1.1x speedup,
and on my Mac laptop a 2.3x speedup overall in redrawing the full window,
with the default setup. The glDrawPixels implementation on Mac seems to
have a lot of overhread.
* Preview icons are now drawn using proper premul alpha, and never faded so
you can see them clearly.
* Also tried to fix issue with texture node preview rendering, globals can't
be used with threads reliably.
2009-09-29 19:12:12 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
struct Main *bmain;
|
|
|
|
|
Scene *scene;
|
|
|
|
|
Depsgraph *depsgraph;
|
|
|
|
|
Object *ob;
|
2019-01-26 20:41:52 +11:00
|
|
|
|
2020-07-03 11:51:15 +02:00
|
|
|
FluidModifierData *fmd;
|
2018-04-01 07:24:45 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
int success;
|
|
|
|
|
double start;
|
2010-03-23 14:09:09 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
int *pause_frame;
|
|
|
|
|
} FluidJob;
|
2010-03-25 06:27:25 +00:00
|
|
|
|
2019-12-17 08:58:43 +11:00
|
|
|
static inline bool fluid_is_bake_all(FluidJob *job)
|
|
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
return (STREQ(job->type, FLUID_JOB_BAKE_ALL));
|
2010-03-25 06:27:25 +00:00
|
|
|
}
|
2019-12-17 08:58:43 +11:00
|
|
|
static inline bool fluid_is_bake_data(FluidJob *job)
|
|
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
return (STREQ(job->type, FLUID_JOB_BAKE_DATA));
|
2012-01-22 03:42:49 +00:00
|
|
|
}
|
2019-12-17 08:58:43 +11:00
|
|
|
static inline bool fluid_is_bake_noise(FluidJob *job)
|
|
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
return (STREQ(job->type, FLUID_JOB_BAKE_NOISE));
|
|
|
|
|
}
|
2019-12-17 08:58:43 +11:00
|
|
|
static inline bool fluid_is_bake_mesh(FluidJob *job)
|
|
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
return (STREQ(job->type, FLUID_JOB_BAKE_MESH));
|
|
|
|
|
}
|
2019-12-17 08:58:43 +11:00
|
|
|
static inline bool fluid_is_bake_particle(FluidJob *job)
|
|
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
return (STREQ(job->type, FLUID_JOB_BAKE_PARTICLES));
|
|
|
|
|
}
|
2019-12-17 08:58:43 +11:00
|
|
|
static inline bool fluid_is_bake_guiding(FluidJob *job)
|
|
|
|
|
{
|
2019-12-17 14:00:19 +11:00
|
|
|
return (STREQ(job->type, FLUID_JOB_BAKE_GUIDES));
|
2019-12-16 15:46:47 +01:00
|
|
|
}
|
2019-12-17 08:58:43 +11:00
|
|
|
static inline bool fluid_is_free_all(FluidJob *job)
|
|
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
return (STREQ(job->type, FLUID_JOB_FREE_ALL));
|
|
|
|
|
}
|
2019-12-17 08:58:43 +11:00
|
|
|
static inline bool fluid_is_free_data(FluidJob *job)
|
|
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
return (STREQ(job->type, FLUID_JOB_FREE_DATA));
|
|
|
|
|
}
|
2019-12-17 08:58:43 +11:00
|
|
|
static inline bool fluid_is_free_noise(FluidJob *job)
|
|
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
return (STREQ(job->type, FLUID_JOB_FREE_NOISE));
|
|
|
|
|
}
|
2019-12-17 08:58:43 +11:00
|
|
|
static inline bool fluid_is_free_mesh(FluidJob *job)
|
|
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
return (STREQ(job->type, FLUID_JOB_FREE_MESH));
|
|
|
|
|
}
|
2019-12-17 08:58:43 +11:00
|
|
|
static inline bool fluid_is_free_particles(FluidJob *job)
|
|
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
return (STREQ(job->type, FLUID_JOB_FREE_PARTICLES));
|
|
|
|
|
}
|
2019-12-17 08:58:43 +11:00
|
|
|
static inline bool fluid_is_free_guiding(FluidJob *job)
|
|
|
|
|
{
|
2019-12-17 14:00:19 +11:00
|
|
|
return (STREQ(job->type, FLUID_JOB_FREE_GUIDES));
|
2010-03-25 06:27:25 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
static bool fluid_initjob(
|
|
|
|
|
bContext *C, FluidJob *job, wmOperator *op, char *error_msg, int error_size)
|
2010-03-25 06:27:25 +00:00
|
|
|
{
|
2020-07-03 11:51:15 +02:00
|
|
|
FluidModifierData *fmd = NULL;
|
|
|
|
|
FluidDomainSettings *fds;
|
2020-05-22 13:43:53 +02:00
|
|
|
Object *ob = ED_object_active_context(C);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-07-03 11:51:15 +02:00
|
|
|
fmd = (FluidModifierData *)BKE_modifiers_findby_type(ob, eModifierType_Fluid);
|
|
|
|
|
if (!fmd) {
|
2019-12-16 15:46:47 +01:00
|
|
|
BLI_strncpy(error_msg, N_("Bake failed: no Fluid modifier found"), error_size);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2020-07-03 11:51:15 +02:00
|
|
|
fds = fmd->domain;
|
|
|
|
|
if (!fds) {
|
2019-12-16 15:46:47 +01:00
|
|
|
BLI_strncpy(error_msg, N_("Bake failed: invalid domain"), error_size);
|
|
|
|
|
return false;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2010-03-25 06:27:25 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
job->bmain = CTX_data_main(C);
|
|
|
|
|
job->scene = CTX_data_scene(C);
|
|
|
|
|
job->depsgraph = CTX_data_depsgraph_pointer(C);
|
2020-05-22 13:43:53 +02:00
|
|
|
job->ob = ob;
|
2020-07-03 11:51:15 +02:00
|
|
|
job->fmd = fmd;
|
2019-12-16 15:46:47 +01:00
|
|
|
job->type = op->type->idname;
|
|
|
|
|
job->name = op->type->name;
|
2009-01-24 13:45:24 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
2009-01-24 13:45:24 +00:00
|
|
|
|
2020-01-14 12:13:50 +01:00
|
|
|
static bool fluid_validatepaths(FluidJob *job, ReportList *reports)
|
2011-12-30 07:55:15 +00:00
|
|
|
{
|
2020-07-03 11:51:15 +02:00
|
|
|
FluidDomainSettings *fds = job->fmd->domain;
|
2019-12-17 11:45:35 +11:00
|
|
|
char temp_dir[FILE_MAX];
|
|
|
|
|
temp_dir[0] = '\0';
|
2020-01-14 12:13:50 +01:00
|
|
|
bool is_relative = false;
|
2009-01-24 13:45:24 +00:00
|
|
|
|
2020-05-08 10:14:02 +02:00
|
|
|
const char *relbase = BKE_modifier_path_relbase(job->bmain, job->ob);
|
2010-03-25 06:27:25 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* We do not accept empty paths, they can end in random places silently, see T51176. */
|
2020-07-03 11:51:15 +02:00
|
|
|
if (fds->cache_directory[0] == '\0') {
|
2020-03-10 17:32:38 +01:00
|
|
|
char cache_name[64];
|
|
|
|
|
BKE_fluid_cache_new_name_for_current_session(sizeof(cache_name), cache_name);
|
2020-07-03 11:51:15 +02:00
|
|
|
BKE_modifier_path_init(fds->cache_directory, sizeof(fds->cache_directory), cache_name);
|
2019-12-16 15:46:47 +01:00
|
|
|
BKE_reportf(reports,
|
|
|
|
|
RPT_WARNING,
|
|
|
|
|
"Fluid: Empty cache path, reset to default '%s'",
|
2020-07-03 11:51:15 +02:00
|
|
|
fds->cache_directory);
|
2019-12-16 15:46:47 +01:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-07-03 11:51:15 +02:00
|
|
|
BLI_strncpy(temp_dir, fds->cache_directory, FILE_MAXDIR);
|
2020-01-14 12:13:50 +01:00
|
|
|
is_relative = BLI_path_abs(temp_dir, relbase);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* Ensure whole path exists */
|
2019-12-17 11:45:35 +11:00
|
|
|
const bool dir_exists = BLI_dir_create_recursive(temp_dir);
|
2010-03-25 06:27:25 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* We change path to some presumably valid default value, but do not allow bake process to
|
|
|
|
|
* continue, this gives user chance to set manually another path. */
|
|
|
|
|
if (!dir_exists) {
|
2020-03-10 17:32:38 +01:00
|
|
|
char cache_name[64];
|
|
|
|
|
BKE_fluid_cache_new_name_for_current_session(sizeof(cache_name), cache_name);
|
2020-07-03 11:51:15 +02:00
|
|
|
BKE_modifier_path_init(fds->cache_directory, sizeof(fds->cache_directory), cache_name);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
BKE_reportf(reports,
|
|
|
|
|
RPT_ERROR,
|
|
|
|
|
"Fluid: Could not create cache directory '%s', reset to default '%s'",
|
2019-12-17 11:45:35 +11:00
|
|
|
temp_dir,
|
2020-07-03 11:51:15 +02:00
|
|
|
fds->cache_directory);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* Ensure whole path exists and is writable. */
|
2019-12-17 11:45:35 +11:00
|
|
|
if (!BLI_dir_create_recursive(temp_dir)) {
|
2019-12-16 15:46:47 +01:00
|
|
|
BKE_reportf(reports,
|
|
|
|
|
RPT_ERROR,
|
|
|
|
|
"Fluid: Could not use default cache directory '%s', "
|
|
|
|
|
"please define a valid cache path manually",
|
2019-12-17 11:45:35 +11:00
|
|
|
temp_dir);
|
2020-01-14 12:13:50 +01:00
|
|
|
return false;
|
2019-12-16 15:46:47 +01:00
|
|
|
}
|
|
|
|
|
/* Copy final dir back into domain settings */
|
2020-07-03 11:51:15 +02:00
|
|
|
BLI_strncpy(fds->cache_directory, temp_dir, FILE_MAXDIR);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-01-14 12:13:50 +01:00
|
|
|
/* Change path back to is original state (ie relative or absolute). */
|
|
|
|
|
if (is_relative) {
|
|
|
|
|
BLI_path_rel(temp_dir, relbase);
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* Copy final dir back into domain settings */
|
2020-07-03 11:51:15 +02:00
|
|
|
BLI_strncpy(fds->cache_directory, temp_dir, FILE_MAXDIR);
|
2019-12-16 15:46:47 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
2009-01-24 13:45:24 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
static void fluid_bake_free(void *customdata)
|
|
|
|
|
{
|
|
|
|
|
FluidJob *job = customdata;
|
|
|
|
|
MEM_freeN(job);
|
|
|
|
|
}
|
2009-01-24 13:45:24 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
static void fluid_bake_sequence(FluidJob *job)
|
2018-06-04 09:31:30 +02:00
|
|
|
{
|
2020-07-03 11:51:15 +02:00
|
|
|
FluidDomainSettings *fds = job->fmd->domain;
|
2019-12-16 15:46:47 +01:00
|
|
|
Scene *scene = job->scene;
|
|
|
|
|
int frame = 1, orig_frame;
|
|
|
|
|
int frames;
|
|
|
|
|
int *pause_frame = NULL;
|
|
|
|
|
bool is_first_frame;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-07-03 11:51:15 +02:00
|
|
|
frames = fds->cache_frame_end - fds->cache_frame_start + 1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
if (frames <= 0) {
|
2020-07-03 11:51:15 +02:00
|
|
|
BLI_strncpy(fds->error, N_("No frames to bake"), sizeof(fds->error));
|
2019-12-16 15:46:47 +01:00
|
|
|
return;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* Show progress bar. */
|
2019-12-17 09:51:38 +11:00
|
|
|
if (job->do_update) {
|
2019-12-16 15:46:47 +01:00
|
|
|
*(job->do_update) = true;
|
2019-12-17 09:51:38 +11:00
|
|
|
}
|
2010-03-25 06:27:25 +00:00
|
|
|
|
2020-06-24 15:30:49 +02:00
|
|
|
/* Get current pause frame (pointer) - depending on bake type. */
|
2019-12-16 15:46:47 +01:00
|
|
|
pause_frame = job->pause_frame;
|
2010-03-25 06:27:25 +00:00
|
|
|
|
2020-06-24 15:30:49 +02:00
|
|
|
/* Set frame to start point (depending on current pause frame value). */
|
2019-12-16 15:46:47 +01:00
|
|
|
is_first_frame = ((*pause_frame) == 0);
|
2020-07-03 11:51:15 +02:00
|
|
|
frame = is_first_frame ? fds->cache_frame_start : (*pause_frame);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-06-24 15:30:49 +02:00
|
|
|
/* Save orig frame and update scene frame. */
|
2019-12-16 15:46:47 +01:00
|
|
|
orig_frame = CFRA;
|
|
|
|
|
CFRA = frame;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-06-24 15:30:49 +02:00
|
|
|
/* Loop through selected frames. */
|
2020-07-03 11:51:15 +02:00
|
|
|
for (; frame <= fds->cache_frame_end; frame++) {
|
|
|
|
|
const float progress = (frame - fds->cache_frame_start) / (float)frames;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-06-24 15:30:49 +02:00
|
|
|
/* Keep track of pause frame - needed to init future loop. */
|
2019-12-16 15:46:47 +01:00
|
|
|
(*pause_frame) = frame;
|
2010-03-25 06:27:25 +00:00
|
|
|
|
2020-06-24 15:30:49 +02:00
|
|
|
/* If user requested stop, quit baking. */
|
2019-12-16 15:46:47 +01:00
|
|
|
if (G.is_break) {
|
|
|
|
|
job->success = 0;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-06-24 15:30:49 +02:00
|
|
|
/* Update progress bar. */
|
2019-12-17 09:51:38 +11:00
|
|
|
if (job->do_update) {
|
2019-12-16 15:46:47 +01:00
|
|
|
*(job->do_update) = true;
|
2019-12-17 09:51:38 +11:00
|
|
|
}
|
|
|
|
|
if (job->progress) {
|
2019-12-16 15:46:47 +01:00
|
|
|
*(job->progress) = progress;
|
2019-12-17 09:51:38 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
CFRA = frame;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-06-24 15:30:49 +02:00
|
|
|
/* Update animation system. */
|
2019-12-16 15:46:47 +01:00
|
|
|
ED_update_for_newframe(job->bmain, job->depsgraph);
|
2020-03-17 13:49:47 +01:00
|
|
|
|
2020-06-24 15:30:49 +02:00
|
|
|
/* If user requested stop, quit baking. */
|
2020-03-17 13:49:47 +01:00
|
|
|
if (G.is_break) {
|
|
|
|
|
job->success = 0;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2020-06-24 15:30:49 +02:00
|
|
|
/* Restore frame position that we were on before bake. */
|
2019-12-16 15:46:47 +01:00
|
|
|
CFRA = orig_frame;
|
2010-03-25 06:27:25 +00:00
|
|
|
}
|
2009-09-09 07:52:44 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
static void fluid_bake_endjob(void *customdata)
|
2010-03-25 06:27:25 +00:00
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
FluidJob *job = customdata;
|
2020-07-03 11:51:15 +02:00
|
|
|
FluidDomainSettings *fds = job->fmd->domain;
|
2019-12-16 15:46:47 +01:00
|
|
|
|
|
|
|
|
if (fluid_is_bake_noise(job) || fluid_is_bake_all(job)) {
|
2020-07-03 11:51:15 +02:00
|
|
|
fds->cache_flag &= ~FLUID_DOMAIN_BAKING_NOISE;
|
|
|
|
|
fds->cache_flag |= FLUID_DOMAIN_BAKED_NOISE;
|
|
|
|
|
fds->cache_flag &= ~FLUID_DOMAIN_OUTDATED_NOISE;
|
2019-12-16 15:46:47 +01:00
|
|
|
}
|
|
|
|
|
if (fluid_is_bake_mesh(job) || fluid_is_bake_all(job)) {
|
2020-07-03 11:51:15 +02:00
|
|
|
fds->cache_flag &= ~FLUID_DOMAIN_BAKING_MESH;
|
|
|
|
|
fds->cache_flag |= FLUID_DOMAIN_BAKED_MESH;
|
|
|
|
|
fds->cache_flag &= ~FLUID_DOMAIN_OUTDATED_MESH;
|
2019-12-16 15:46:47 +01:00
|
|
|
}
|
|
|
|
|
if (fluid_is_bake_particle(job) || fluid_is_bake_all(job)) {
|
2020-07-03 11:51:15 +02:00
|
|
|
fds->cache_flag &= ~FLUID_DOMAIN_BAKING_PARTICLES;
|
|
|
|
|
fds->cache_flag |= FLUID_DOMAIN_BAKED_PARTICLES;
|
|
|
|
|
fds->cache_flag &= ~FLUID_DOMAIN_OUTDATED_PARTICLES;
|
2019-12-16 15:46:47 +01:00
|
|
|
}
|
|
|
|
|
if (fluid_is_bake_guiding(job) || fluid_is_bake_all(job)) {
|
2020-07-03 11:51:15 +02:00
|
|
|
fds->cache_flag &= ~FLUID_DOMAIN_BAKING_GUIDE;
|
|
|
|
|
fds->cache_flag |= FLUID_DOMAIN_BAKED_GUIDE;
|
|
|
|
|
fds->cache_flag &= ~FLUID_DOMAIN_OUTDATED_GUIDE;
|
2019-12-16 15:46:47 +01:00
|
|
|
}
|
|
|
|
|
if (fluid_is_bake_data(job) || fluid_is_bake_all(job)) {
|
2020-07-03 11:51:15 +02:00
|
|
|
fds->cache_flag &= ~FLUID_DOMAIN_BAKING_DATA;
|
|
|
|
|
fds->cache_flag |= FLUID_DOMAIN_BAKED_DATA;
|
|
|
|
|
fds->cache_flag &= ~FLUID_DOMAIN_OUTDATED_DATA;
|
2019-12-16 15:46:47 +01:00
|
|
|
}
|
|
|
|
|
DEG_id_tag_update(&job->ob->id, ID_RECALC_GEOMETRY);
|
|
|
|
|
|
|
|
|
|
G.is_rendering = false;
|
|
|
|
|
BKE_spacedata_draw_locks(false);
|
|
|
|
|
WM_set_locked_interface(G_MAIN->wm.first, false);
|
|
|
|
|
|
|
|
|
|
/* Bake was successful:
|
2020-06-24 15:30:49 +02:00
|
|
|
* Report for ended bake and how long it took. */
|
2019-12-16 15:46:47 +01:00
|
|
|
if (job->success) {
|
2020-06-24 15:30:49 +02:00
|
|
|
/* Show bake info. */
|
2019-12-17 08:58:43 +11:00
|
|
|
WM_reportf(
|
|
|
|
|
RPT_INFO, "Fluid: %s complete! (%.2f)", job->name, PIL_check_seconds_timer() - job->start);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2019-12-16 15:46:47 +01:00
|
|
|
else {
|
2020-07-03 11:51:15 +02:00
|
|
|
if (fds->error[0] != '\0') {
|
|
|
|
|
WM_reportf(RPT_ERROR, "Fluid: %s failed: %s", job->name, fds->error);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2020-06-24 15:30:49 +02:00
|
|
|
else { /* User canceled the bake. */
|
2019-12-16 15:46:47 +01:00
|
|
|
WM_reportf(RPT_WARNING, "Fluid: %s canceled!", job->name);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2010-03-25 06:27:25 +00:00
|
|
|
}
|
2009-01-24 13:45:24 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
static void fluid_bake_startjob(void *customdata, short *stop, short *do_update, float *progress)
|
2010-03-25 06:27:25 +00:00
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
FluidJob *job = customdata;
|
2020-07-03 11:51:15 +02:00
|
|
|
FluidDomainSettings *fds = job->fmd->domain;
|
2019-12-16 15:46:47 +01:00
|
|
|
|
2019-12-17 11:45:35 +11:00
|
|
|
char temp_dir[FILE_MAX];
|
2020-05-08 10:14:02 +02:00
|
|
|
const char *relbase = BKE_modifier_path_relbase_from_global(job->ob);
|
2019-12-16 15:46:47 +01:00
|
|
|
|
|
|
|
|
job->stop = stop;
|
|
|
|
|
job->do_update = do_update;
|
|
|
|
|
job->progress = progress;
|
|
|
|
|
job->start = PIL_check_seconds_timer();
|
|
|
|
|
job->success = 1;
|
|
|
|
|
|
|
|
|
|
G.is_break = false;
|
|
|
|
|
G.is_rendering = true;
|
|
|
|
|
BKE_spacedata_draw_locks(true);
|
|
|
|
|
|
|
|
|
|
if (fluid_is_bake_noise(job) || fluid_is_bake_all(job)) {
|
2020-07-03 11:51:15 +02:00
|
|
|
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE, NULL);
|
2020-01-14 21:44:32 +01:00
|
|
|
BLI_path_abs(temp_dir, relbase);
|
2019-12-17 11:45:35 +11:00
|
|
|
BLI_dir_create_recursive(temp_dir); /* Create 'noise' subdir if it does not exist already */
|
2020-07-03 11:51:15 +02:00
|
|
|
fds->cache_flag &= ~(FLUID_DOMAIN_BAKED_NOISE | FLUID_DOMAIN_OUTDATED_NOISE);
|
|
|
|
|
fds->cache_flag |= FLUID_DOMAIN_BAKING_NOISE;
|
|
|
|
|
job->pause_frame = &fds->cache_frame_pause_noise;
|
2019-12-16 15:46:47 +01:00
|
|
|
}
|
|
|
|
|
if (fluid_is_bake_mesh(job) || fluid_is_bake_all(job)) {
|
2020-07-03 11:51:15 +02:00
|
|
|
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_MESH, NULL);
|
2020-01-14 21:44:32 +01:00
|
|
|
BLI_path_abs(temp_dir, relbase);
|
2019-12-17 11:45:35 +11:00
|
|
|
BLI_dir_create_recursive(temp_dir); /* Create 'mesh' subdir if it does not exist already */
|
2020-07-03 11:51:15 +02:00
|
|
|
fds->cache_flag &= ~(FLUID_DOMAIN_BAKED_MESH | FLUID_DOMAIN_OUTDATED_MESH);
|
|
|
|
|
fds->cache_flag |= FLUID_DOMAIN_BAKING_MESH;
|
|
|
|
|
job->pause_frame = &fds->cache_frame_pause_mesh;
|
2019-12-16 15:46:47 +01:00
|
|
|
}
|
|
|
|
|
if (fluid_is_bake_particle(job) || fluid_is_bake_all(job)) {
|
2019-12-17 11:45:35 +11:00
|
|
|
BLI_path_join(
|
2020-07-03 11:51:15 +02:00
|
|
|
temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_PARTICLES, NULL);
|
2020-01-14 21:44:32 +01:00
|
|
|
BLI_path_abs(temp_dir, relbase);
|
2019-12-17 11:45:35 +11:00
|
|
|
BLI_dir_create_recursive(
|
|
|
|
|
temp_dir); /* Create 'particles' subdir if it does not exist already */
|
2020-07-03 11:51:15 +02:00
|
|
|
fds->cache_flag &= ~(FLUID_DOMAIN_BAKED_PARTICLES | FLUID_DOMAIN_OUTDATED_PARTICLES);
|
|
|
|
|
fds->cache_flag |= FLUID_DOMAIN_BAKING_PARTICLES;
|
|
|
|
|
job->pause_frame = &fds->cache_frame_pause_particles;
|
2019-12-16 15:46:47 +01:00
|
|
|
}
|
|
|
|
|
if (fluid_is_bake_guiding(job) || fluid_is_bake_all(job)) {
|
2020-07-03 11:51:15 +02:00
|
|
|
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_GUIDE, NULL);
|
2020-01-14 21:44:32 +01:00
|
|
|
BLI_path_abs(temp_dir, relbase);
|
2019-12-17 11:45:35 +11:00
|
|
|
BLI_dir_create_recursive(temp_dir); /* Create 'guiding' subdir if it does not exist already */
|
2020-07-03 11:51:15 +02:00
|
|
|
fds->cache_flag &= ~(FLUID_DOMAIN_BAKED_GUIDE | FLUID_DOMAIN_OUTDATED_GUIDE);
|
|
|
|
|
fds->cache_flag |= FLUID_DOMAIN_BAKING_GUIDE;
|
|
|
|
|
job->pause_frame = &fds->cache_frame_pause_guide;
|
2019-12-16 15:46:47 +01:00
|
|
|
}
|
|
|
|
|
if (fluid_is_bake_data(job) || fluid_is_bake_all(job)) {
|
2020-07-03 11:51:15 +02:00
|
|
|
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_CONFIG, NULL);
|
2020-01-14 21:44:32 +01:00
|
|
|
BLI_path_abs(temp_dir, relbase);
|
2019-12-17 11:45:35 +11:00
|
|
|
BLI_dir_create_recursive(temp_dir); /* Create 'config' subdir if it does not exist already */
|
2019-12-17 12:11:28 +11:00
|
|
|
|
2020-07-03 11:51:15 +02:00
|
|
|
BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_DATA, NULL);
|
2020-01-14 21:44:32 +01:00
|
|
|
BLI_path_abs(temp_dir, relbase);
|
2019-12-17 11:45:35 +11:00
|
|
|
BLI_dir_create_recursive(temp_dir); /* Create 'data' subdir if it does not exist already */
|
2020-07-03 11:51:15 +02:00
|
|
|
fds->cache_flag &= ~(FLUID_DOMAIN_BAKED_DATA | FLUID_DOMAIN_OUTDATED_DATA);
|
|
|
|
|
fds->cache_flag |= FLUID_DOMAIN_BAKING_DATA;
|
|
|
|
|
job->pause_frame = &fds->cache_frame_pause_data;
|
2019-12-16 15:46:47 +01:00
|
|
|
|
2020-07-03 11:51:15 +02:00
|
|
|
if (fds->flags & FLUID_DOMAIN_EXPORT_MANTA_SCRIPT) {
|
2019-12-17 11:45:35 +11:00
|
|
|
BLI_path_join(
|
2020-07-03 11:51:15 +02:00
|
|
|
temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, NULL);
|
2020-01-14 21:44:32 +01:00
|
|
|
BLI_path_abs(temp_dir, relbase);
|
2019-12-17 11:45:35 +11:00
|
|
|
BLI_dir_create_recursive(temp_dir); /* Create 'script' subdir if it does not exist already */
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2019-12-16 15:46:47 +01:00
|
|
|
DEG_id_tag_update(&job->ob->id, ID_RECALC_GEOMETRY);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
fluid_bake_sequence(job);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-17 09:51:38 +11:00
|
|
|
if (do_update) {
|
2019-12-16 15:46:47 +01:00
|
|
|
*do_update = true;
|
2019-12-17 09:51:38 +11:00
|
|
|
}
|
|
|
|
|
if (stop) {
|
2019-12-16 15:46:47 +01:00
|
|
|
*stop = 0;
|
2019-12-17 09:51:38 +11:00
|
|
|
}
|
2019-12-16 15:46:47 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
static void fluid_free_endjob(void *customdata)
|
|
|
|
|
{
|
|
|
|
|
FluidJob *job = customdata;
|
2020-07-03 11:51:15 +02:00
|
|
|
FluidDomainSettings *fds = job->fmd->domain;
|
2019-12-16 15:46:47 +01:00
|
|
|
|
|
|
|
|
G.is_rendering = false;
|
|
|
|
|
BKE_spacedata_draw_locks(false);
|
|
|
|
|
WM_set_locked_interface(G_MAIN->wm.first, false);
|
|
|
|
|
|
2020-01-29 19:21:09 +01:00
|
|
|
/* Reflect the now empty cache in the viewport too. */
|
|
|
|
|
DEG_id_tag_update(&job->ob->id, ID_RECALC_GEOMETRY);
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* Free was successful:
|
|
|
|
|
* Report for ended free job and how long it took */
|
|
|
|
|
if (job->success) {
|
|
|
|
|
/* Show free job info */
|
2019-12-17 08:58:43 +11:00
|
|
|
WM_reportf(
|
|
|
|
|
RPT_INFO, "Fluid: %s complete! (%.2f)", job->name, PIL_check_seconds_timer() - job->start);
|
2019-12-16 15:46:47 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2020-07-03 11:51:15 +02:00
|
|
|
if (fds->error[0] != '\0') {
|
|
|
|
|
WM_reportf(RPT_ERROR, "Fluid: %s failed: %s", job->name, fds->error);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-12-16 15:46:47 +01:00
|
|
|
else { /* User canceled the free job */
|
|
|
|
|
WM_reportf(RPT_WARNING, "Fluid: %s canceled!", job->name);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2009-01-24 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
static void fluid_free_startjob(void *customdata, short *stop, short *do_update, float *progress)
|
2009-01-24 13:45:24 +00:00
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
FluidJob *job = customdata;
|
2020-07-03 11:51:15 +02:00
|
|
|
FluidDomainSettings *fds = job->fmd->domain;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
job->stop = stop;
|
|
|
|
|
job->do_update = do_update;
|
|
|
|
|
job->progress = progress;
|
|
|
|
|
job->start = PIL_check_seconds_timer();
|
|
|
|
|
job->success = 1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
G.is_break = false;
|
|
|
|
|
G.is_rendering = true;
|
|
|
|
|
BKE_spacedata_draw_locks(true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
int cache_map = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
if (fluid_is_free_data(job) || fluid_is_free_all(job)) {
|
|
|
|
|
cache_map |= (FLUID_DOMAIN_OUTDATED_DATA | FLUID_DOMAIN_OUTDATED_NOISE |
|
|
|
|
|
FLUID_DOMAIN_OUTDATED_MESH | FLUID_DOMAIN_OUTDATED_PARTICLES);
|
|
|
|
|
}
|
|
|
|
|
if (fluid_is_free_noise(job) || fluid_is_free_all(job)) {
|
|
|
|
|
cache_map |= FLUID_DOMAIN_OUTDATED_NOISE;
|
|
|
|
|
}
|
|
|
|
|
if (fluid_is_free_mesh(job) || fluid_is_free_all(job)) {
|
|
|
|
|
cache_map |= FLUID_DOMAIN_OUTDATED_MESH;
|
|
|
|
|
}
|
|
|
|
|
if (fluid_is_free_particles(job) || fluid_is_free_all(job)) {
|
|
|
|
|
cache_map |= FLUID_DOMAIN_OUTDATED_PARTICLES;
|
|
|
|
|
}
|
|
|
|
|
if (fluid_is_free_guiding(job) || fluid_is_free_all(job)) {
|
2020-02-09 17:15:41 +01:00
|
|
|
cache_map |= (FLUID_DOMAIN_OUTDATED_DATA | FLUID_DOMAIN_OUTDATED_NOISE |
|
|
|
|
|
FLUID_DOMAIN_OUTDATED_MESH | FLUID_DOMAIN_OUTDATED_PARTICLES |
|
|
|
|
|
FLUID_DOMAIN_OUTDATED_GUIDE);
|
2019-12-16 15:46:47 +01:00
|
|
|
}
|
2019-12-17 08:38:08 +11:00
|
|
|
#ifdef WITH_FLUID
|
2020-07-03 11:51:15 +02:00
|
|
|
BKE_fluid_cache_free(fds, job->ob, cache_map);
|
2020-01-16 16:25:12 +11:00
|
|
|
#else
|
2020-07-03 11:51:15 +02:00
|
|
|
UNUSED_VARS(fds);
|
2019-12-17 08:38:08 +11:00
|
|
|
#endif
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
*do_update = true;
|
|
|
|
|
*stop = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* Update scene so that viewport shows freed up scene */
|
|
|
|
|
ED_update_for_newframe(job->bmain, job->depsgraph);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/***************************** Operators ******************************/
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
static int fluid_bake_exec(struct bContext *C, struct wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
FluidJob *job = MEM_mallocN(sizeof(FluidJob), "FluidJob");
|
|
|
|
|
char error_msg[256] = "\0";
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
if (!fluid_initjob(C, job, op, error_msg, sizeof(error_msg))) {
|
|
|
|
|
if (error_msg[0]) {
|
|
|
|
|
BKE_report(op->reports, RPT_ERROR, error_msg);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2019-12-16 15:46:47 +01:00
|
|
|
fluid_bake_free(job);
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2020-01-14 12:13:50 +01:00
|
|
|
if (!fluid_validatepaths(job, op->reports)) {
|
2020-07-13 18:26:48 +02:00
|
|
|
fluid_bake_free(job);
|
2019-12-16 15:46:47 +01:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2020-02-04 21:36:18 +01:00
|
|
|
WM_report_banners_cancel(job->bmain);
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
fluid_bake_startjob(job, NULL, NULL, NULL);
|
|
|
|
|
fluid_bake_endjob(job);
|
|
|
|
|
fluid_bake_free(job);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
static int fluid_bake_invoke(struct bContext *C,
|
|
|
|
|
struct wmOperator *op,
|
|
|
|
|
const wmEvent *UNUSED(_event))
|
|
|
|
|
{
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
|
FluidJob *job = MEM_mallocN(sizeof(FluidJob), "FluidJob");
|
|
|
|
|
char error_msg[256] = "\0";
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
if (!fluid_initjob(C, job, op, error_msg, sizeof(error_msg))) {
|
|
|
|
|
if (error_msg[0]) {
|
|
|
|
|
BKE_report(op->reports, RPT_ERROR, error_msg);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-12-16 15:46:47 +01:00
|
|
|
fluid_bake_free(job);
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-01-14 12:13:50 +01:00
|
|
|
if (!fluid_validatepaths(job, op->reports)) {
|
2020-07-13 18:26:48 +02:00
|
|
|
fluid_bake_free(job);
|
2019-12-16 15:46:47 +01:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-02-04 21:36:18 +01:00
|
|
|
/* Clear existing banners so that the upcoming progress bar from this job has more room. */
|
|
|
|
|
WM_report_banners_cancel(job->bmain);
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
|
|
|
|
|
CTX_wm_window(C),
|
|
|
|
|
scene,
|
|
|
|
|
"Fluid Bake",
|
|
|
|
|
WM_JOB_PROGRESS,
|
|
|
|
|
WM_JOB_TYPE_OBJECT_SIM_FLUID);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
WM_jobs_customdata_set(wm_job, job, fluid_bake_free);
|
|
|
|
|
WM_jobs_timer(wm_job, 0.01, NC_OBJECT | ND_MODIFIER, NC_OBJECT | ND_MODIFIER);
|
|
|
|
|
WM_jobs_callbacks(wm_job, fluid_bake_startjob, NULL, NULL, fluid_bake_endjob);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
WM_set_locked_interface(CTX_wm_manager(C), true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
WM_jobs_start(CTX_wm_manager(C), wm_job);
|
|
|
|
|
WM_event_add_modal_handler(C, op);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
2010-03-25 06:27:25 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
static int fluid_bake_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
|
2010-03-25 06:27:25 +00:00
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
/* no running blender, remove handler and pass through */
|
2019-12-17 09:51:38 +11:00
|
|
|
if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_SIM_FLUID)) {
|
2019-12-16 15:46:47 +01:00
|
|
|
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
|
2019-12-17 09:51:38 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
switch (event->type) {
|
2020-03-18 10:38:37 -06:00
|
|
|
case EVT_ESCKEY:
|
2019-12-16 15:46:47 +01:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-12-16 15:46:47 +01:00
|
|
|
return OPERATOR_PASS_THROUGH;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
static int fluid_free_exec(struct bContext *C, struct wmOperator *op)
|
|
|
|
|
{
|
2020-07-03 11:51:15 +02:00
|
|
|
FluidModifierData *fmd = NULL;
|
|
|
|
|
FluidDomainSettings *fds;
|
2020-05-22 13:43:53 +02:00
|
|
|
Object *ob = ED_object_active_context(C);
|
2019-12-16 15:46:47 +01:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/*
|
|
|
|
|
* Get modifier data
|
|
|
|
|
*/
|
2020-07-03 11:51:15 +02:00
|
|
|
fmd = (FluidModifierData *)BKE_modifiers_findby_type(ob, eModifierType_Fluid);
|
|
|
|
|
if (!fmd) {
|
2019-12-16 15:46:47 +01:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Bake free failed: no Fluid modifier found");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2020-07-03 11:51:15 +02:00
|
|
|
fds = fmd->domain;
|
|
|
|
|
if (!fds) {
|
2019-12-16 15:46:47 +01:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Bake free failed: invalid domain");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* Cannot free data if other bakes currently working */
|
2020-07-03 11:51:15 +02:00
|
|
|
if (fmd->domain->cache_flag & (FLUID_DOMAIN_BAKING_DATA | FLUID_DOMAIN_BAKING_NOISE |
|
2019-12-16 15:46:47 +01:00
|
|
|
FLUID_DOMAIN_BAKING_MESH | FLUID_DOMAIN_BAKING_PARTICLES)) {
|
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "Bake free failed: pending bake jobs found");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
FluidJob *job = MEM_mallocN(sizeof(FluidJob), "FluidJob");
|
|
|
|
|
job->bmain = CTX_data_main(C);
|
|
|
|
|
job->scene = scene;
|
|
|
|
|
job->depsgraph = CTX_data_depsgraph_pointer(C);
|
|
|
|
|
job->ob = ob;
|
2020-07-03 11:51:15 +02:00
|
|
|
job->fmd = fmd;
|
2019-12-16 15:46:47 +01:00
|
|
|
job->type = op->type->idname;
|
|
|
|
|
job->name = op->type->name;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-01-14 12:13:50 +01:00
|
|
|
if (!fluid_validatepaths(job, op->reports)) {
|
2020-07-13 18:26:48 +02:00
|
|
|
fluid_bake_free(job);
|
2019-12-16 15:46:47 +01:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2020-02-04 21:36:18 +01:00
|
|
|
/* Clear existing banners so that the upcoming progress bar from this job has more room. */
|
|
|
|
|
WM_report_banners_cancel(job->bmain);
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
|
|
|
|
|
CTX_wm_window(C),
|
|
|
|
|
scene,
|
|
|
|
|
"Fluid Free",
|
|
|
|
|
WM_JOB_PROGRESS,
|
|
|
|
|
WM_JOB_TYPE_OBJECT_SIM_FLUID);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
WM_jobs_customdata_set(wm_job, job, fluid_bake_free);
|
|
|
|
|
WM_jobs_timer(wm_job, 0.01, NC_OBJECT | ND_MODIFIER, NC_OBJECT | ND_MODIFIER);
|
|
|
|
|
WM_jobs_callbacks(wm_job, fluid_free_startjob, NULL, NULL, fluid_free_endjob);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
WM_set_locked_interface(CTX_wm_manager(C), true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* Free Fluid Geometry */
|
|
|
|
|
WM_jobs_start(CTX_wm_manager(C), wm_job);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
return OPERATOR_FINISHED;
|
2010-03-25 06:27:25 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
static int fluid_pause_exec(struct bContext *C, struct wmOperator *op)
|
|
|
|
|
{
|
2020-07-03 11:51:15 +02:00
|
|
|
FluidModifierData *fmd = NULL;
|
|
|
|
|
FluidDomainSettings *fds;
|
2020-05-22 13:43:53 +02:00
|
|
|
Object *ob = ED_object_active_context(C);
|
2019-12-16 15:46:47 +01:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Get modifier data
|
|
|
|
|
*/
|
2020-07-03 11:51:15 +02:00
|
|
|
fmd = (FluidModifierData *)BKE_modifiers_findby_type(ob, eModifierType_Fluid);
|
|
|
|
|
if (!fmd) {
|
2019-12-16 15:46:47 +01:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Bake free failed: no Fluid modifier found");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2020-07-03 11:51:15 +02:00
|
|
|
fds = fmd->domain;
|
|
|
|
|
if (!fds) {
|
2019-12-16 15:46:47 +01:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Bake free failed: invalid domain");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2010-03-25 06:27:25 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
G.is_break = true;
|
2010-03-25 06:27:25 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
return OPERATOR_FINISHED;
|
2010-03-25 06:27:25 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
void FLUID_OT_bake_all(wmOperatorType *ot)
|
2010-03-25 06:27:25 +00:00
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Bake All";
|
|
|
|
|
ot->description = "Bake Entire Fluid Simulation";
|
|
|
|
|
ot->idname = FLUID_JOB_BAKE_ALL;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = fluid_bake_exec;
|
|
|
|
|
ot->invoke = fluid_bake_invoke;
|
|
|
|
|
ot->modal = fluid_bake_modal;
|
|
|
|
|
ot->poll = ED_operator_object_active_editable;
|
2010-03-25 06:27:25 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
void FLUID_OT_free_all(wmOperatorType *ot)
|
2010-03-25 06:27:25 +00:00
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Free All";
|
|
|
|
|
ot->description = "Free Entire Fluid Simulation";
|
|
|
|
|
ot->idname = FLUID_JOB_FREE_ALL;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = fluid_free_exec;
|
|
|
|
|
ot->poll = ED_operator_object_active_editable;
|
2009-01-24 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
void FLUID_OT_bake_data(wmOperatorType *ot)
|
2010-03-25 06:27:25 +00:00
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Bake Data";
|
|
|
|
|
ot->description = "Bake Fluid Data";
|
|
|
|
|
ot->idname = FLUID_JOB_BAKE_DATA;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = fluid_bake_exec;
|
|
|
|
|
ot->invoke = fluid_bake_invoke;
|
|
|
|
|
ot->modal = fluid_bake_modal;
|
|
|
|
|
ot->poll = ED_operator_object_active_editable;
|
2010-03-25 06:27:25 +00:00
|
|
|
}
|
2009-01-24 13:45:24 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
void FLUID_OT_free_data(wmOperatorType *ot)
|
2010-05-27 08:22:16 +00:00
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Free Data";
|
|
|
|
|
ot->description = "Free Fluid Data";
|
|
|
|
|
ot->idname = FLUID_JOB_FREE_DATA;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = fluid_free_exec;
|
|
|
|
|
ot->poll = ED_operator_object_active_editable;
|
2010-05-27 08:22:16 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
void FLUID_OT_bake_noise(wmOperatorType *ot)
|
2011-12-30 07:55:15 +00:00
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Bake Noise";
|
|
|
|
|
ot->description = "Bake Fluid Noise";
|
|
|
|
|
ot->idname = FLUID_JOB_BAKE_NOISE;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = fluid_bake_exec;
|
|
|
|
|
ot->invoke = fluid_bake_invoke;
|
|
|
|
|
ot->modal = fluid_bake_modal;
|
|
|
|
|
ot->poll = ED_operator_object_active_editable;
|
2009-01-24 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
void FLUID_OT_free_noise(wmOperatorType *ot)
|
2010-06-03 07:28:47 +00:00
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Free Noise";
|
|
|
|
|
ot->description = "Free Fluid Noise";
|
|
|
|
|
ot->idname = FLUID_JOB_FREE_NOISE;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = fluid_free_exec;
|
|
|
|
|
ot->poll = ED_operator_object_active_editable;
|
2010-06-03 07:28:47 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
void FLUID_OT_bake_mesh(wmOperatorType *ot)
|
2011-06-12 23:51:30 +00:00
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Bake Mesh";
|
|
|
|
|
ot->description = "Bake Fluid Mesh";
|
|
|
|
|
ot->idname = FLUID_JOB_BAKE_MESH;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = fluid_bake_exec;
|
|
|
|
|
ot->invoke = fluid_bake_invoke;
|
|
|
|
|
ot->modal = fluid_bake_modal;
|
|
|
|
|
ot->poll = ED_operator_object_active_editable;
|
2011-06-12 23:51:30 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
void FLUID_OT_free_mesh(wmOperatorType *ot)
|
2009-01-24 13:45:24 +00:00
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Free Mesh";
|
|
|
|
|
ot->description = "Free Fluid Mesh";
|
|
|
|
|
ot->idname = FLUID_JOB_FREE_MESH;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = fluid_free_exec;
|
|
|
|
|
ot->poll = ED_operator_object_active_editable;
|
2009-01-24 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
void FLUID_OT_bake_particles(wmOperatorType *ot)
|
2009-01-24 13:45:24 +00:00
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Bake Particles";
|
|
|
|
|
ot->description = "Bake Fluid Particles";
|
|
|
|
|
ot->idname = FLUID_JOB_BAKE_PARTICLES;
|
2009-01-24 13:45:24 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = fluid_bake_exec;
|
|
|
|
|
ot->invoke = fluid_bake_invoke;
|
|
|
|
|
ot->modal = fluid_bake_modal;
|
|
|
|
|
ot->poll = ED_operator_object_active_editable;
|
2009-01-24 13:45:24 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
void FLUID_OT_free_particles(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Free Particles";
|
|
|
|
|
ot->description = "Free Fluid Particles";
|
|
|
|
|
ot->idname = FLUID_JOB_FREE_PARTICLES;
|
2009-01-24 13:45:24 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = fluid_free_exec;
|
|
|
|
|
ot->poll = ED_operator_object_active_editable;
|
|
|
|
|
}
|
2009-07-02 19:41:31 +00:00
|
|
|
|
2019-12-17 14:00:19 +11:00
|
|
|
void FLUID_OT_bake_guides(wmOperatorType *ot)
|
2009-07-02 19:41:31 +00:00
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
/* identifiers */
|
2019-12-17 14:00:19 +11:00
|
|
|
ot->name = "Bake Guides";
|
2019-12-16 15:46:47 +01:00
|
|
|
ot->description = "Bake Fluid Guiding";
|
2019-12-17 14:00:19 +11:00
|
|
|
ot->idname = FLUID_JOB_BAKE_GUIDES;
|
2011-09-28 06:26:46 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = fluid_bake_exec;
|
|
|
|
|
ot->invoke = fluid_bake_invoke;
|
|
|
|
|
ot->modal = fluid_bake_modal;
|
|
|
|
|
ot->poll = ED_operator_object_active_editable;
|
2011-09-28 06:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-17 14:00:19 +11:00
|
|
|
void FLUID_OT_free_guides(wmOperatorType *ot)
|
2011-09-28 06:26:46 +00:00
|
|
|
{
|
2019-12-16 15:46:47 +01:00
|
|
|
/* identifiers */
|
2019-12-17 14:00:19 +11:00
|
|
|
ot->name = "Free Guides";
|
2019-12-16 15:46:47 +01:00
|
|
|
ot->description = "Free Fluid Guiding";
|
2019-12-17 14:00:19 +11:00
|
|
|
ot->idname = FLUID_JOB_FREE_GUIDES;
|
2009-07-02 19:41:31 +00:00
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = fluid_free_exec;
|
|
|
|
|
ot->poll = ED_operator_object_active_editable;
|
2009-07-02 19:41:31 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-16 15:46:47 +01:00
|
|
|
void FLUID_OT_pause_bake(wmOperatorType *ot)
|
2009-07-02 19:41:31 +00:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* identifiers */
|
2019-12-16 15:46:47 +01:00
|
|
|
ot->name = "Pause Bake";
|
|
|
|
|
ot->description = "Pause Bake";
|
|
|
|
|
ot->idname = FLUID_JOB_BAKE_PAUSE;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2019-12-16 15:46:47 +01:00
|
|
|
ot->exec = fluid_pause_exec;
|
2019-04-17 06:17:24 +02:00
|
|
|
ot->poll = ED_operator_object_active_editable;
|
2009-07-02 19:41:31 +00:00
|
|
|
}
|