98static int neighX[8] = {1, 1, 0, -1, -1, -1, 0, 1};
99static int neighY[8] = {0, 1, 1, 1, 0, -1, -1, -1};
106#define SUBFRAME_RECURSION 5
108#define BRUSH_USES_VELOCITY (1 << 0)
111#define HIT_PROXIMITY 2
114#define ON_MESH_EDGE -2
115#define OUT_OF_TEXTURE -3
117#define EFF_MOVEMENT_PER_FRAME 0.05f
119#define WAVE_TIME_FAC (1.0f / 24.0f)
120#define CANVAS_REL_SIZE 5.0f
122#define MIN_WETNESS 0.001f
123#define MAX_WETNESS 5.0f
131 *r_value = (is_log) ? (*r_value) *
powf(
MIN_WETNESS, 1.0f / (1.2f * time / scale)) :
132 (*r_value) - 1.0f / time * scale;
237#define ADJ_ON_MESH_EDGE (1 << 0)
238#define ADJ_BORDER_PIXEL (1 << 1)
261 if (runtime_data ==
nullptr) {
318 return (canvas_mesh) ? canvas_mesh->
verts_num : 0;
336 else if (output == 1) {
337 name = surface->output_name2;
363 for (; surface; surface = surface->next) {
364 if (surface != t_surface && surface->
type == t_surface->
type &&
365 surface->format == t_surface->
format)
367 if ((surface->output_name[0] !=
'\0' && !
BLI_path_cmp(name, surface->output_name)) ||
368 (surface->output_name2[0] !=
'\0' && !
BLI_path_cmp(name, surface->output_name2)))
386 surface->output_name,
387 sizeof(surface->output_name));
389 else if (output == 1) {
394 surface->output_name2,
395 sizeof(surface->output_name2));
405 for (; surface; surface = surface->next) {
406 if (surface != t_surface &&
STREQ(name, surface->name)) {
423 const char *name_prefix =
"";
424 const char *name_suffix_1 =
"";
425 const char *name_suffix_2 =
"";
428 surface->output_name[0] =
'\0';
429 surface->output_name2[0] =
'\0';
431 surface->depth_clamp = 1.0f;
435 surface->flags &= ~MOD_DPAINT_ANTIALIAS;
436 surface->depth_clamp = 0.0f;
440 name_suffix_1 =
"paintmap";
441 name_suffix_2 =
"wetmap";
444 name_suffix_1 = name_suffix_2 =
"displace";
447 name_suffix_1 = name_suffix_2 =
"weight";
450 name_suffix_1 = name_suffix_2 =
"wave";
453 SNPRINTF(surface->output_name,
"%s%s", name_prefix, name_suffix_1);
454 SNPRINTF(surface->output_name2,
"%s%s", name_prefix, name_suffix_2);
455 const bool output_name_equal =
STREQ(surface->output_name, surface->output_name2);
458 if (!output_name_equal) {
466 return (surface->data->total_points * 5);
469 surface->data->adj_data)
471 return (surface->data->total_points + surface->data->adj_data->total_targets);
474 return surface->data->total_points;
479 const float s_color[3],
484 float i_alpha = 1.0f - s_alpha;
485 float f_alpha = t_alpha * i_alpha + s_alpha;
489 for (
int i = 0; i < 3; i++) {
490 result[i] = (t_color[i] * t_alpha * i_alpha + s_color[i] * s_alpha) / f_alpha;
502 float a_color[3],
float a_weight,
const float b_color[3],
float b_weight,
float ratio)
504 float weight_ratio, factor;
509 return b_weight * ratio;
511 weight_ratio = b_weight / (a_weight + b_weight);
514 return a_weight * (1.0f - ratio);
519 factor = weight_ratio * (ratio * 2.0f);
522 ratio = (ratio * 2.0f - 1.0f);
523 factor = weight_ratio * (1.0f - ratio) + ratio;
527 return (1.0f - factor) * a_weight + factor * b_weight;
534 scene->r.subframe = subframe;
545 for (
int i = 0; i < numobjects; i++) {
546 Object *brushObj = objects[i];
573 for (
int i = 2; i--;) {
574 if (!(b1->
min[i] <= b2->
max[i] && b1->
max[i] >= b2->
min[i])) {
587 for (
int i = 2; i--;) {
588 if (!(b1->
min[i] <= (b2->
max[i] + dist) && b1->
max[i] >= (b2->
min[i] - dist))) {
601 for (
int i = 2; i--;) {
602 if (!(
b->min[i] <= (point[i] + radius) &&
b->max[i] >= (point[i] - radius))) {
647 bData->
grid =
nullptr;
662 void *__restrict chunk_join,
663 void *__restrict chunk)
679 int *s_num =
static_cast<int *
>(tls->userdata_chunk);
683 for (
int j = 3; j--;) {
685 bData->
dim[j] * grid->dim[j]));
686 CLAMP(co[j], 0, grid->dim[j] - 1);
689 temp_t_index[i] = co[0] + co[1] * grid->dim[0] + co[2] * grid->dim[0] * grid->dim[1];
690 s_num[temp_t_index[i]]++;
694 void *__restrict chunk_join,
695 void *__restrict chunk)
699 const int grid_cells = grid->
dim[0] * grid->dim[1] * grid->dim[2];
701 int *join_s_num =
static_cast<int *
>(chunk_join);
702 int *s_num =
static_cast<int *
>(chunk);
705 for (
int i = 0; i < grid_cells; i++) {
706 join_s_num[i] += s_num[i];
716 float *dim = bData->
dim;
717 int *grid_dim = grid->dim;
719 for (
int y = 0; y < grid_dim[1]; y++) {
720 for (
int z = 0;
z < grid_dim[2];
z++) {
721 const int b_index = x + y * grid_dim[0] +
z * grid_dim[0] * grid_dim[1];
723 for (
int j = 3; j--;) {
724 const int s = (j == 0) ? x : ((j == 1) ? y :
z);
725 grid->bounds[b_index].min[j] = grid->grid_bounds.min[j] + dim[j] / grid_dim[j] * s;
726 grid->bounds[b_index].max[j] = grid->grid_bounds.min[j] + dim[j] / grid_dim[j] * (s + 1);
728 grid->bounds[b_index].valid =
true;
738 int grid_cells, axis = 3;
739 int *temp_t_index =
nullptr;
740 int *temp_s_num =
nullptr;
746 bData->
grid = MEM_cnew<DynamicPaintVolumeGrid>(__func__);
751 float dim_factor, volume, dim[3];
762 settings.userdata_chunk = &grid->grid_bounds;
763 settings.userdata_chunk_size =
sizeof(grid->grid_bounds);
768 sub_v3_v3v3(dim, grid->grid_bounds.max, grid->grid_bounds.min);
771 min_dim =
max_fff(td[0], td[1], td[2]) / 1000.0f;
774 for (i = 0; i < 3; i++) {
775 if (td[i] < min_dim) {
781 if (axis == 0 ||
max_fff(td[0], td[1], td[2]) < 0.0001f) {
783 bData->
grid =
nullptr;
788 volume = td[0] * td[1] * td[2];
792 pow(
double(volume) / (
double(sData->
total_points) / 10000.0), 1.0 /
double(axis)));
795 for (i = 0; i < 3; i++) {
796 grid->dim[i] =
int(
floor(td[i] / dim_factor));
797 CLAMP(grid->dim[i], (dim[i] >= min_dim) ? 3 : 1, 100);
799 grid_cells = grid->dim[0] * grid->dim[1] * grid->dim[2];
802 grid->bounds =
static_cast<Bounds3D *
>(
804 grid->s_pos =
static_cast<int *
>(
805 MEM_callocN(
sizeof(
int) * grid_cells,
"Surface Grid Position"));
807 grid->s_num =
static_cast<int *
>(
MEM_callocN(
sizeof(
int) * grid_cells,
"Surface Grid Points"));
808 temp_s_num =
static_cast<int *
>(
809 MEM_callocN(
sizeof(
int) * grid_cells,
"Temp Surface Grid Points"));
810 grid->t_index =
static_cast<int *
>(
812 grid->temp_t_index = temp_t_index =
static_cast<int *
>(
816 if (!grid->bounds || !grid->s_pos || !grid->s_num || !grid->t_index || !temp_s_num ||
828 settings.userdata_chunk = grid->s_num;
829 settings.userdata_chunk_size =
sizeof(*grid->s_num) * grid_cells;
835 for (i = 1; i < grid_cells; i++) {
836 grid->s_pos[i] = grid->s_pos[i - 1] + grid->s_num[i - 1];
841 int pos = grid->s_pos[temp_t_index[i]] + temp_s_num[temp_t_index[i]];
842 grid->t_index[
pos] = i;
844 temp_s_num[temp_t_index[i]]++;
851 settings.use_threading = (grid_cells > 1000);
861 if (
error || !grid->s_num) {
862 setError(surface->canvas,
N_(
"Not enough free memory"));
881 pmd->
brush =
nullptr;
887 if (data->adj_data) {
888 if (data->adj_data->n_index) {
891 if (data->adj_data->n_num) {
894 if (data->adj_data->n_target) {
897 if (data->adj_data->flags) {
900 if (data->adj_data->border) {
904 data->adj_data =
nullptr;
941 data->bData =
nullptr;
948 if (!surface->data) {
954 (surface->pointcache && surface->pointcache->flag &
PTCACHE_BAKED))
967 if (data->format_data) {
971 if (format_data->
uv_p) {
981 if (data->type_data) {
989 surface->data =
nullptr;
998 surface->pointcache =
nullptr;
1002 BLI_remlink(&(surface->canvas->surfaces), surface);
1015 next_surface = surface->
next;
1017 surface = next_surface;
1027 if (pmd ==
nullptr) {
1045 surface->canvas = canvas;
1052 surface->pointcache->step = 1;
1058 surface->effect = 0;
1059 surface->effect_ui = 1;
1061 surface->diss_speed = 250;
1062 surface->dry_speed = 500;
1063 surface->color_dry_threshold = 1.0f;
1064 surface->depth_clamp = 0.0f;
1065 surface->disp_factor = 1.0f;
1069 surface->influence_scale = 1.0f;
1070 surface->radius_scale = 1.0f;
1072 surface->init_color[0] = 1.0f;
1073 surface->init_color[1] = 1.0f;
1074 surface->init_color[2] = 1.0f;
1075 surface->init_color[3] = 1.0f;
1077 surface->image_resolution = 256;
1078 surface->substeps = 0;
1081 surface->start_frame = scene->r.sfra;
1082 surface->end_frame = scene->r.efra;
1085 surface->start_frame = 1;
1086 surface->end_frame = 250;
1089 surface->spread_speed = 1.0f;
1090 surface->color_spread_speed = 1.0f;
1091 surface->shrink_speed = 1.0f;
1093 surface->wave_damping = 0.04f;
1094 surface->wave_speed = 1.0f;
1095 surface->wave_timescale = 1.0f;
1096 surface->wave_spring = 0.20f;
1097 surface->wave_smoothness = 1.0f;
1100 surface->image_output_path,
sizeof(surface->image_output_path),
"cache_dynamicpaint");
1123 canvas = pmd->
canvas = MEM_cnew<DynamicPaintCanvasSettings>(__func__);
1140 brush = pmd->
brush = MEM_cnew<DynamicPaintBrushSettings>(__func__);
1146 brush->
psys =
nullptr;
1154 brush->
alpha = 1.0f;
1179 ramp[0].
r = ramp[0].
g = ramp[0].
b = ramp[0].
a = 1.0f;
1181 ramp[1].
r = ramp[1].
g = ramp[1].
b = ramp[1].
pos = 1.0f;
1195 ramp[0].
r = ramp[0].
g = ramp[0].
b = ramp[0].
a = ramp[0].
pos = 0.0f;
1196 ramp[1].
r = ramp[1].
g = ramp[1].
b = ramp[1].
a = ramp[1].
pos = 1.0f;
1235 surface = surface->next)
1243 t_surface->
ptcaches = surface->ptcaches;
1254 t_surface->
format = surface->format;
1255 t_surface->
type = surface->type;
1256 t_surface->
disp_type = surface->disp_type;
1258 t_surface->
effect_ui = surface->effect_ui;
1260 t_surface->
flags = surface->flags;
1261 t_surface->
effect = surface->effect;
1264 t_surface->
substeps = surface->substeps;
1266 t_surface->
end_frame = surface->end_frame;
1272 t_surface->
dry_speed = surface->dry_speed;
1281 t_surface->
drip_vel = surface->drip_vel;
1282 t_surface->
drip_acc = surface->drip_acc;
1301 t_brush->
pmd = tpmd;
1303 t_brush->flags = brush->
flags;
1306 t_brush->r = brush->
r;
1307 t_brush->g = brush->
g;
1308 t_brush->b = brush->
b;
1309 t_brush->alpha = brush->
alpha;
1310 t_brush->wetness = brush->
wetness;
1319 t_brush->psys = brush->
psys;
1330 t_brush->ray_dir = brush->
ray_dir;
1344 switch (surface->type) {
1347 "DynamicPaintSurface Data");
1351 "DynamicPaintSurface DepthData");
1355 "DynamicPaintSurface WeightData");
1359 "DynamicPaintSurface WaveData");
1364 setError(surface->canvas,
N_(
"Not enough free memory"));
1387 int neigh_points = 0;
1395 neigh_points = 2 * mesh->edges_num;
1401 if (!neigh_points) {
1406 ad = sData->
adj_data = MEM_cnew<PaintAdjData>(__func__);
1410 ad->
n_index =
static_cast<int *
>(
1412 ad->
n_num =
static_cast<int *
>(
1416 MEM_callocN(
sizeof(
int) * neigh_points,
"Surface Adj Targets"));
1417 ad->
flags =
static_cast<int *
>(
1429 setError(surface->canvas,
N_(
"Not enough free memory"));
1435 int numOfEdges = mesh->edges_num;
1436 int numOfPolys = mesh->faces_num;
1442 for (
int i = 0; i < numOfEdges; i++) {
1443 ad->
n_num[edges[i][0]]++;
1444 ad->
n_num[edges[i][1]]++;
1446 temp_data[edges[i][0]]++;
1447 temp_data[edges[i][1]]++;
1452 for (
int i = 0; i < numOfPolys; i++) {
1453 for (
const int vert : corner_verts.
slice(faces[i])) {
1461 if ((temp_data[i] % 2) || (temp_data[i] < 4)) {
1473 n_pos += ad->
n_num[i];
1477 for (
int i = 0; i < numOfEdges; i++) {
1479 int index = edges[i][0];
1480 n_pos = ad->
n_index[index] + temp_data[index];
1485 index = edges[i][1];
1486 n_pos = ad->
n_index[index] + temp_data[index];
1520 const float(*mloopuv)[2] = data->mloopuv;
1522 Tex *
tex = data->surface->init_texture;
1524 float uv[3] = {0.0f};
1526 for (
int j = 3; j--;) {
1528 const int vert = corner_verts[corner_tris[i][j]];
1531 uv[0] = mloopuv[corner_tris[i][j]][0] * 2.0f - 1.0f;
1532 uv[1] = mloopuv[corner_tris[i][j]][1] * 2.0f - 1.0f;
1536 if (texres.
tin > pPoint[vert].
color[3]) {
1538 pPoint[vert].
color[3] = texres.
tin;
1553 const float(*mloopuv)[2] = data->mloopuv;
1554 Tex *
tex = data->surface->init_texture;
1558 float uv[9] = {0.0f};
1559 float uv_final[3] = {0.0f};
1564 for (
int j = 3; j--;) {
1571 uv_final[0] = uv_final[0] * 2.0f - 1.0f;
1572 uv_final[1] = uv_final[1] * 2.0f - 1.0f;
1582 void *__restrict userdata,
const int i,
const TaskParallelTLS *__restrict )
1590 const MLoopCol *mloopcol = data->mloopcol;
1596 float final_color[4];
1599 for (
int j = 3; j--;) {
1627 copy_v4_v4(pPoint[i].color, surface->init_color);
1632 Tex *
tex = surface->init_texture;
1645 &mesh->corner_data,
CD_PROP_FLOAT2, surface->init_layername, uvname);
1646 const float(*mloopuv)[2] =
static_cast<const float(*)[2]
>(
1660 data.corner_verts = corner_verts;
1661 data.corner_tris = corner_tris;
1662 data.mloopuv = mloopuv;
1667 settings.use_threading = (corner_tris.
size() > 1000);
1675 data.corner_tris = corner_tris;
1676 data.mloopuv = mloopuv;
1711 data.corner_tris = corner_tris;
1712 data.mloopcol =
col;
1736 data_size =
sizeof(
float);
1756 if (surface->data) {
1764 if (numOfPoints < 1) {
1769 surface->data = MEM_cnew<PaintSurfaceData>(__func__);
1770 if (!surface->data) {
1775 surface->data->total_points = numOfPoints;
1823 const float val = value[i] * surface->disp_factor;
1825 madd_v3_v3fl(data->vert_positions[i], data->vert_normals[i], -val);
1841 data.vert_positions = result->vert_positions_for_write();
1842 data.vert_normals = result->vert_normals();
1846 settings.use_threading = (sData->
total_points > 10000);
1860 float(*fcolor)[4] = data->fcolor;
1864 pPoint[i].color, pPoint[i].color[3], pPoint[i].e_color, pPoint[i].e_color[3], fcolor[i]);
1878 float(*fcolor)[4] = data->fcolor;
1880 MLoopCol *mloopcol = data->mloopcol;
1881 MLoopCol *mloopcol_wet = data->mloopcol_wet;
1883 for (
const int l_index : data->faces[p_index]) {
1884 const int v_index = corner_verts[l_index];
1894 mloopcol_wet[l_index].
r = c;
1895 mloopcol_wet[l_index].
g = c;
1896 mloopcol_wet[l_index].
b = c;
1897 mloopcol_wet[l_index].
a = 255;
1929 surface = surface->next)
1947 float(*fcolor)[4] =
static_cast<float(*)[4]
>(
1952 data.fcolor = fcolor;
1969 surface->output_name,
1970 result->corners_num));
1976 corner_verts.
size(),
1977 surface->output_name));
1984 surface->output_name2,
1985 result->corners_num));
1988 mloopcol_wet =
static_cast<MLoopCol *
>(
1992 corner_verts.
size(),
1993 surface->output_name2));
1997 data.corner_verts = corner_verts;
1999 data.mloopcol = mloopcol;
2000 data.mloopcol_wet = mloopcol_wet;
2005 settings.use_threading = (faces.size() > 1000);
2017 float *weight = (
float *)sData->
type_data;
2020 if (defgrp_index != -1 && !dvert && (surface->output_name[0] !=
'\0')) {
2024 if (defgrp_index != -1 && dvert) {
2030 if ((def_weight !=
nullptr) || (weight[i] != 0.0f)) {
2032 if (def_weight ==
nullptr) {
2037 def_weight->
weight = weight[i];
2046 data.vert_positions = result->vert_positions_for_write();
2047 data.vert_normals = result->vert_normals();
2054 result->tag_positions_changed();
2060 result->tag_positions_changed();
2080 if (surface->pointcache) {
2081 surface->pointcache->startframe = surface->start_frame;
2082 surface->pointcache->endframe = surface->end_frame;
2115 for (; surface; surface = surface->next) {
2116 int current_frame =
int(scene->r.cfra);
2117 bool no_surface_data;
2130 no_surface_data = surface->data ==
nullptr;
2136 CLAMP(current_frame, surface->start_frame, surface->end_frame);
2138 if (no_surface_data || current_frame != surface->current_frame ||
2139 int(scene->r.cfra) == surface->start_frame)
2143 surface->current_frame = current_frame;
2152 if (
int(scene->r.cfra) == surface->start_frame && !(cache->
flag &
PTCACHE_BAKED)) {
2155 cache->
flag &= ~PTCACHE_REDO_NEEDED;
2159 bool can_simulate = (
int(scene->r.cfra) == current_frame) &&
2166 else if (can_simulate) {
2170 canvas->
flags &= ~MOD_DPAINT_BAKING;
2202#define JITTER_SAMPLES \
2204 0.0f, 0.0f, -0.2f, -0.4f, 0.2f, 0.4f, 0.4f, -0.2f, -0.4f, 0.3f, \
2230 Vec3f *tempWeights = data->tempWeights;
2233 const float(*mloopuv)[2] = data->mloopuv;
2236 const Bounds2D *faceBB = data->faceBB;
2240 const int w = surface->image_resolution;
2243 for (
int tx = 0; tx <
w; tx++) {
2244 const int index = tx +
w * ty;
2254 point[0][0] = (
float(tx) + 0.5f) /
w;
2255 point[0][1] = (
float(ty) + 0.5f) / h;
2261 point[1][0] =
float(tx) /
w;
2262 point[1][1] =
float(ty) / h;
2264 point[2][0] = (
float(tx) + 1) /
w;
2265 point[2][1] =
float(ty) / h;
2267 point[3][0] =
float(tx) /
w;
2268 point[3][1] = (
float(ty) + 1) / h;
2270 point[4][0] = (
float(tx) + 1) /
w;
2271 point[4][1] = (
float(ty) + 1) / h;
2280 if ((faceBB[i].
min[0] > point[
sample][0]) || (faceBB[i].
min[1] > point[
sample][1]) ||
2281 (faceBB[i].max[0] < point[
sample][0]) || (faceBB[i].
max[1] < point[
sample][1]))
2286 const float *uv1 = mloopuv[corner_tris[i][0]];
2287 const float *uv2 = mloopuv[corner_tris[i][1]];
2288 const float *uv3 = mloopuv[corner_tris[i][2]];
2295 for (
int j = 0; j < aa_samples; j++) {
2296 uv[0] = point[0][0] + jitter5sample[j * 2] /
w;
2297 uv[1] = point[0][1] + jitter5sample[j * 2 + 1] / h;
2306 tPoint->
v1 = corner_verts[corner_tris[i][0]];
2307 tPoint->
v2 = corner_verts[corner_tris[i][1]];
2308 tPoint->
v3 = corner_verts[corner_tris[i][2]];
2327 Vec3f *tempWeights = data->tempWeights;
2330 const float(*mloopuv)[2] = data->mloopuv;
2333 uint32_t *active_points = data->active_points;
2337 const int w = surface->image_resolution;
2340 for (
int tx = 0; tx <
w; tx++) {
2341 const int index = tx +
w * ty;
2349 const int u_min = (tx > 0) ? -1 : 0;
2350 const int u_max = (tx < (
w - 1)) ? 1 : 0;
2351 const int v_min = (ty > 0) ? -1 : 0;
2352 const int v_max = (ty < (h - 1)) ? 1 : 0;
2354 point[0] = (
float(tx) + 0.5f) /
w;
2355 point[1] = (
float(ty) + 0.5f) / h;
2358 for (
int ni = 0; ni < 8; ni++) {
2362 if (u >= u_min && u <= u_max && v >= v_min &&
v <= v_max) {
2364 if (u != 0 ||
v != 0) {
2365 const int ind = (tx + u) +
w * (ty +
v);
2368 if (tempPoints[ind].neighbor_pixel == -1 && tempPoints[ind].tri_index != -1) {
2370 const int i = tempPoints[ind].
tri_index;
2371 const float *uv1 = mloopuv[corner_tris[i][0]];
2372 const float *uv2 = mloopuv[corner_tris[i][1]];
2373 const float *uv3 = mloopuv[corner_tris[i][2]];
2389 for (
int j = 0; j < aa_samples; j++) {
2390 uv[0] = point[0] + jitter5sample[j * 2] /
w;
2391 uv[1] = point[1] + jitter5sample[j * 2 + 1] / h;
2396 tPoint->
v1 = corner_verts[corner_tris[i][0]];
2397 tPoint->
v2 = corner_verts[corner_tris[i][1]];
2398 tPoint->
v3 = corner_verts[corner_tris[i][2]];
2414#undef JITTER_SAMPLES
2417 const float (*mloopuv)[2],
2419 const float point[2])
2425 for (
int i = 0; i < 3; i++) {
2428 mloopuv[corner_tris[tri_index][(i + 0)]],
2429 mloopuv[corner_tris[tri_index][(i + 1) % 3]]);
2431 if (dist_squared < min_distance) {
2432 min_distance = dist_squared;
2436 return min_distance;
2450 const float pixel[2],
2474 const int x = px +
neighX[n_index];
2475 const int y = py +
neighY[n_index];
2518 bdata.best_weight = 1.0f;
2522 pixel[0] = (
float(px +
neighX[n_index]) + 0.5f) /
float(
w);
2523 pixel[1] = (
float(py +
neighY[n_index]) + 0.5f) /
float(h);
2528 return bdata.best_index;
2535 const float pixel[2],
2541 const float(*mloopuv)[2] = data->mloopuv;
2543 const int3 loop_idx = corner_tris[tri_index];
2546 for (
int edge_idx = 0; edge_idx < 3; edge_idx++) {
2548 if (edge_idx == in_edge) {
2552 float uv0[2], uv1[2], uv2[2];
2554 copy_v2_v2(uv0, mloopuv[loop_idx[(edge_idx + 0)]]);
2555 copy_v2_v2(uv1, mloopuv[loop_idx[(edge_idx + 1) % 3]]);
2556 copy_v2_v2(uv2, mloopuv[loop_idx[(edge_idx + 2) % 3]]);
2563 if (side2 == 0.0f) {
2568 const bool correct_side = (in_edge == -1) || (sidep < 0 && side2 > 0) ||
2569 (sidep > 0 && side2 < 0);
2572 if (!correct_side && sidep != 0.0f) {
2577 const int vert0 = corner_verts[loop_idx[(edge_idx + 0)]];
2578 const int vert1 = corner_verts[loop_idx[(edge_idx + 1) % 3]];
2584 bool found_other =
false;
2585 int target_tri = -1;
2586 int target_edge = -1;
2588 float ouv0[2], ouv1[2];
2590 for (
int i = 0; i < map->count && !found_other; i++) {
2591 const int tri_other_index = map->
indices[i];
2593 if (tri_other_index == tri_index) {
2597 const int3 other_tri = corner_tris[tri_other_index];
2600 for (
int j = 0; j < 3; j++) {
2601 const int overt0 = corner_verts[other_tri[(j + 0)]];
2602 const int overt1 = corner_verts[other_tri[(j + 1) % 3]];
2605 if (overt0 == vert0 && overt1 == vert1) {
2607 copy_v2_v2(ouv0, mloopuv[other_tri[(j + 0)]]);
2608 copy_v2_v2(ouv1, mloopuv[other_tri[(j + 1) % 3]]);
2610 else if (overt0 == vert1 && overt1 == vert0) {
2612 copy_v2_v2(ouv1, mloopuv[other_tri[(j + 0)]]);
2613 copy_v2_v2(ouv0, mloopuv[other_tri[(j + 1) % 3]]);
2617 target_tri = tri_other_index;
2634 if (depth > 0 && correct_side) {
2653 float closest_point[2], dir_vec[2], tgt_pixel[2];
2656 CLAMP(lambda, 0.0f, 1.0f);
2661 int w = bdata->
w, h = bdata->
h, px = bdata->
px, py = bdata->
py;
2663 const int final_pixel[2] = {
int(
floorf(tgt_pixel[0] *
w)),
int(
floorf(tgt_pixel[1] * h))};
2666 if (final_pixel[0] < 0 || final_pixel[0] >=
w || final_pixel[1] < 0 || final_pixel[1] >= h) {
2675 int final_index = final_pixel[0] +
w * final_pixel[1];
2678 if (final_index == (px +
w * py)) {
2683 if (tempPoints[final_index].neighbor_pixel != -1) {
2687 if (final_index == (px +
w * py)) {
2692 const int final_tri_index = tempPoints[final_index].
tri_index;
2694 if (!
ELEM(final_tri_index, target_tri, -1)) {
2697 const float final_pt[2] = {((final_index %
w) + 0.5f) /
w, ((final_index /
w) + 0.5f) / h};
2698 const float threshold =
square_f(0.7f) / (
w * h);
2714 const int idx = ed->
n_index[index];
2716 for (
int i = 0; i < ed->
n_num[index]; i++) {
2717 if (ed->
n_target[idx + i] == neighbor) {
2729 int *new_n_index =
static_cast<int *
>(
2730 MEM_callocN(
sizeof(
int) * active_points,
"Surface Adj Index"));
2731 int *new_n_num =
static_cast<int *
>(
2732 MEM_callocN(
sizeof(
int) * active_points,
"Surface Adj Counts"));
2734 if (new_n_num && new_n_index) {
2736 int total_targets = 0;
2738 for (
int index = 0; index < active_points; index++) {
2739 total_targets += ed->
n_num[index];
2740 new_n_num[index] = ed->
n_num[index];
2743 for (
int index = 0; index < active_points; index++) {
2748 for (
int i = 0, idx = ed->
n_index[index]; i < ed->
n_num[index]; i++) {
2749 const int target = ed->
n_target[idx + i];
2754 new_n_num[target]++;
2761 int *new_n_target =
static_cast<int *
>(
2762 MEM_callocN(
sizeof(
int) * total_targets,
"Surface Adj Targets"));
2768 for (
int index = 0; index < active_points; index++) {
2769 new_n_index[index] = n_pos;
2770 memcpy(&new_n_target[n_pos],
2772 sizeof(
int) * ed->
n_num[index]);
2775 n_pos += new_n_num[index];
2776 new_n_num[index] = ed->
n_num[index];
2782 for (
int index = 0; index < active_points; index++) {
2787 for (
int i = 0, idx = ed->
n_index[index]; i < ed->
n_num[index]; i++) {
2788 const int target = ed->
n_target[idx + i];
2791 const int num = new_n_num[target]++;
2792 new_n_target[new_n_index[target] + num] = index;
2805 ed->
n_num = new_n_num;
2838 Vec3f *tempWeights =
nullptr;
2839 const float(*mloopuv)[2] =
nullptr;
2848 return setError(canvas,
N_(
"Canvas mesh not updated"));
2851 return setError(canvas,
N_(
"Cannot bake non-'image sequence' formats"));
2860 &mesh->corner_data,
CD_PROP_FLOAT2, surface->uvlayer_name, uvname);
2861 mloopuv =
static_cast<const float(*)[2]
>(
2867 return setError(canvas,
N_(
"No UV data on canvas"));
2869 if (surface->image_resolution < 16 || surface->image_resolution > 8192) {
2870 return setError(canvas,
N_(
"Invalid resolution"));
2873 const int w = surface->image_resolution;
2880 &
LOG, 1,
"Preparing UV surface of %ix%i pixels and %i tris.",
w, h,
int(corner_tris.
size()));
2883 if (surface->data) {
2886 sData = surface->data = MEM_cnew<PaintSurfaceData>(__func__);
2887 if (!surface->data) {
2888 return setError(canvas,
N_(
"Not enough free memory"));
2892 MEM_callocN(
w * h *
sizeof(*tempPoints),
"Temp PaintUVPoint"));
2897 final_index =
static_cast<int *
>(
2898 MEM_callocN(
w * h *
sizeof(*final_index),
"Temp UV Final Indexes"));
2903 tempWeights =
static_cast<Vec3f *
>(
2904 MEM_mallocN(
w * h * aa_samples *
sizeof(*tempWeights),
"Temp bWeights"));
2927 copy_v2_v2(faceBB[i].max, mloopuv[corner_tris[i][0]]);
2929 for (
int j = 1; j < 3; j++) {
2940 data.tempPoints = tempPoints;
2941 data.tempWeights = tempWeights;
2942 data.corner_tris = corner_tris;
2943 data.mloopuv = mloopuv;
2944 data.corner_verts = corner_verts;
2945 data.faceBB = faceBB;
2950 settings.use_threading = (h > 64 || corner_tris.
size() > 1000);
2963 data.active_points = &active_points;
2967 settings.use_threading = (h > 64);
2980 for (
int i = 0; i <
w * h; i++) {
2981 if (tempPoints[i].tri_index != -1) {
2982 final_index[i] = cursor;
2995 int *vert_to_tri_map_mem;
2998 &vert_to_tri_map_mem,
3002 corner_verts.
data(),
3005 int total_border = 0;
3007 for (
int ty = 0; ty < h; ty++) {
3008 for (
int tx = 0; tx <
w; tx++) {
3009 const int index = tx +
w * ty;
3011 if (tempPoints[index].tri_index != -1) {
3012 ed->
n_index[final_index[index]] = n_pos;
3013 ed->
n_num[final_index[index]] = 0;
3015 if (tempPoints[index].neighbor_pixel != -1) {
3020 for (
int i = 0; i < 8; i++) {
3024 &data, vert_to_tri_map,
w, h, tx, ty, i);
3026 if (n_target >= 0 && n_target != index) {
3028 ed, final_index[index], final_index[n_target]))
3030 ed->
n_target[n_pos] = final_index[n_target];
3031 ed->
n_num[final_index[index]]++;
3052 ed->
border =
static_cast<int *
>(
3053 MEM_callocN(
sizeof(
int) * total_border,
"Border Pixel Index"));
3058 for (
int i = 0,
next = 0; i < active_points; i++) {
3069 FILE *dump_file = fopen(
"dynpaint-adj-data.txt",
"w");
3070 int *tmp =
MEM_callocN(
sizeof(
int) * active_points,
"tmp");
3071 for (
int ty = 0; ty < h; ty++) {
3072 for (
int tx = 0; tx <
w; tx++) {
3073 const int index = tx +
w * ty;
3074 if (tempPoints[index].tri_index != -1) {
3075 tmp[final_index[index]] = index;
3079 for (
int ty = 0; ty < h; ty++) {
3080 for (
int tx = 0; tx <
w; tx++) {
3081 const int index = tx +
w * ty;
3082 const int fidx = final_index[index];
3084 if (tempPoints[index].tri_index != -1) {
3087 "%d\t%d,%d\t%u\t%d,%d\t%d\t",
3091 tempPoints[index].tri_index,
3092 nidx < 0 ? -1 : (nidx %
w),
3093 nidx < 0 ? -1 : h - 1 - (nidx /
w),
3095 for (
int i = 0; i < ed->
n_num[fidx]; i++) {
3097 fprintf(dump_file,
"%s%d,%d", i ?
" " :
"", tgt %
w, h - 1 - tgt /
w);
3099 fprintf(dump_file,
"\n");
3145 for (
int index = 0, cursor = 0; index < (
w * h); index++) {
3146 if (tempPoints[index].tri_index != -1) {
3149 &tempWeights[index * aa_samples],
3150 sizeof(*tempWeights) * aa_samples);
3157 setError(canvas,
N_(
"Not enough free memory"));
3181 for (index = 0; index < sData->
total_points; index++) {
3185 pPoint->alpha = 1.0f;
3189 pPoint->
color[2] = 1.0f;
3194 pPoint->
color[0] = 1.0f;
3206 return (
error == 0);
3227 ImBuf *ibuf = data->ibuf;
3229 const int pos = ((
ImgSeqFormatData *)(surface->data->format_data))->uv_p[index].pixel_index * 4;
3245 void *__restrict userdata,
const int index,
const TaskParallelTLS *__restrict )
3251 float depth = ((
float *)surface->data->type_data)[index];
3253 ImBuf *ibuf = data->ibuf;
3255 const int pos = ((
ImgSeqFormatData *)(surface->data->format_data))->uv_p[index].pixel_index * 4;
3257 if (surface->depth_clamp) {
3258 depth /= surface->depth_clamp;
3262 depth = (0.5f - depth / 2.0f);
3265 CLAMP(depth, 0.0f, 1.0f);
3280 float depth = wPoint->
height;
3282 ImBuf *ibuf = data->ibuf;
3284 const int pos = ((
ImgSeqFormatData *)(surface->data->format_data))->uv_p[index].pixel_index * 4;
3286 if (surface->depth_clamp) {
3287 depth /= surface->depth_clamp;
3290 depth = (0.5f + depth / 2.0f);
3291 CLAMP(depth, 0.0f, 1.0f);
3307 ImBuf *ibuf = data->ibuf;
3309 const int pos = ((
ImgSeqFormatData *)(surface->data->format_data))->uv_p[index].pixel_index * 4;
3316 const char *filepath,
3319 ImBuf *ibuf =
nullptr;
3327 setError(surface->canvas,
N_(
"Image save failed: invalid surface"));
3336 STRNCPY(output_file, filepath);
3345 if (ibuf ==
nullptr) {
3346 setError(surface->canvas,
N_(
"Image save failed: not enough free memory"));
3354 switch (surface->type) {
3356 switch (output_layer) {
3360 settings.use_threading = (sData->
total_points > 10000);
3371 settings.use_threading = (sData->
total_points > 10000);
3385 switch (output_layer) {
3389 settings.use_threading = (sData->
total_points > 10000);
3405 switch (output_layer) {
3409 settings.use_threading = (sData->
total_points > 10000);
3464 const int3 *corner_tris = data->corner_tris.
data();
3465 const int *corner_verts = data->corner_verts.data();
3467 const float *t0, *t1, *t2;
3470 t0 = positions[corner_verts[corner_tris[index][0]]];
3471 t1 = positions[corner_verts[corner_tris[index][1]]];
3472 t2 = positions[corner_verts[corner_tris[index][2]]];
3476 if (dist >= 0 && dist < hit->dist) {
3496 const int3 *corner_tris = data->corner_tris.
data();
3497 const int *corner_verts = data->corner_verts.data();
3498 float nearest_tmp[3], dist_sq;
3500 const float *t0, *t1, *t2;
3501 t0 = positions[corner_verts[corner_tris[index][0]]];
3502 t1 = positions[corner_verts[corner_tris[index][1]]];
3503 t2 = positions[corner_verts[corner_tris[index][2]]];
3508 if (dist_sq < nearest->dist_sq) {
3509 nearest->index = index;
3510 nearest->dist_sq = dist_sq;
3512 nearest->no[0] = 0.0f;
3530 const int paintFlags,
3531 const float paintColor[3],
3532 const float paintAlpha,
3533 const float paintWetness,
3534 const float timescale)
3554 float wetness = paintWetness;
3555 CLAMP(wetness, 0.0f, 1.0f);
3566 float a_ratio, a_highest;
3568 float invFact = 1.0f - paintAlpha;
3576 if (a_highest > invFact) {
3577 a_ratio = invFact / a_highest;
3579 pPoint->
e_color[3] *= a_ratio;
3580 pPoint->
color[3] *= a_ratio;
3584 pPoint->
e_color[3] -= paintAlpha * timescale;
3586 pPoint->
color[3] -= paintAlpha * timescale;
3590 wetness = (1.0f - paintWetness) * pPoint->
e_color[3];
3600 const float isect_change = isect_height - wPoint->
brush_isect;
3608 isect_height *= wave_factor;
3611 if (wave_factor > 0.0f && wPoint->
height > isect_height) {
3614 else if (wave_factor < 0.0f && wPoint->height < isect_height) {
3621 wPoint->
height = isect_height;
3632 if (isect_change < 0.0f) {
3633 wPoint->
height += isect_change * wave_factor;
3653 const float timescale)
3659 influence *= surface->influence_scale;
3660 depth *= surface->influence_scale;
3662 strength = influence * brush->
alpha;
3663 CLAMP(strength, 0.0f, 1.0f);
3671 CLAMP(vel_factor, 0.0f, 1.0f);
3678 strength *= coba_res[3];
3681 depth *= coba_res[3];
3688 float paintWetness = brush->
wetness * strength;
3689 float paintAlpha = strength;
3692 surface, index, brush->
flags, paint, paintAlpha, paintWetness, timescale);
3696 float *value = (
float *)sData->
type_data;
3699 depth = value[index] + depth;
3702 if (surface->depth_clamp) {
3703 CLAMP(depth, 0.0f - surface->depth_clamp, surface->depth_clamp);
3707 value[index] *= (1.0f - strength);
3716 float *value = (
float *)sData->
type_data;
3719 value[index] *= (1.0f - strength);
3776 Vec3f *brush_vel = data->brush_vel;
3778 const float(*positions_p)[3] = data->positions_p;
3779 const float(*positions_c)[3] = data->positions_c;
3781 const float(*obmat)[4] = data->obmat;
3782 float(*prev_obmat)[4] = data->prev_obmat;
3784 const float timescale = data->timescale;
3805 float prev_obmat[4][4];
3806 Mesh *mesh_p, *mesh_c;
3807 int numOfVerts_p, numOfVerts_c;
3809 float cur_sfra = scene->r.subframe;
3810 int cur_fra = scene->r.cfra;
3811 float prev_sfra = cur_sfra - timescale;
3812 int prev_fra = cur_fra;
3814 if (prev_sfra < 0.0f) {
3816 prev_fra = cur_fra - 1;
3820 scene->r.cfra = prev_fra;
3821 scene->r.subframe = prev_sfra;
3833 float(*positions_p)[3] =
reinterpret_cast<float(*)[3]
>(
3834 mesh_p->vert_positions_for_write().data());
3835 copy_m4_m4(prev_obmat, ob->object_to_world().ptr());
3838 scene->r.cfra = cur_fra;
3839 scene->r.subframe = cur_sfra;
3850 float(*positions_c)[3] =
reinterpret_cast<float(*)[3]
>(
3851 mesh_c->vert_positions_for_write().data());
3860 if (numOfVerts_p != numOfVerts_c) {
3861 positions_p = positions_c;
3867 data.positions_p = positions_p;
3868 data.positions_c = positions_c;
3869 data.obmat = ob->object_to_world().ptr();
3870 data.prev_obmat = prev_obmat;
3871 data.timescale = timescale;
3875 settings.use_threading = (numOfVerts_c > 10000);
3886 float prev_obmat[4][4];
3887 float cur_loc[3] = {0.0f}, prev_loc[3] = {0.0f};
3889 float cur_sfra = scene->r.subframe;
3890 int cur_fra = scene->r.cfra;
3891 float prev_sfra = cur_sfra - timescale;
3892 int prev_fra = cur_fra;
3894 if (prev_sfra < 0.0f) {
3896 prev_fra = cur_fra - 1;
3900 scene->r.cfra = prev_fra;
3901 scene->r.subframe = prev_sfra;
3909 copy_m4_m4(prev_obmat, ob->object_to_world().ptr());
3912 scene->r.cfra = cur_fra;
3913 scene->r.subframe = cur_sfra;
3924 mul_m4_v3(ob->object_to_world().ptr(), cur_loc);
3970 const float timescale = data->timescale;
3971 const int c_index = data->c_index;
3976 const float brush_radius = data->brush_radius;
3977 const float *avg_brushNor = data->avg_brushNor;
3978 const Vec3f *brushVelocity = data->brushVelocity;
3982 const int index = grid->t_index[grid->s_pos[c_index] + id];
3983 const int samples = bData->
s_num[index];
3985 float total_sample =
float(samples);
3986 float brushStrength = 0.0f;
3988 float velocity_val = 0.0f;
3990 float paintColor[3] = {0.0f};
3999 for (ss = 0; ss < samples; ss++) {
4000 float ray_start[3], ray_dir[3];
4001 float sample_factor = 0.0f;
4002 float sampleStrength = 0.0f;
4005 short hit_found = 0;
4008 float volume_factor = 0.0f;
4010 float proximity_factor = 0.0f;
4011 float prox_colorband[4] = {0.0f};
4024 sample_factor = 1.0f;
4037 nearest.dist_sq = brush_radius * brush_radius;
4043 if (hit.index != -1) {
4047 const int vtri[3] = {
4048 corner_verts[corner_tris[hit.index][0]],
4049 corner_verts[corner_tris[hit.index][1]],
4050 corner_verts[corner_tris[hit.index][2]],
4054 normal_tri_v3(hit.no, positions[vtri[0]], positions[vtri[1]], positions[vtri[2]]);
4060 const float dist = hit.dist;
4061 const int f_index = hit.index;
4072 if (hit.index != -1) {
4074 volume_factor = 1.0f;
4082 depth += dist * sample_factor;
4093 float proxDist = -1.0f;
4094 float hitCo[3] = {0.0f, 0.0f, 0.0f};
4098 if (inner_proximity && !hit_found) {
4106 if (nearest.index != -1) {
4107 proxDist =
sqrtf(nearest.dist_sq);
4109 tri = nearest.index;
4113 float proj_ray[3] = {0.0f};
4126 hit.dist = brush_radius;
4131 if (hit.index != -1) {
4132 proxDist = hit.dist;
4142 if (proxDist >= 0.0f && proxDist <= brush_radius) {
4143 proximity_factor = proxDist / brush_radius;
4144 CLAMP(proximity_factor, 0.0f, 1.0f);
4145 if (!inner_proximity) {
4146 proximity_factor = 1.0f - proximity_factor;
4163 volume_factor = 1.0f - volume_factor;
4164 if (inner_proximity) {
4165 proximity_factor = 1.0f - proximity_factor;
4171 sampleStrength = volume_factor;
4178 proximity_factor = prox_colorband[3];
4185 sampleStrength = proximity_factor;
4188 sampleStrength *= sample_factor;
4197 float brushPointVelocity[3];
4200 const int v1 = corner_verts[corner_tris[hitTri][0]];
4201 const int v2 = corner_verts[corner_tris[hitTri][1]];
4202 const int v3 = corner_verts[corner_tris[hitTri][2]];
4212 brushVelocity[v1].
v,
4213 brushVelocity[
v2].
v,
4214 brushVelocity[v3].
v,
4239 float sampleColor[3];
4240 float alpha_factor = 1.0f;
4242 sampleColor[0] = brush->
r;
4243 sampleColor[1] = brush->
g;
4244 sampleColor[2] = brush->
b;
4249 sampleColor[0] = prox_colorband[0];
4250 sampleColor[1] = prox_colorband[1];
4251 sampleColor[2] = prox_colorband[2];
4256 paintColor[0] += sampleColor[0];
4257 paintColor[1] += sampleColor[1];
4258 paintColor[2] += sampleColor[2];
4259 sampleStrength *= alpha_factor;
4264 brushStrength += sampleStrength;
4268 if (brushStrength > 0.0f || depth > 0.0f) {
4271 brushStrength /= total_sample;
4273 CLAMP(brushStrength, 0.0f, 1.0f);
4277 paintColor[0] /= numOfHits;
4278 paintColor[1] /= numOfHits;
4279 paintColor[2] /= numOfHits;
4287 surface, index, brush, paintColor, brushStrength, depth, velocity_val, timescale);
4300 Mesh *mesh =
nullptr;
4301 Vec3f *brushVelocity =
nullptr;
4305 depsgraph, scene, brushOb, brush, &brushVelocity, timescale);
4309 if (brush_mesh ==
nullptr) {
4315 float avg_brushNor[3] = {0.0f};
4316 const float brush_radius = brush->
paint_distance * surface->radius_scale;
4327 numOfVerts = mesh->verts_num;
4332 for (ii = 0; ii < numOfVerts; ii++) {
4333 mul_m4_v3(brushOb->object_to_world().ptr(), positions[ii]);
4348 mul_v3_fl(avg_brushNor, 1.0f /
float(numOfVerts));
4351 avg_brushNor[2] = 1.0f;
4360 int total_cells = grid->dim[0] * grid->dim[1] * grid->dim[2];
4363 for (c_index = 0; c_index < total_cells; c_index++) {
4365 if (!grid->s_num[c_index] ||
4375 data.brushOb = brushOb;
4377 data.timescale = timescale;
4378 data.c_index = c_index;
4380 data.positions = positions;
4381 data.corner_verts = corner_verts;
4382 data.corner_tris = corner_tris;
4383 data.brush_radius = brush_radius;
4384 data.avg_brushNor = avg_brushNor;
4385 data.brushVelocity = brushVelocity;
4386 data.treeData = &treeData;
4390 settings.use_threading = (grid->s_num[c_index] > 250);
4392 grid->s_num[c_index],
4405 if (brushVelocity) {
4416 void *__restrict userdata,
const int id,
const TaskParallelTLS *__restrict )
4429 const float timescale = data->timescale;
4430 const int c_index = data->c_index;
4432 KDTree_3d *
tree =
static_cast<KDTree_3d *
>(data->treeData);
4434 const float solidradius = data->solidradius;
4436 const float range = solidradius +
smooth;
4437 const float particle_timestep = 0.04f * psys->
part->
timetweak;
4439 const int index = grid->t_index[grid->s_pos[c_index] + id];
4440 float disp_intersect = 0.0f;
4441 float radius = 0.0f;
4442 float strength = 0.0f;
4443 int part_index = -1;
4450 KDTreeNearest_3d nearest;
4451 float smooth_range, part_solidradius;
4456 if (nearest.dist > range) {
4463 part_solidradius = pa->
size;
4466 part_solidradius = solidradius;
4468 radius = part_solidradius +
smooth;
4469 if (nearest.dist < radius) {
4471 smooth_range =
max_ff(0.0f, (nearest.dist - part_solidradius));
4477 strength = 1.0f - smooth_range;
4478 disp_intersect = radius - nearest.dist;
4479 part_index = nearest.index;
4488 KDTreeNearest_3d *nearest;
4490 float smooth_range = smooth * (1.0f - strength), dist;
4492 const float max_range = smooth - strength * smooth + solidradius;
4496 const int particles = BLI_kdtree_3d_range_search(
4500 for (
int n = 0; n < particles; n++) {
4504 if (nearest[n].dist > (pa->
size + smooth)) {
4509 const float s_range = nearest[n].dist - pa->
size;
4511 if (smooth_range < s_range) {
4516 smooth_range = s_range;
4517 dist = nearest[n].dist;
4518 part_index = nearest[n].index;
4521 if ((s_range < 0.0f) &&
4533 const float rad = radius +
smooth;
4534 if ((rad - dist) > disp_intersect) {
4535 disp_intersect = radius - dist;
4545 const float str = 1.0f - smooth_range;
4547 if (
str > strength) {
4552 if (strength > 0.001f) {
4553 float paintColor[4] = {0.0f};
4555 float velocity_val = 0.0f;
4583 disp_intersect = (1.0f -
sqrtf(disp_intersect / radius)) * radius;
4588 surface, index, brush, paintColor, strength, depth, velocity_val, timescale);
4603 int particlesAdded = 0;
4604 int invalidParticles = 0;
4612 const float range = solidradius +
smooth;
4637 if (isnan(pa->state.co[0]) || isnan(pa->state.co[1]) || isnan(pa->state.co[2])) {
4647 BLI_kdtree_3d_insert(
tree, p, pa->state.co);
4654 if (invalidParticles) {
4659 if (particlesAdded < 1) {
4660 BLI_kdtree_3d_free(
tree);
4667 int total_cells = grid->dim[0] * grid->dim[1] * grid->dim[2];
4670 BLI_kdtree_3d_balance(
tree);
4673 for (c_index = 0; c_index < total_cells; c_index++) {
4675 if (!grid->s_num[c_index] || !
boundsIntersectDist(&grid->bounds[c_index], &part_bb, range)) {
4684 data.solidradius = solidradius;
4685 data.timescale = timescale;
4686 data.c_index = c_index;
4687 data.treeData =
tree;
4691 settings.use_threading = (grid->s_num[c_index] > 250);
4693 grid->s_num[c_index],
4699 BLI_kdtree_3d_free(
tree);
4717 const float timescale = data->timescale;
4719 const float brush_radius = data->brush_radius;
4720 const Vec3f *brushVelocity = data->brushVelocity;
4722 float *pointCoord = data->pointCoord;
4725 float colorband[4] = {0.0f};
4728 if (distance > brush_radius) {
4734 strength = 1.0f - distance / brush_radius;
4735 CLAMP(strength, 0.0f, 1.0f);
4741 if (strength >= 0.001f) {
4742 float paintColor[3] = {0.0f};
4744 float velocity_val = 0.0f;
4750 strength = colorband[3];
4763 velocity_val =
len_v3(velocity);
4778 paintColor[0] = colorband[0];
4779 paintColor[1] = colorband[1];
4780 paintColor[2] = colorband[2];
4783 paintColor[0] = brush->
r;
4784 paintColor[1] = brush->
g;
4785 paintColor[2] = brush->
b;
4790 const float disp_intersect = (1.0f -
sqrtf((brush_radius - distance) / brush_radius)) *
4795 surface, index, brush, paintColor, strength, depth, velocity_val, timescale);
4811 float brush_radius = brush->
paint_distance * surface->radius_scale;
4826 data.brushOb = brushOb;
4828 data.timescale = timescale;
4829 data.positions = brush_mesh->vert_positions();
4830 data.brush_radius = brush_radius;
4831 data.brushVelocity = &brushVel;
4832 data.pointCoord = pointCoord;
4859 const int num_neighs = adj_data->
n_num[index];
4861 for (
int i = 0; i < num_neighs; i++) {
4862 const int n_index = adj_data->
n_index[index] + i;
4863 const int t_index = adj_data->
n_target[n_index];
4867 realCoord[bData->
s_pos[t_index]].
v,
4868 realCoord[bData->
s_pos[index]].
v);
4906 for (index = 0; index < sData->
total_points; index++) {
4907 int numOfNeighs = adj_data->
n_num[index];
4909 for (
int i = 0; i < numOfNeighs; i++) {
4920 const float force[3],
4927 closest_id[0] = closest_id[1] = -1;
4928 closest_d[0] = closest_d[1] = -1.0f;
4931 for (
int i = 0; i < numOfNeighs; i++) {
4933 const float dir_dot =
dot_v3v3(bNeighs[n_index].dir, force);
4935 if (dir_dot > closest_d[0] && dir_dot > 0.0f) {
4936 closest_d[0] = dir_dot;
4937 closest_id[0] = n_index;
4941 if (closest_d[0] < 0.0f) {
4946 for (
int i = 0; i < numOfNeighs; i++) {
4949 if (n_index == closest_id[0]) {
4953 const float dir_dot =
dot_v3v3(bNeighs[n_index].dir, force);
4954 const float closest_dot =
dot_v3v3(bNeighs[n_index].dir, bNeighs[closest_id[0]].dir);
4958 if (dir_dot > closest_d[1] && closest_dot < closest_d[0] && dir_dot > 0.0f) {
4959 closest_d[1] = dir_dot;
4960 closest_id[1] = n_index;
4966 if (closest_id[1] != -1) {
4967 float force_proj[3];
4969 const float neigh_diff =
acosf(
4970 dot_v3v3(bNeighs[closest_id[0]].dir, bNeighs[closest_id[1]].dir));
4971 float force_intersect;
4976 cross_v3_v3v3(tangent, bNeighs[closest_id[0]].dir, bNeighs[closest_id[1]].dir);
4978 force_intersect =
dot_v3v3(force, tangent);
4979 madd_v3_v3v3fl(force_proj, force, tangent, (-1.0f) * force_intersect);
4983 temp =
dot_v3v3(bNeighs[closest_id[0]].dir, force_proj);
4984 CLAMP(temp, -1.0f, 1.0f);
4985 closest_d[1] =
acosf(temp) / neigh_diff;
4986 closest_d[0] = 1.0f - closest_d[1];
4989 temp =
fabsf(force_intersect);
4990 CLAMP(temp, 0.0f, 1.0f);
5006 float max_velocity = 0.0f;
5013 for (
int index = 0; index < sData->
total_points; index++) {
5022 for (
int step = 0; step <
steps; step++) {
5023 for (
int index = 0; index < sData->
total_points; index++) {
5042 sData, index, &bData->
brush_velocity[index * 4], closest_d, closest_id);
5045 for (
int i = 0; i < 2; i++) {
5046 int n_index = closest_id[i];
5047 if (n_index != -1 && closest_d[i] > 0.0f) {
5048 float dir_dot = closest_d[i], dir_factor;
5049 float speed_scale = eff_scale * smudge_str / bNeighs[n_index].
dist;
5054 if (dir_dot <= 0.0f) {
5058 dir_factor = dir_dot * speed_scale;
5063 ePoint->
color[3] = ePoint->
color[3] * (1.0f - dir_factor) +
5064 pPoint->
color[3] * dir_factor;
5073 pPoint->
e_color[3] * dir_factor;
5074 pPoint->
wetness *= (1.0f - dir_factor);
5117 Scene *scene = data->scene;
5119 float *force = data->force;
5120 ListBase *effectors = data->effectors;
5122 float forc[3] = {0};
5131 effectors,
nullptr, surface->effector_weights, &epoint, forc,
nullptr,
nullptr);
5139 scene->physics_settings.gravity,
5140 surface->effector_weights->global_gravity * surface->effector_weights->weight[0] /
5146 if (surface->drip_vel) {
5170 double average_force = 0.0f;
5171 float shrink_speed = 0.0f, spread_speed = 0.0f;
5172 float fastest_effect, avg_dist;
5180 depsgraph, ob,
nullptr, surface->effector_weights,
false);
5183 *force =
static_cast<float *
>(
5190 data.force = *force;
5191 data.effectors = effectors;
5200 for (
int index = 0; index < sData->
total_points; index++) {
5201 average_force +=
double((*force)[index * 4 + 3]);
5213 spread_speed = surface->spread_speed;
5216 shrink_speed = surface->shrink_speed;
5219 fastest_effect =
max_fff(spread_speed, shrink_speed, average_force);
5248 const float eff_scale = data->eff_scale;
5254 for (
int i = 0; i < numOfNeighs; i++) {
5255 const int n_idx = n_index[index] + i;
5257 const PaintPoint *pPoint_prev = &prevPoint[n_target[n_idx]];
5258 const float speed_scale = (bNeighs[n_idx].
dist < eff_scale) ? 1.0f :
5259 eff_scale / bNeighs[n_idx].
dist;
5261 surface->color_spread_speed;
5277 w_factor = 1.0f / numOfNeighs *
min_ff(pPoint_prev->
wetness, 1.0f) * speed_scale;
5278 CLAMP(w_factor, 0.0f, 1.0f);
5307 const float eff_scale = data->eff_scale;
5313 for (
int i = 0; i < numOfNeighs; i++) {
5314 const int n_idx = n_index[index] + i;
5315 const float speed_scale = (bNeighs[n_idx].
dist < eff_scale) ? 1.0f :
5316 eff_scale / bNeighs[n_idx].
dist;
5317 const PaintPoint *pPoint_prev = &prevPoint[n_target[n_idx]];
5318 float a_factor, ea_factor, w_factor;
5327 a_factor =
max_ff((1.0f - pPoint_prev->
color[3]) / numOfNeighs *
5328 (pPoint->
color[3] - pPoint_prev->
color[3]) * speed_scale,
5339 pPoint->
color[3] -= a_factor;
5341 pPoint->
e_color[3] -= ea_factor;
5364 const PaintPoint *pPoint_prev = &prevPoint[index];
5365 const float *force = data->force;
5366 const float eff_scale = data->eff_scale;
5370 uint8_t *point_locks = data->point_locks;
5376 float w_factor = pPoint_prev->
wetness - 0.025f;
5377 if (w_factor <= 0) {
5380 CLAMP(w_factor, 0.0f, 1.0f);
5382 float ppoint_wetness_diff = 0.0f;
5388 for (
int i = 0; i < 2; i++) {
5389 const int n_idx = closest_id[i];
5390 if (n_idx != -1 && closest_d[i] > 0.0f) {
5391 const float dir_dot = closest_d[i];
5394 if (dir_dot <= 0.0f) {
5398 float dir_factor, a_factor;
5399 const float speed_scale = eff_scale * force[index * 4 + 3] / bNeighs[n_idx].
dist;
5401 const uint n_trgt =
uint(n_target[n_idx]);
5406 const uint epointlock_idx = n_trgt / 8;
5407 const uint8_t epointlock_bitmask = 1 << (n_trgt & 7);
5415 const float e_wet = ePoint->
wetness;
5417 dir_factor =
min_ff(0.5f, dir_dot *
min_ff(speed_scale, 1.0f) * w_factor);
5420 ePoint->
wetness += dir_factor;
5424 a_factor = dir_factor / pPoint_prev->
wetness;
5425 CLAMP(a_factor, 0.0f, 1.0f);
5439 ppoint_wetness_diff += (ePoint->
wetness - e_wet);
5444 ~epointlock_bitmask);
5454 const uint ppointlock_idx = index / 8;
5455 const uint8_t ppointlock_bitmask = 1 << (index & 7);
5462 pPoint->
wetness -= ppoint_wetness_diff;
5506 data.prevPoint = prevPoint;
5507 data.eff_scale = eff_scale;
5528 data.prevPoint = prevPoint;
5529 data.eff_scale = eff_scale;
5545 const size_t point_locks_size = (sData->
total_points / 8) + 1;
5547 MEM_callocN(
sizeof(*point_locks) * point_locks_size, __func__));
5554 data.prevPoint = prevPoint;
5555 data.eff_scale = eff_scale;
5557 data.point_locks = point_locks;
5587 float mix_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5588 float mix_e_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5589 float mix_wetness = 0.0f;
5591 for (
int i = 0; i < numOfNeighs; i++) {
5592 const int n_idx = n_index[index] + i;
5593 const int target = n_target[n_idx];
5600 mix_color[3] += pPoint2->
color[3];
5603 mix_e_color[3] += pPoint2->
e_color[3];
5605 mix_wetness += pPoint2->
wetness;
5608 const float divisor = 1.0f / numOfNeighs;
5611 pPoint->
color[3] = mix_color[3] * divisor;
5615 pPoint->
color[3] = 0.0f;
5618 if (mix_e_color[3]) {
5619 pPoint->
e_color[3] = mix_e_color[3] * divisor;
5626 pPoint->
wetness = mix_wetness / numOfNeighs;
5659 const float wave_speed = data->wave_speed;
5660 const float wave_scale = data->wave_scale;
5661 const float wave_max_slope = data->wave_max_slope;
5663 const float dt = data->dt;
5664 const float min_dist = data->min_dist;
5665 const float damp_factor = data->damp_factor;
5669 float force = 0.0f, avg_dist = 0.0f, avg_height = 0.0f, avg_n_height = 0.0f;
5670 int numOfN = 0, numOfRN = 0;
5672 if (wPoint->
state > 0) {
5681 for (
int i = 0; i < numOfNeighs; i++) {
5682 const int n_idx = n_index[index] + i;
5683 float dist = bNeighs[n_idx].
dist * wave_scale;
5686 if (!dist || tPoint->
state > 0) {
5696 avg_n_height += tPoint->
height;
5700 force += (tPoint->
height - wPoint->
height) / (dist * dist);
5701 avg_height += tPoint->
height;
5703 avg_dist = (numOfN) ? avg_dist / numOfN : 0.0f;
5707 avg_n_height = (numOfRN) ? avg_n_height / numOfRN : 0.0f;
5708 wPoint->
height = (dt * wave_speed * avg_n_height + wPoint->
height * avg_dist) /
5709 (avg_dist + dt * wave_speed);
5715 force += (0.0f - wPoint->
height) * surface->wave_spring / (avg_dist * avg_dist) / 2.0f;
5719 wPoint->
velocity += force * dt * wave_speed * wave_speed;
5726 if (wave_max_slope && avg_dist) {
5727 const float max_offset = wave_max_slope * avg_dist;
5728 const float offset = (numOfN) ? (avg_height / numOfN - wPoint->
height) : 0.0f;
5729 if (offset > max_offset) {
5730 wPoint->
height += offset - max_offset;
5732 else if (offset < -max_offset) {
5733 wPoint->
height += offset + max_offset;
5738 if (data->reset_wave) {
5753 float dt, min_dist, damp_factor;
5754 const float wave_speed = surface->wave_speed;
5755 const float wave_max_slope = (surface->wave_smoothness >= 0.01f) ?
5756 (0.5f / surface->wave_smoothness) :
5758 double average_dist = 0.0f;
5770 for (index = 0; index < sData->
total_points; index++) {
5773 for (
int i = 0; i < numOfNeighs; i++) {
5781 (average_dist /
double(wave_speed) / 3)));
5787 min_dist = wave_speed * dt * 1.5f;
5788 damp_factor =
pow((1.0f - surface->wave_damping), timescale * surface->wave_timescale);
5790 for (ss = 0; ss <
steps; ss++) {
5796 data.prevPoint = prevPoint;
5797 data.wave_speed = wave_speed;
5798 data.wave_scale = wave_scale;
5799 data.wave_max_slope = wave_max_slope;
5801 data.min_dist = min_dist;
5802 data.damp_factor = damp_factor;
5803 data.reset_wave = (ss ==
steps - 1);
5837 const float timescale = data->timescale;
5846 float p_wetness = pPoint->
wetness;
5854 if (pPoint->
wetness < surface->color_dry_threshold) {
5855 float dry_ratio = pPoint->
wetness / p_wetness;
5868 pPoint->
e_color[3] *= dry_ratio;
5874 if (pPoint->
color[3]) {
5875 for (
int i = 0; i < 3; i++) {
5876 pPoint->
color[i] = (f_color[i] * f_color[3] -
5886 else if (pPoint->
state > 0) {
5899 surface->diss_speed,
5905 surface->diss_speed,
5915 float *point = &((
float *)sData->
type_data)[index];
5930 int numOfVerts = mesh->verts_num;
5942 for (
int i = 0; i < numOfVerts; i++) {
5978 const Vec3f *canvas_verts = data->canvas_verts;
5980 const bool do_velocity_data = data->do_velocity_data;
5981 const bool new_bdata = data->new_bdata;
5983 float prev_point[3] = {0.0f, 0.0f, 0.0f};
5986 if (do_velocity_data && !new_bdata) {
5994 float n1[3], n2[3], n3[3];
5999 bData->
s_pos[index] = index * bData->
s_num[index];
6002 for (
int ss = 0; ss < bData->
s_num[index]; ss++) {
6004 canvas_verts[tPoint->
v1].
v,
6005 canvas_verts[tPoint->
v2].
v,
6006 canvas_verts[tPoint->
v3].
v,
6021 float scaled_nor[3];
6032 bData->
s_num[index] = adj_data->
n_num[index] + 1;
6033 bData->
s_pos[index] = adj_data->
n_index[index] + index;
6036 bData->
s_num[index] = 1;
6037 bData->
s_pos[index] = index;
6041 for (ss = 0; ss < bData->
s_num[index]; ss++) {
6045 int t_index = adj_data->
n_index[index] + (ss - 1);
6049 canvas_verts[adj_data->
n_target[t_index]].
v,
6055 copy_v3_v3(temp_nor, data->vert_normals[index]);
6059 float scaled_nor[3];
6069 if (do_velocity_data && !new_bdata && !bData->
clear) {
6082 bool new_bdata =
false;
6088 int canvasNumOfVerts = mesh->verts_num;
6090 Vec3f *canvas_verts;
6101 if (do_velocity_data && bData->
velocity && (bData->
clear || !surface_moved)) {
6106 if (!surface_moved) {
6112 "Dynamic Paint transformed canvas verts");
6113 if (!canvas_verts) {
6120 "Dynamic Paint bake data");
6130 "Dynamic Paint step data");
6131 bData->
s_pos =
static_cast<int *
>(
6133 bData->
s_num =
static_cast<int *
>(
6136 "Dynamic Paint point coords");
6138 MEM_mallocN(canvasNumOfVerts *
sizeof(
float[3]),
"Dynamic Paint bData prev_positions"));
6158 return setError(surface->canvas,
N_(
"Not enough free memory"));
6164 if (do_velocity_data && !bData->
velocity) {
6166 "Dynamic Paint velocity");
6170 "Dynamic Paint prev velocity");
6181 for (index = 0; index < canvasNumOfVerts; index++) {
6182 copy_v3_v3(canvas_verts[index].
v, positions[index]);
6183 mul_m4_v3(ob->object_to_world().ptr(), canvas_verts[index].
v);
6193 data.positions = positions;
6194 data.vert_normals = mesh->vert_normals();
6195 data.canvas_verts = canvas_verts;
6196 data.do_velocity_data = do_velocity_data;
6197 data.new_bdata = new_bdata;
6214 memcpy(bData->
prev_positions, positions.data(), canvasNumOfVerts *
sizeof(
float[3]));
6244 data.timescale = timescale;
6262 int scene_frame = scene->r.cfra;
6263 float scene_subframe = scene->r.subframe;
6265 for (
int i = 0; i < numobjects; i++) {
6266 Object *brushObj = objects[i];
6279 sizeof(
float[4]) * sData->
total_points,
"Dynamic Paint brush velocity"));
6323 depsgraph, surface, brushObj->
loc, brush, brushObj, scene, timescale);
6326 else if (brushObj != ob) {
6332 scene->r.cfra = scene_frame;
6333 scene->r.subframe = scene_subframe;
6370 float *force =
nullptr;
6376 return setError(canvas,
N_(
"Not enough free memory"));
6381 for (s = 0; s <
steps; s++) {
6406 float timescale = 1.0f;
6417 if (surface->substeps && (frame != surface->start_frame)) {
6419 timescale = 1.0f / (surface->substeps + 1);
6421 for (st = 1; st <= surface->substeps; st++) {
6422 float subframe =
float(st) / (surface->substeps + 1);
void free_bvhtree_from_mesh(BVHTreeFromMesh *data)
BVHTree * BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data, const Mesh *mesh, BVHCacheType bvh_cache_type, int tree_type)
@ BVHTREE_FROM_CORNER_TRIS
float bvhtree_ray_tri_intersection(const BVHTreeRay *ray, float m_dist, const float v0[3], const float v1[3], const float v2[3])
void BKE_collision_objects_free(struct Object **objects)
struct Object ** BKE_collision_objects_create(struct Depsgraph *depsgraph, struct Object *self, struct Collection *collection, unsigned int *numcollobj, unsigned int modifier_type)
bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
ColorBand * BKE_colorband_add(bool rangetype)
CustomData interface, see also DNA_customdata_types.h.
void * CustomData_get_layer_named_for_write(CustomData *data, eCustomDataType type, blender::StringRef name, int totelem)
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void * CustomData_add_layer_named(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem, blender::StringRef name)
void CustomData_validate_layer_name(const CustomData *data, eCustomDataType type, blender::StringRef name, char *outname)
int CustomData_get_named_layer_index(const CustomData *data, eCustomDataType type, blender::StringRef name)
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
void * CustomData_add_layer(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem)
struct PaintPoint PaintPoint
struct PaintWavePoint PaintWavePoint
#define DPAINT_WAVE_ISECT_CHANGED
#define DPAINT_WAVE_REFLECT_ONLY
#define DPAINT_WAVE_OBSTACLE
struct EffectorWeights * BKE_effector_add_weights(struct Collection *collection)
void BKE_effectors_free(struct ListBase *lb)
void BKE_effectors_apply(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *wind_force, float *impulse)
struct ListBase * BKE_effectors_create(struct Depsgraph *depsgraph, struct Object *ob_src, struct ParticleSystem *psys_src, struct EffectorWeights *weights, bool use_rotation)
void pd_point_from_loc(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point)
void BKE_image_pool_free(ImagePool *pool)
ImagePool * BKE_image_pool_new(void)
@ LIB_ID_COPY_SET_COPIED_ON_WRITE
void BKE_id_free(Main *bmain, void *idv)
const char * BKE_main_blendfile_path_from_global()
General operations, lookup, etc. for materials.
Mesh * BKE_mesh_copy_for_eval(const Mesh &source)
void BKE_mesh_vert_corner_tri_map_create(MeshElemMap **r_map, int **r_mem, int totvert, const blender::int3 *corner_tris, int tris_num, const int *corner_verts, int corners_num)
void BKE_modifier_path_init(char *path, int path_maxncpy, const char *name)
ModifierData * BKE_modifiers_findby_type(const Object *ob, ModifierType type)
General operations, lookup, etc. for blender objects.
bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph, Scene *scene, Object *ob, bool update_mesh, int parent_recursion, float frame, int type)
bool psys_check_enabled(struct Object *ob, struct ParticleSystem *psys, bool use_render_params)
void BKE_ptcache_id_time(PTCacheID *pid, struct Scene *scene, float cfra, int *startframe, int *endframe, float *timescale)
void BKE_ptcache_validate(struct PointCache *cache, int framenr)
void BKE_ptcache_id_from_dynamicpaint(PTCacheID *pid, struct Object *ob, struct DynamicPaintSurface *surface)
struct PointCache * BKE_ptcache_add(struct ListBase *ptcaches)
int BKE_ptcache_read(PTCacheID *pid, float cfra, bool no_extrapolate_old)
int BKE_ptcache_write(PTCacheID *pid, unsigned int cfra)
void BKE_ptcache_free_list(struct ListBase *ptcaches)
#define PTCACHE_RESET_OUTDATED
int BKE_ptcache_id_reset(struct Scene *scene, PTCacheID *pid, int mode)
float BKE_scene_ctime_get(const Scene *scene)
bool BLI_file_ensure_parent_dir_exists(const char *filepath) ATTR_NONNULL(1)
#define BVH_RAYCAST_DIST_MAX
int BLI_bvhtree_find_nearest(const BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
int BLI_bvhtree_ray_cast(const BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
A KD-tree for nearest neighbor search.
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
MINLINE float max_fff(float a, float b, float c)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
MINLINE float square_f(float a)
MINLINE float min_fff(float a, float b, float c)
void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4])
void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
void interp_weights_tri_v3(float w[3], const float v1[3], const float v2[3], const float v3[3], const float co[3])
void closest_on_tri_to_point_v3(float r[3], const float p[3], const float v1[3], const float v2[3], const float v3[3])
float closest_to_line_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2])
int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2])
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2])
void mul_m4_v3(const float M[4][4], float r[3])
bool equals_m4m4(const float mat1[4][4], const float mat2[4][4])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void mul_mat3_m4_v3(const float mat[4][4], float r[3])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_fl(float r[3], float f)
MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], float f)
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE bool equals_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3])
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
void minmax_v2v2_v2(float min[2], float max[2], const float vec[2])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE bool equals_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
void interp_v4_v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float w[3])
MINLINE void negate_v3(float r[3])
MINLINE void mul_v3_v3v3(float r[3], const float v1[3], const float v2[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE float line_point_side_v2(const float l1[2], const float l2[2], const float pt[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
bool BLI_path_abs(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1
#define STRNCPY(dst, src)
#define SNPRINTF(dst, format,...)
#define STRNCPY_UTF8(dst, src)
size_t void BLI_uniquename_cb(UniquenameCheckCallback unique_check, void *arg, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(1
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
#define BLT_I18NCONTEXT_ID_BRUSH
#define CTX_DATA_(context, msgid)
typedef double(DMatrix)[4][4]
#define CLOG_WARN(clg_ref,...)
#define CLOG_STR_ERROR(clg_ref, str)
#define CLOG_INFO(clg_ref, level,...)
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
Object groups, one object can be in many groups at once.
#define MAX_CUSTOMDATA_LAYER_NAME
@ MOD_DPAINT_WAVE_OPEN_BORDERS
@ MOD_DPAINT_DISP_INCREMENTAL
@ MOD_DPAINT_DISSOLVE_LOG
@ MOD_DPAINT_DISP_DISPLACE
@ MOD_DPAINT_RAY_BRUSH_AVG
@ MOD_DPAINT_INITIAL_NONE
@ MOD_DPAINT_INITIAL_VERTEXCOLOR
@ MOD_DPAINT_INITIAL_COLOR
@ MOD_DPAINT_INITIAL_TEXTURE
@ MOD_DPAINT_IMGFORMAT_OPENEXR
@ MOD_DPAINT_IMGFORMAT_PNG
@ MOD_DPAINT_PRFALL_CONSTANT
@ MOD_DPAINT_PRFALL_SMOOTH
@ MOD_DPAINT_PROX_PROJECT
@ MOD_DPAINT_INVERSE_PROX
@ MOD_DPAINT_USES_VELOCITY
@ MOD_DPAINT_VELOCITY_ALPHA
@ MOD_DPAINT_VELOCITY_DEPTH
@ MOD_DPAINT_VELOCITY_COLOR
@ MOD_DPAINT_NEGATE_VOLUME
@ MOD_DPAINT_SURFACE_T_WEIGHT
@ MOD_DPAINT_SURFACE_T_PAINT
@ MOD_DPAINT_SURFACE_T_DISPLACE
@ MOD_DPAINT_SURFACE_T_WAVE
@ MOD_DPAINT_EFFECT_DO_DRIP
@ MOD_DPAINT_EFFECT_DO_SPREAD
@ MOD_DPAINT_EFFECT_DO_SHRINK
@ MOD_DPAINT_SURFACE_F_PTEX
@ MOD_DPAINT_SURFACE_F_VERTEX
@ MOD_DPAINT_SURFACE_F_IMAGESEQ
@ MOD_DPAINT_WAVEB_REFLECT
@ MOD_DPAINT_WAVEB_CHANGE
@ eModifierFlag_SharedCaches
@ MOD_DYNAMICPAINT_TYPE_BRUSH
@ MOD_DYNAMICPAINT_TYPE_CANVAS
@ eModifierType_DynamicPaint
Object is a sort of wrapper for general info.
@ PART_FLUID_SPRAYFOAMBUBBLE
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE uint8_t atomic_fetch_and_and_uint8(uint8_t *p, uint8_t b)
ATOMIC_INLINE uint8_t atomic_fetch_and_or_uint8(uint8_t *p, uint8_t b)
ATOMIC_INLINE uint32_t atomic_add_and_fetch_uint32(uint32_t *p, uint32_t x)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
constexpr Span slice(int64_t start, int64_t size) const
constexpr const T * data() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
local_group_size(16, 16) .push_constant(Type b
pow(value.r - subtrahend, 2.0)") .do_static_compilation(true)
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
const Depsgraph * depsgraph
static bool dynamicPaint_checkSurfaceData(const Scene *scene, DynamicPaintSurface *surface)
static bool dynamicPaint_paintMesh(Depsgraph *depsgraph, DynamicPaintSurface *surface, DynamicPaintBrushSettings *brush, Object *brushOb, Scene *scene, float timescale)
static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata, const int p_index, const TaskParallelTLS *__restrict)
void dynamicPaint_clearSurface(const Scene *scene, DynamicPaintSurface *surface)
static void dynamic_paint_set_init_color_tex_to_vcol_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
static void dynamic_paint_paint_single_point_cb_ex(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static void dynamic_paint_wave_step_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static void freeGrid(PaintSurfaceData *data)
static void dynamicPaint_mixPaintColors(const DynamicPaintSurface *surface, const int index, const int paintFlags, const float paintColor[3], const float paintAlpha, const float paintWetness, const float timescale)
static bool surface_usesAdjDistance(DynamicPaintSurface *surface)
DynamicPaintSurface * dynamicPaint_createNewSurface(DynamicPaintCanvasSettings *canvas, Scene *scene)
static Mesh * dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *ob, Mesh *mesh)
static void dynamicPaint_doSmudge(DynamicPaintSurface *surface, DynamicPaintBrushSettings *brush, float timescale)
static float dist_squared_to_corner_tris_uv_edges(const blender::Span< int3 > corner_tris, const float(*mloopuv)[2], int tri_index, const float point[2])
static void free_bakeData(PaintSurfaceData *data)
static void grid_cell_points_reduce(const void *__restrict userdata, void *__restrict chunk_join, void *__restrict chunk)
static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force, PaintPoint *prevPoint, float timescale, float steps)
static void scene_setSubframe(Scene *scene, float subframe)
static const float gaussianTotal
static void dynamic_paint_border_cb(void *__restrict userdata, const int b_index, const TaskParallelTLS *__restrict)
static void dynamicPaint_mixWaveHeight(PaintWavePoint *wPoint, const DynamicPaintBrushSettings *brush, float isect_height)
static bool boundsIntersect(Bounds3D *b1, Bounds3D *b2)
static bool dynamicPaint_surfaceHasMoved(DynamicPaintSurface *surface, Object *ob)
static void dynamic_paint_effect_drip_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
void dynamicPaint_freeSurface(const DynamicPaintModifierData *pmd, DynamicPaintSurface *surface)
static void grid_bound_insert_cb_ex(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict tls)
static const float gaussianFactors[5]
static void dynamic_paint_output_surface_image_wave_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static void dynamic_paint_output_surface_image_displace_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
bool dynamicPaint_createType(DynamicPaintModifierData *pmd, int type, Scene *scene)
static bool boundIntersectPoint(Bounds3D *b, const float point[3], const float radius)
static int dynamicPaint_prepareEffectStep(Depsgraph *depsgraph, DynamicPaintSurface *surface, Scene *scene, Object *ob, float **force, float timescale)
static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceData *data, DynamicPaintFindIslandBorderData *bdata, int tri_index, const float pixel[2], int in_edge, int depth)
static void dynamic_paint_brush_velocity_compute_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
static void surface_freeUnusedData(DynamicPaintSurface *surface)
static void surface_setUniqueOutputName(DynamicPaintSurface *surface, char *basename, int output)
void dynamicPaintSurface_setUniqueName(DynamicPaintSurface *surface, const char *basename)
void dynamicPaint_cacheUpdateFrames(DynamicPaintSurface *surface)
static void dynamic_paint_paint_mesh_cell_point_cb_ex(void *__restrict userdata, const int id, const TaskParallelTLS *__restrict)
static int dynamic_paint_find_neighbor_pixel(const DynamicPaintCreateUVSurfaceData *data, const MeshElemMap *vert_to_tri_map, const int w, const int h, const int px, const int py, const int n_index)
static bool dynamicPaint_symmetrizeAdjData(PaintAdjData *ed, int active_points)
static void dynamic_paint_paint_particle_cell_point_cb_ex(void *__restrict userdata, const int id, const TaskParallelTLS *__restrict)
static int neighStraightX[8]
static void dynamicPaint_allocateSurfaceType(DynamicPaintSurface *surface)
#define EFF_MOVEMENT_PER_FRAME
static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescale)
static Mesh * dynamicPaint_canvas_mesh_get(DynamicPaintCanvasSettings *canvas)
static void dynamicPaint_doBorderStep(DynamicPaintSurface *surface)
static void dynamic_paint_output_surface_image_paint_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, const char *filepath, short output_layer)
static void dynamic_paint_effect_spread_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static void mesh_tris_nearest_point_dp(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
static void dynamicPaint_prepareAdjacencyData(DynamicPaintSurface *surface, const bool force_init)
static void dynamic_paint_output_surface_image_wetmap_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static bool setError(DynamicPaintCanvasSettings *canvas, const char *string)
static DynamicPaintRuntime * dynamicPaint_Modifier_runtime_ensure(DynamicPaintModifierData *pmd)
static bool dynamic_paint_surface_needs_dry_dissolve(DynamicPaintSurface *surface)
static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph, Scene *scene, Object *ob, DynamicPaintBrushSettings *brush, Vec3f **brushVel, float timescale)
static void dynamic_paint_surface_pre_step_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static void dynamic_paint_prepare_effect_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static void surface_determineForceTargetPoints(const PaintSurfaceData *sData, const int index, const float force[3], float closest_d[2], int closest_id[2])
bool dynamicPaint_resetSurface(const Scene *scene, DynamicPaintSurface *surface)
BLI_INLINE void value_dissolve(float *r_value, const float time, const float scale, const bool is_log)
int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, Depsgraph *depsgraph, Scene *scene, Object *cObject, int frame)
static float getSurfaceDimension(PaintSurfaceData *sData)
static void dynamic_paint_set_init_color_tex_to_imseq_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
static int surface_totalSamples(DynamicPaintSurface *surface)
static void dynamic_paint_generate_bake_data_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface, Depsgraph *depsgraph, Object *ob)
#define SUBFRAME_RECURSION
void dynamicPaintSurface_updateType(DynamicPaintSurface *surface)
static void dynamic_paint_apply_surface_wave_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
static void dynamicPaint_brushObjectCalculateVelocity(Depsgraph *depsgraph, Scene *scene, Object *ob, Vec3f *brushVel, float timescale)
void dynamicPaint_Modifier_copy(const DynamicPaintModifierData *pmd, DynamicPaintModifierData *tpmd, int flag)
static void dynamic_paint_effect_shrink_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Mesh *result)
DynamicPaintSurface * get_activeSurface(DynamicPaintCanvasSettings *canvas)
static bool boundsIntersectDist(Bounds3D *b1, Bounds3D *b2, const float dist)
static Mesh * dynamicPaint_brush_mesh_get(DynamicPaintBrushSettings *brush)
static void grid_cell_points_cb_ex(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict tls)
static void mesh_tris_spherecast_dp(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
static void canvas_copyMesh(DynamicPaintCanvasSettings *canvas, Mesh *mesh)
int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface, float *progress, bool *do_update)
static void grid_bound_insert_reduce(const void *__restrict, void *__restrict chunk_join, void *__restrict chunk)
static void boundInsert(Bounds3D *b, const float point[3])
static void dynamic_paint_prepare_adjacency_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const bool force_init)
static bool surface_duplicateOutputExists(void *arg, const char *name)
void dynamicPaint_freeSurfaceData(DynamicPaintSurface *surface)
static int surface_getBrushFlags(DynamicPaintSurface *surface, Depsgraph *depsgraph)
void dynamicPaint_freeBrush(DynamicPaintModifierData *pmd)
#define BRUSH_USES_VELOCITY
static bool dynamicPaint_paintParticles(DynamicPaintSurface *surface, ParticleSystem *psys, DynamicPaintBrushSettings *brush, float timescale)
static void dynamic_paint_create_uv_surface_direct_cb(void *__restrict userdata, const int ty, const TaskParallelTLS *__restrict)
static bool meshBrush_boundsIntersect(Bounds3D *b1, Bounds3D *b2, DynamicPaintBrushSettings *brush, float brush_radius)
static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Depsgraph *depsgraph, Scene *scene, Object *ob, Mesh *mesh)
void dynamicPaint_Modifier_free(DynamicPaintModifierData *pmd)
static void blendColors(const float t_color[3], const float t_alpha, const float s_color[3], const float s_alpha, float result[4])
static void surfaceGenerateGrid(DynamicPaintSurface *surface)
static int dynamicPaint_doStep(Depsgraph *depsgraph, Scene *scene, Object *ob, DynamicPaintSurface *surface, float timescale, float subframe)
static bool dynamicPaint_paintSinglePoint(Depsgraph *depsgraph, DynamicPaintSurface *surface, float *pointCoord, DynamicPaintBrushSettings *brush, Object *brushOb, Scene *scene, float timescale)
static int neighStraightY[8]
Mesh * dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, Depsgraph *depsgraph, Scene *scene, Object *ob, Mesh *mesh)
void dynamicPaint_freeCanvas(DynamicPaintModifierData *pmd)
bool dynamicPaint_outputLayerExists(DynamicPaintSurface *surface, Object *ob, int output)
static bool surface_duplicateNameExists(void *arg, const char *name)
static void dynamic_paint_set_init_color_vcol_to_imseq_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
static bool dynamicPaint_pointHasNeighbor(PaintAdjData *ed, int index, int neighbor)
static float mixColors(float a_color[3], float a_weight, const float b_color[3], float b_weight, float ratio)
void dynamicPaint_Modifier_free_runtime(DynamicPaintRuntime *runtime_data)
static bool surface_usesAdjData(DynamicPaintSurface *surface)
static int dynamicPaint_surfaceNumOfPoints(DynamicPaintSurface *surface)
static void dynamic_paint_create_uv_surface_neighbor_cb(void *__restrict userdata, const int ty, const TaskParallelTLS *__restrict)
static void dynamicPaint_setInitialColor(const Scene *, DynamicPaintSurface *surface)
static void dynamicPaint_updatePointData(const DynamicPaintSurface *surface, const int index, const DynamicPaintBrushSettings *brush, float paint[3], float influence, float depth, float vel_factor, const float timescale)
static void dynamicPaint_freeAdjData(PaintSurfaceData *data)
static void dynamic_paint_apply_surface_vpaint_blend_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
static void grid_cell_bounds_cb(void *__restrict userdata, const int x, const TaskParallelTLS *__restrict)
static void dynamic_paint_apply_surface_displace_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
smooth(Type::VEC3, "P") .flat(Type out_color storage_buf(0, Qualifier::READ, "Surfel", "surfels_buf[]") .push_constant(Type smooth(Type::VEC4, "interp_color")
struct ImBuf * IMB_allocImBuf(unsigned int, unsigned int, unsigned char, unsigned int)
bool IMB_saveiff(struct ImBuf *, const char *, int)
void IMB_freeImBuf(ImBuf *)
void *(* MEM_mallocN)(size_t len, const char *str)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_dupallocN)(const void *vmemh)
#define unit_float_to_uchar_clamp(val)
ccl_device_inline float2 floor(const float2 a)
ccl_device_inline float3 ceil(const float3 a)
static void error(const char *str)
Frequency::GEOMETRY nor[]
struct ColorBand * vel_ramp
struct DynamicPaintModifierData * pmd
struct ParticleSystem * psys
struct ColorBand * paint_ramp
const float(* positions_c)[3]
const float(* positions_p)[3]
struct DynamicPaintModifierData * pmd
blender::Span< int3 > corner_tris
blender::Span< int > corner_verts
PaintUVPoint * tempPoints
const float(* mloopuv)[2]
const DynamicPaintSurface * surface
const DynamicPaintSurface * surface
const DynamicPaintSurface * surface
const MeshElemMap * vert_to_tri_map
blender::Span< blender::float3 > positions
const DynamicPaintSurface * surface
blender::Span< blender::float3 > vert_normals
const Vec3f * canvas_verts
blender::Span< int > corner_verts
blender::MutableSpan< blender::float3 > vert_positions
const DynamicPaintSurface * surface
blender::Span< blender::float3 > vert_normals
blender::OffsetIndices< int > faces
struct DynamicPaintCanvasSettings * canvas
struct DynamicPaintBrushSettings * brush
const DynamicPaintSurface * surface
blender::Span< blender::float3 > positions
blender::Span< int > corner_verts
const DynamicPaintBrushSettings * brush
const float * avg_brushNor
const ParticleSystem * psys
const DynamicPaintSurface * surface
const Vec3f * brushVelocity
blender::Span< int3 > corner_tris
struct Mesh * canvas_mesh
const float(* mloopuv)[2]
const DynamicPaintSurface * surface
const MLoopCol * mloopcol
blender::Span< int > corner_verts
blender::Span< int3 > corner_tris
struct DynamicPaintCanvasSettings * canvas
struct Tex * init_texture
struct PaintSurfaceData * data
struct Collection * brush_group
float color_dry_threshold
struct DynamicPaintSurface * next
char image_output_path[1024]
struct EffectorWeights * effector_weights
struct PointCache * pointcache
ImBufFloatBuffer float_buffer
ImbFormatOptions foptions
struct PointCache * cache
DynamicPaintVolumeGrid * grid
float(* prev_positions)[3]
PaintBakeNormal * bNormal
struct PaintBakeData * bData
struct PaintAdjData * adj_data
int multitex_ext_safe(Tex *tex, const float texvec[3], TexResult *texres, ImagePool *pool, bool scene_color_manage, const bool skip_load_image)