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 OBJECT_MODIFIER_UPDATE_SUBFRAME_RECURSION_DEFAULT
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
142 *r_value = (is_log) ? (*r_value) *
powf(
MIN_WETNESS, 1.0f / (1.2f * time / scale)) :
143 (*r_value) - 1.0f / time * scale;
250#define ADJ_ON_MESH_EDGE (1 << 0)
251#define ADJ_BORDER_PIXEL (1 << 1)
274 if (runtime_data ==
nullptr) {
286 MEM_delete(runtime_data);
292 pmd->
modifier.
runtime = MEM_new<DynamicPaintRuntime>(
"dynamic paint runtime");
325 return (canvas_mesh) ? canvas_mesh->
verts_num : 0;
370 for (; surface; surface = surface->
next) {
371 if (surface != t_surface && surface->
type == t_surface->
type &&
407 for (; surface; surface = surface->
next) {
426 sizeof(surface->
name));
431 const char *name_prefix =
"";
432 const char *name_suffix_1 =
"";
433 const char *name_suffix_2 =
"";
448 name_suffix_1 =
"paintmap";
449 name_suffix_2 =
"wetmap";
452 name_suffix_1 = name_suffix_2 =
"displace";
455 name_suffix_1 = name_suffix_2 =
"weight";
458 name_suffix_1 = name_suffix_2 =
"wave";
466 if (!output_name_equal) {
487 const float s_color[3],
492 float i_alpha = 1.0f - s_alpha;
493 float f_alpha = t_alpha * i_alpha + s_alpha;
497 for (
int i = 0;
i < 3;
i++) {
498 result[
i] = (t_color[
i] * t_alpha * i_alpha + s_color[
i] * s_alpha) / f_alpha;
510 float a_color[3],
float a_weight,
const float b_color[3],
float b_weight,
float ratio)
512 float weight_ratio, factor;
517 return b_weight * ratio;
519 weight_ratio = b_weight / (a_weight + b_weight);
522 return a_weight * (1.0f - ratio);
527 factor = weight_ratio * (ratio * 2.0f);
530 ratio = (ratio * 2.0f - 1.0f);
531 factor = weight_ratio * (1.0f - ratio) + ratio;
535 return (1.0f - factor) * a_weight + factor * b_weight;
553 for (
int i = 0;
i < numobjects;
i++) {
581 for (
int i = 2;
i--;) {
595 for (
int i = 2;
i--;) {
596 if (!(b1->
min[
i] <= (b2->
max[
i] + dist) && b1->
max[
i] >= (b2->
min[
i] - dist))) {
609 for (
int i = 2;
i--;) {
610 if (!(
b->min[
i] <= (point[
i] + radius) &&
b->max[
i] >= (point[
i] - radius))) {
655 bData->
grid =
nullptr;
670 void *__restrict chunk_join,
671 void *__restrict chunk)
687 int *s_num =
static_cast<int *
>(tls->userdata_chunk);
691 for (
int j = 3; j--;) {
693 bData->
dim[j] * grid->
dim[j]));
697 temp_t_index[
i] = co[0] + co[1] * grid->
dim[0] + co[2] * grid->
dim[0] * grid->
dim[1];
698 s_num[temp_t_index[
i]]++;
702 void *__restrict chunk_join,
703 void *__restrict chunk)
707 const int grid_cells = grid->
dim[0] * grid->
dim[1] * grid->
dim[2];
709 int *join_s_num =
static_cast<int *
>(chunk_join);
710 int *s_num =
static_cast<int *
>(chunk);
713 for (
int i = 0;
i < grid_cells;
i++) {
714 join_s_num[
i] += s_num[
i];
724 float *dim = bData->
dim;
725 int *grid_dim = grid->
dim;
727 for (
int y = 0;
y < grid_dim[1];
y++) {
728 for (
int z = 0;
z < grid_dim[2];
z++) {
729 const int b_index =
x +
y * grid_dim[0] +
z * grid_dim[0] * grid_dim[1];
731 for (
int j = 3; j--;) {
732 const int s = (j == 0) ?
x : ((j == 1) ?
y :
z);
746 int grid_cells, axis = 3;
747 int *temp_t_index =
nullptr;
748 int *temp_s_num =
nullptr;
759 float dim_factor, volume, dim[3];
779 min_dim =
max_fff(td[0], td[1], td[2]) / 1000.0f;
782 for (
i = 0;
i < 3;
i++) {
783 if (td[
i] < min_dim) {
789 if (axis == 0 ||
max_fff(td[0], td[1], td[2]) < 0.0001f) {
791 bData->
grid =
nullptr;
796 volume = td[0] * td[1] * td[2];
800 pow(
double(volume) / (
double(sData->
total_points) / 10000.0), 1.0 /
double(axis)));
803 for (
i = 0;
i < 3;
i++) {
804 grid->
dim[
i] = int(
floor(td[
i] / dim_factor));
805 CLAMP(grid->
dim[
i], (dim[
i] >= min_dim) ? 3 : 1, 100);
807 grid_cells = grid->
dim[0] * grid->
dim[1] * grid->
dim[2];
817 "Temp Surface Grid Target Ids");
839 for (
i = 1;
i < grid_cells;
i++) {
845 int pos = grid->
s_pos[temp_t_index[
i]] + temp_s_num[temp_t_index[
i]];
848 temp_s_num[temp_t_index[
i]]++;
885 pmd->
brush =
nullptr;
891 if (
data->adj_data) {
892 if (
data->adj_data->n_index) {
895 if (
data->adj_data->n_num) {
898 if (
data->adj_data->n_target) {
901 if (
data->adj_data->flags) {
904 if (
data->adj_data->border) {
908 data->adj_data =
nullptr;
945 data->bData =
nullptr;
952 if (!surface->
data) {
971 if (
data->format_data) {
975 if (format_data->
uv_p) {
985 if (
data->type_data) {
993 surface->
data =
nullptr;
1019 next_surface = surface->
next;
1021 surface = next_surface;
1031 if (pmd ==
nullptr) {
1049 surface->
canvas = canvas;
1150 brush->
psys =
nullptr;
1158 brush->
alpha = 1.0f;
1183 ramp[0].
r = ramp[0].
g = ramp[0].
b = ramp[0].
a = 1.0f;
1185 ramp[1].
r = ramp[1].
g = ramp[1].
b = ramp[1].
pos = 1.0f;
1199 ramp[0].
r = ramp[0].
g = ramp[0].
b = ramp[0].
a = ramp[0].
pos = 0.0f;
1200 ramp[1].
r = ramp[1].
g = ramp[1].
b = ramp[1].
a = ramp[1].
pos = 1.0f;
1239 surface = surface->
next)
1305 t_brush->
pmd = tpmd;
1307 t_brush->flags = brush->
flags;
1310 t_brush->r = brush->
r;
1311 t_brush->g = brush->
g;
1312 t_brush->b = brush->
b;
1313 t_brush->alpha = brush->
alpha;
1314 t_brush->wetness = brush->
wetness;
1323 t_brush->psys = brush->
psys;
1334 t_brush->ray_dir = brush->
ray_dir;
1348 switch (surface->
type) {
1351 "DynamicPaintSurface Data");
1355 "DynamicPaintSurface DepthData");
1359 "DynamicPaintSurface WeightData");
1363 "DynamicPaintSurface WaveData");
1391 int neigh_points = 0;
1405 if (!neigh_points) {
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)) {
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 )
1596 float final_color[4];
1599 for (
int j = 3; j--;) {
1646 const float(*mloopuv)[2] =
static_cast<const float(*)[2]
>(
1656 ImagePool *pool = BKE_image_pool_new();
1658 DynamicPaintSetInitColorData data{};
1659 data.surface = surface;
1660 data.corner_verts = corner_verts;
1661 data.corner_tris = corner_tris;
1662 data.mloopuv = mloopuv;
1667 settings.use_threading = (corner_tris.
size() > 1000);
1674 data.surface = surface;
1675 data.corner_tris = corner_tris;
1676 data.mloopuv = mloopuv;
1710 data.surface = surface;
1711 data.corner_tris = corner_tris;
1736 data_size =
sizeof(float);
1756 if (surface->
data) {
1764 if (numOfPoints < 1) {
1770 if (!surface->
data) {
1840 data.surface = surface;
1841 data.vert_positions =
result->vert_positions_for_write();
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;
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)
1948 "Temp paint color");
1951 data.surface = surface;
1952 data.fcolor = fcolor;
1976 corner_verts.
size(),
1988 mloopcol_wet =
static_cast<MLoopCol *
>(
1992 corner_verts.
size(),
1997 data.corner_verts = corner_verts;
1999 data.mloopcol = mloopcol;
2000 data.mloopcol_wet = mloopcol_wet;
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];
2045 data.surface = surface;
2046 data.vert_positions =
result->vert_positions_for_write();
2054 result->tag_positions_changed();
2060 result->tag_positions_changed();
2117 for (; surface; surface = surface->
next) {
2118 int current_frame = scene->
r.
cfra;
2119 bool no_surface_data;
2132 no_surface_data = surface->
data ==
nullptr;
2140 if (no_surface_data || current_frame != surface->
current_frame ||
2167 else if (can_simulate) {
2203#define JITTER_SAMPLES \
2205 0.0f, 0.0f, -0.2f, -0.4f, 0.2f, 0.4f, 0.4f, -0.2f, -0.4f, 0.3f, \
2234 const float(*mloopuv)[2] =
data->mloopuv;
2244 for (
int tx = 0; tx <
w; tx++) {
2245 const int index = tx +
w * ty;
2255 point[0][0] = (float(tx) + 0.5f) /
w;
2256 point[0][1] = (float(ty) + 0.5f) / h;
2262 point[1][0] = float(tx) /
w;
2263 point[1][1] = float(ty) / h;
2265 point[2][0] = (float(tx) + 1) /
w;
2266 point[2][1] = float(ty) / h;
2268 point[3][0] = float(tx) /
w;
2269 point[3][1] = (float(ty) + 1) / h;
2271 point[4][0] = (float(tx) + 1) /
w;
2272 point[4][1] = (float(ty) + 1) / h;
2287 const float *uv1 = mloopuv[corner_tris[
i][0]];
2288 const float *uv2 = mloopuv[corner_tris[
i][1]];
2289 const float *uv3 = mloopuv[corner_tris[
i][2]];
2296 for (
int j = 0; j < aa_samples; j++) {
2297 uv[0] = point[0][0] + jitter5sample[j * 2] /
w;
2298 uv[1] = point[0][1] + jitter5sample[j * 2 + 1] / h;
2307 tPoint->
v1 = corner_verts[corner_tris[
i][0]];
2308 tPoint->
v2 = corner_verts[corner_tris[
i][1]];
2309 tPoint->
v3 = corner_verts[corner_tris[
i][2]];
2331 const float(*mloopuv)[2] =
data->mloopuv;
2334 uint32_t *active_points =
data->active_points;
2341 for (
int tx = 0; tx <
w; tx++) {
2342 const int index = tx +
w * ty;
2350 const int u_min = (tx > 0) ? -1 : 0;
2351 const int u_max = (tx < (
w - 1)) ? 1 : 0;
2352 const int v_min = (ty > 0) ? -1 : 0;
2353 const int v_max = (ty < (h - 1)) ? 1 : 0;
2355 point[0] = (float(tx) + 0.5f) /
w;
2356 point[1] = (float(ty) + 0.5f) / h;
2359 for (
int ni = 0; ni < 8; ni++) {
2363 if (u >= u_min && u <= u_max && v >= v_min &&
v <= v_max) {
2365 if (u != 0 ||
v != 0) {
2366 const int ind = (tx + u) +
w * (ty +
v);
2369 if (tempPoints[ind].neighbor_pixel == -1 && tempPoints[ind].tri_index != -1) {
2372 const float *uv1 = mloopuv[corner_tris[
i][0]];
2373 const float *uv2 = mloopuv[corner_tris[
i][1]];
2374 const float *uv3 = mloopuv[corner_tris[
i][2]];
2390 for (
int j = 0; j < aa_samples; j++) {
2391 uv[0] = point[0] + jitter5sample[j * 2] /
w;
2392 uv[1] = point[1] + jitter5sample[j * 2 + 1] / h;
2397 tPoint->
v1 = corner_verts[corner_tris[
i][0]];
2398 tPoint->
v2 = corner_verts[corner_tris[
i][1]];
2399 tPoint->
v3 = corner_verts[corner_tris[
i][2]];
2415#undef JITTER_SAMPLES
2418 const float (*mloopuv)[2],
2420 const float point[2])
2426 for (
int i = 0;
i < 3;
i++) {
2429 mloopuv[corner_tris[tri_index][(
i + 0)]],
2430 mloopuv[corner_tris[tri_index][(
i + 1) % 3]]);
2432 min_distance = std::min(dist_squared, min_distance);
2435 return min_distance;
2449 const float pixel[2],
2473 const int x = px +
neighX[n_index];
2474 const int y = py +
neighY[n_index];
2521 pixel[0] = (float(px +
neighX[n_index]) + 0.5f) /
float(
w);
2522 pixel[1] = (float(py +
neighY[n_index]) + 0.5f) /
float(h);
2534 const float pixel[2],
2540 const float(*mloopuv)[2] =
data->mloopuv;
2542 const int3 loop_idx = corner_tris[tri_index];
2545 for (
int edge_idx = 0; edge_idx < 3; edge_idx++) {
2547 if (edge_idx == in_edge) {
2551 float uv0[2], uv1[2], uv2[2];
2553 copy_v2_v2(uv0, mloopuv[loop_idx[(edge_idx + 0)]]);
2554 copy_v2_v2(uv1, mloopuv[loop_idx[(edge_idx + 1) % 3]]);
2555 copy_v2_v2(uv2, mloopuv[loop_idx[(edge_idx + 2) % 3]]);
2562 if (side2 == 0.0f) {
2567 const bool correct_side = (in_edge == -1) || (sidep < 0 && side2 > 0) ||
2568 (sidep > 0 && side2 < 0);
2571 if (!correct_side && sidep != 0.0f) {
2576 const int vert0 = corner_verts[loop_idx[(edge_idx + 0)]];
2577 const int vert1 = corner_verts[loop_idx[(edge_idx + 1) % 3]];
2583 bool found_other =
false;
2584 int target_tri = -1;
2585 int target_edge = -1;
2587 float ouv0[2], ouv1[2];
2589 for (
int i = 0;
i < map->count && !found_other;
i++) {
2590 const int tri_other_index = map->indices[
i];
2592 if (tri_other_index == tri_index) {
2596 const int3 other_tri = corner_tris[tri_other_index];
2599 for (
int j = 0; j < 3; j++) {
2600 const int overt0 = corner_verts[other_tri[(j + 0)]];
2601 const int overt1 = corner_verts[other_tri[(j + 1) % 3]];
2604 if (overt0 == vert0 && overt1 == vert1) {
2606 copy_v2_v2(ouv0, mloopuv[other_tri[(j + 0)]]);
2607 copy_v2_v2(ouv1, mloopuv[other_tri[(j + 1) % 3]]);
2609 else if (overt0 == vert1 && overt1 == vert0) {
2611 copy_v2_v2(ouv1, mloopuv[other_tri[(j + 0)]]);
2612 copy_v2_v2(ouv0, mloopuv[other_tri[(j + 1) % 3]]);
2616 target_tri = tri_other_index;
2633 if (depth > 0 && correct_side) {
2652 float closest_point[2], dir_vec[2], tgt_pixel[2];
2655 CLAMP(lambda, 0.0f, 1.0f);
2660 int w = bdata->
w, h = bdata->
h, px = bdata->
px, py = bdata->
py;
2662 const int final_pixel[2] = {int(
floorf(tgt_pixel[0] *
w)), int(
floorf(tgt_pixel[1] * h))};
2665 if (final_pixel[0] < 0 || final_pixel[0] >=
w || final_pixel[1] < 0 || final_pixel[1] >= h) {
2674 int final_index = final_pixel[0] +
w * final_pixel[1];
2677 if (final_index == (px +
w * py)) {
2682 if (tempPoints[final_index].neighbor_pixel != -1) {
2686 if (final_index == (px +
w * py)) {
2691 const int final_tri_index = tempPoints[final_index].
tri_index;
2693 if (!
ELEM(final_tri_index, target_tri, -1)) {
2696 const float final_pt[2] = {((final_index %
w) + 0.5f) /
w, ((final_index /
w) + 0.5f) / h};
2697 const float threshold =
square_f(0.7f) / (
w * h);
2713 const int idx = ed->
n_index[index];
2715 for (
int i = 0;
i < ed->
n_num[index];
i++) {
2716 if (ed->
n_target[idx +
i] == neighbor) {
2731 if (new_n_num && new_n_index) {
2733 int total_targets = 0;
2735 for (
int index = 0; index < active_points; index++) {
2736 total_targets += ed->
n_num[index];
2737 new_n_num[index] = ed->
n_num[index];
2740 for (
int index = 0; index < active_points; index++) {
2746 const int target = ed->
n_target[idx +
i];
2751 new_n_num[target]++;
2764 for (
int index = 0; index < active_points; index++) {
2765 new_n_index[index] = n_pos;
2766 memcpy(&new_n_target[n_pos],
2768 sizeof(
int) * ed->
n_num[index]);
2771 n_pos += new_n_num[index];
2772 new_n_num[index] = ed->
n_num[index];
2778 for (
int index = 0; index < active_points; index++) {
2784 const int target = ed->
n_target[idx +
i];
2787 const int num = new_n_num[target]++;
2788 new_n_target[new_n_index[target] +
num] = index;
2801 ed->
n_num = new_n_num;
2826 uint32_t active_points = 0;
2834 Vec3f *tempWeights =
nullptr;
2835 const float(*mloopuv)[2] =
nullptr;
2844 return setError(canvas,
N_(
"Canvas mesh not updated"));
2847 return setError(canvas,
N_(
"Cannot bake non-'image sequence' formats"));
2857 mloopuv =
static_cast<const float(*)[2]
>(
2863 return setError(canvas,
N_(
"No UV data on canvas"));
2866 return setError(canvas,
N_(
"Invalid resolution"));
2876 &
LOG, 1,
"Preparing UV surface of %ix%i pixels and %i tris.",
w, h,
int(corner_tris.
size()));
2879 if (surface->
data) {
2883 if (!surface->
data) {
2884 return setError(canvas,
N_(
"Not enough free memory"));
2922 for (
int j = 1; j < 3; j++) {
2932 data.surface = surface;
2933 data.tempPoints = tempPoints;
2934 data.tempWeights = tempWeights;
2935 data.corner_tris = corner_tris;
2936 data.mloopuv = mloopuv;
2937 data.corner_verts = corner_verts;
2938 data.faceBB = faceBB;
2956 data.active_points = &active_points;
2973 for (
int i = 0;
i <
w * h;
i++) {
2974 if (tempPoints[
i].tri_index != -1) {
2975 final_index[
i] = cursor;
2988 int *vert_to_tri_map_mem;
2991 &vert_to_tri_map_mem,
2995 corner_verts.
data(),
2998 int total_border = 0;
3000 for (
int ty = 0; ty < h; ty++) {
3001 for (
int tx = 0; tx <
w; tx++) {
3002 const int index = tx +
w * ty;
3004 if (tempPoints[index].tri_index != -1) {
3005 ed->
n_index[final_index[index]] = n_pos;
3006 ed->
n_num[final_index[index]] = 0;
3008 if (tempPoints[index].neighbor_pixel != -1) {
3013 for (
int i = 0;
i < 8;
i++) {
3017 &
data, vert_to_tri_map,
w, h, tx, ty,
i);
3019 if (n_target >= 0 && n_target != index) {
3021 ed, final_index[index], final_index[n_target]))
3023 ed->
n_target[n_pos] = final_index[n_target];
3024 ed->
n_num[final_index[index]]++;
3050 for (
int i = 0,
next = 0;
i < active_points;
i++) {
3061 FILE *dump_file = fopen(
"dynpaint-adj-data.txt",
"w");
3063 for (
int ty = 0; ty < h; ty++) {
3064 for (
int tx = 0; tx <
w; tx++) {
3065 const int index = tx +
w * ty;
3066 if (tempPoints[index].tri_index != -1) {
3067 tmp[final_index[index]] = index;
3071 for (
int ty = 0; ty < h; ty++) {
3072 for (
int tx = 0; tx <
w; tx++) {
3073 const int index = tx +
w * ty;
3074 const int fidx = final_index[index];
3076 if (tempPoints[index].tri_index != -1) {
3079 "%d\t%d,%d\t%u\t%d,%d\t%d\t",
3083 tempPoints[index].tri_index,
3084 nidx < 0 ? -1 : (nidx %
w),
3085 nidx < 0 ? -1 : h - 1 - (nidx /
w),
3087 for (
int i = 0;
i < ed->
n_num[fidx];
i++) {
3089 fprintf(dump_file,
"%s%d,%d",
i ?
" " :
"", tgt %
w, h - 1 - tgt /
w);
3091 fprintf(dump_file,
"\n");
3136 for (
int index = 0, cursor = 0; index < (
w * h); index++) {
3137 if (tempPoints[index].tri_index != -1) {
3140 &tempWeights[index * aa_samples],
3141 sizeof(*tempWeights) * aa_samples);
3148 setError(canvas,
N_(
"Not enough free memory"));
3172 for (index = 0; index < sData->
total_points; index++) {
3176 pPoint->alpha = 1.0f;
3180 pPoint->
color[2] = 1.0f;
3185 pPoint->
color[0] = 1.0f;
3197 return (
error == 0);
3236 void *__restrict userdata,
const int index,
const TaskParallelTLS *__restrict )
3253 depth = (0.5f - depth / 2.0f);
3256 CLAMP(depth, 0.0f, 1.0f);
3271 float depth = wPoint->
height;
3281 depth = (0.5f + depth / 2.0f);
3282 CLAMP(depth, 0.0f, 1.0f);
3307 const char *filepath,
3310 ImBuf *ibuf =
nullptr;
3322#ifndef WITH_IMAGE_OPENEXR
3327 STRNCPY(output_file, filepath);
3336 if (ibuf ==
nullptr) {
3337 setError(surface->
canvas,
N_(
"Image save failed: not enough free memory"));
3342 data.surface = surface;
3345 switch (surface->
type) {
3347 switch (output_layer) {
3376 switch (output_layer) {
3396 switch (output_layer) {
3421#ifdef WITH_IMAGE_OPENEXR
3455 const int3 *corner_tris =
data->corner_tris.data();
3456 const int *corner_verts =
data->corner_verts.data();
3458 const float *t0, *t1, *t2;
3461 t0 = positions[corner_verts[corner_tris[index][0]]];
3462 t1 = positions[corner_verts[corner_tris[index][1]]];
3463 t2 = positions[corner_verts[corner_tris[index][2]]];
3467 if (dist >= 0 && dist < hit->dist) {
3487 const int3 *corner_tris =
data->corner_tris.data();
3488 const int *corner_verts =
data->corner_verts.data();
3489 float nearest_tmp[3], dist_sq;
3491 const float *t0, *t1, *t2;
3492 t0 = positions[corner_verts[corner_tris[index][0]]];
3493 t1 = positions[corner_verts[corner_tris[index][1]]];
3494 t2 = positions[corner_verts[corner_tris[index][2]]];
3499 if (dist_sq < nearest->dist_sq) {
3500 nearest->
index = index;
3503 nearest->
no[0] = 0.0f;
3521 const int paintFlags,
3522 const float paintColor[3],
3523 const float paintAlpha,
3524 const float paintWetness,
3525 const float timescale)
3545 float wetness = paintWetness;
3546 CLAMP(wetness, 0.0f, 1.0f);
3557 float a_ratio, a_highest;
3559 float invFact = 1.0f - paintAlpha;
3567 if (a_highest > invFact) {
3568 a_ratio = invFact / a_highest;
3570 pPoint->
e_color[3] *= a_ratio;
3571 pPoint->
color[3] *= a_ratio;
3575 pPoint->
e_color[3] -= paintAlpha * timescale;
3577 pPoint->
color[3] -= paintAlpha * timescale;
3581 wetness = (1.0f - paintWetness) * pPoint->
e_color[3];
3591 const float isect_change = isect_height - wPoint->
brush_isect;
3599 isect_height *= wave_factor;
3602 if (wave_factor > 0.0f && wPoint->
height > isect_height) {
3605 else if (wave_factor < 0.0f && wPoint->height < isect_height) {
3612 wPoint->
height = isect_height;
3623 if (isect_change < 0.0f) {
3624 wPoint->
height += isect_change * wave_factor;
3644 const float timescale)
3653 strength = influence * brush->
alpha;
3654 CLAMP(strength, 0.0f, 1.0f);
3662 CLAMP(vel_factor, 0.0f, 1.0f);
3669 strength *= coba_res[3];
3672 depth *= coba_res[3];
3679 float paintWetness = brush->
wetness * strength;
3680 float paintAlpha = strength;
3683 surface, index, brush->
flags, paint, paintAlpha, paintWetness, timescale);
3687 float *value = (
float *)sData->
type_data;
3690 depth = value[index] + depth;
3698 value[index] *= (1.0f - strength);
3707 float *value = (
float *)sData->
type_data;
3710 value[index] *= (1.0f - strength);
3769 const float(*positions_p)[3] =
data->positions_p;
3770 const float(*positions_c)[3] =
data->positions_c;
3772 const float(*obmat)[4] =
data->obmat;
3773 float(*prev_obmat)[4] =
data->prev_obmat;
3775 const float timescale =
data->timescale;
3796 float prev_obmat[4][4];
3797 Mesh *mesh_p, *mesh_c;
3798 int numOfVerts_p, numOfVerts_c;
3801 int cur_fra = scene->
r.
cfra;
3802 float prev_sfra = cur_sfra - timescale;
3803 int prev_fra = cur_fra;
3805 if (prev_sfra < 0.0f) {
3807 prev_fra = cur_fra - 1;
3811 scene->
r.
cfra = prev_fra;
3824 if (!runtime_data) {
3827 std::lock_guard
lock(runtime_data->brush_mutex);
3832 float(*positions_p)[3] =
reinterpret_cast<float(*)[3]
>(
3833 mesh_p->vert_positions_for_write().
data());
3834 copy_m4_m4(prev_obmat, ob->object_to_world().ptr());
3837 scene->
r.
cfra = cur_fra;
3848 if (!runtime_data) {
3851 std::lock_guard
lock(runtime_data->brush_mutex);
3852 mesh_c = runtime_data->brush_mesh;
3855 float(*positions_c)[3] =
reinterpret_cast<float(*)[3]
>(
3856 mesh_c->vert_positions_for_write().
data());
3865 if (numOfVerts_p != numOfVerts_c) {
3866 positions_p = positions_c;
3871 data.brush_vel = *brushVel;
3872 data.positions_p = positions_p;
3873 data.positions_c = positions_c;
3874 data.obmat = ob->object_to_world().ptr();
3875 data.prev_obmat = prev_obmat;
3876 data.timescale = timescale;
3891 float prev_obmat[4][4];
3892 float cur_loc[3] = {0.0f}, prev_loc[3] = {0.0f};
3895 int cur_fra = scene->
r.
cfra;
3896 float prev_sfra = cur_sfra - timescale;
3897 int prev_fra = cur_fra;
3899 if (prev_sfra < 0.0f) {
3901 prev_fra = cur_fra - 1;
3905 scene->
r.
cfra = prev_fra;
3914 copy_m4_m4(prev_obmat, ob->object_to_world().ptr());
3917 scene->
r.
cfra = cur_fra;
3929 mul_m4_v3(ob->object_to_world().ptr(), cur_loc);
3975 const float timescale =
data->timescale;
3976 const int c_index =
data->c_index;
3981 const float brush_radius =
data->brush_radius;
3982 const float *avg_brushNor =
data->avg_brushNor;
3983 const Vec3f *brushVelocity =
data->brushVelocity;
3988 const int index = grid->
t_index[grid->
s_pos[c_index] + id];
3989 const int samples = bData->
s_num[index];
3991 float total_sample = float(samples);
3992 float brushStrength = 0.0f;
3994 float velocity_val = 0.0f;
3996 float paintColor[3] = {0.0f};
4005 for (ss = 0; ss < samples; ss++) {
4006 float ray_start[3], ray_dir[3];
4007 float sample_factor = 0.0f;
4008 float sampleStrength = 0.0f;
4011 short hit_found = 0;
4014 float volume_factor = 0.0f;
4016 float proximity_factor = 0.0f;
4017 float prox_colorband[4] = {0.0f};
4030 sample_factor = 1.0f;
4043 nearest.
dist_sq = brush_radius * brush_radius;
4049 if (hit.
index != -1) {
4053 const int vtri[3] = {
4054 corner_verts[corner_tris[hit.
index][0]],
4055 corner_verts[corner_tris[hit.
index][1]],
4056 corner_verts[corner_tris[hit.
index][2]],
4060 normal_tri_v3(hit.
no, positions[vtri[0]], positions[vtri[1]], positions[vtri[2]]);
4066 const float dist = hit.
dist;
4067 const int f_index = hit.
index;
4078 if (hit.
index != -1) {
4080 volume_factor = 1.0f;
4088 depth += dist * sample_factor;
4099 float proxDist = -1.0f;
4100 float hitCo[3] = {0.0f, 0.0f, 0.0f};
4104 if (inner_proximity && !hit_found) {
4112 if (nearest.
index != -1) {
4115 tri = nearest.
index;
4119 float proj_ray[3] = {0.0f};
4132 hit.
dist = brush_radius;
4137 if (hit.
index != -1) {
4138 proxDist = hit.
dist;
4148 if (proxDist >= 0.0f && proxDist <= brush_radius) {
4149 proximity_factor = proxDist / brush_radius;
4150 CLAMP(proximity_factor, 0.0f, 1.0f);
4151 if (!inner_proximity) {
4152 proximity_factor = 1.0f - proximity_factor;
4169 volume_factor = 1.0f - volume_factor;
4170 if (inner_proximity) {
4171 proximity_factor = 1.0f - proximity_factor;
4177 sampleStrength = volume_factor;
4184 proximity_factor = prox_colorband[3];
4191 sampleStrength = proximity_factor;
4194 sampleStrength *= sample_factor;
4203 float brushPointVelocity[3];
4206 const int v1 = corner_verts[corner_tris[hitTri][0]];
4207 const int v2 = corner_verts[corner_tris[hitTri][1]];
4208 const int v3 = corner_verts[corner_tris[hitTri][2]];
4218 brushVelocity[v1].
v,
4219 brushVelocity[
v2].
v,
4220 brushVelocity[v3].
v,
4245 float sampleColor[3];
4246 float alpha_factor = 1.0f;
4248 sampleColor[0] = brush->
r;
4249 sampleColor[1] = brush->
g;
4250 sampleColor[2] = brush->
b;
4255 sampleColor[0] = prox_colorband[0];
4256 sampleColor[1] = prox_colorband[1];
4257 sampleColor[2] = prox_colorband[2];
4262 paintColor[0] += sampleColor[0];
4263 paintColor[1] += sampleColor[1];
4264 paintColor[2] += sampleColor[2];
4265 sampleStrength *= alpha_factor;
4270 brushStrength += sampleStrength;
4274 if (brushStrength > 0.0f || depth > 0.0f) {
4277 brushStrength /= total_sample;
4279 CLAMP(brushStrength, 0.0f, 1.0f);
4283 paintColor[0] /= numOfHits;
4284 paintColor[1] /= numOfHits;
4285 paintColor[2] /= numOfHits;
4293 surface, index, brush, paintColor, brushStrength, depth, velocity_val, timescale);
4306 Mesh *mesh =
nullptr;
4307 Vec3f *brushVelocity =
nullptr;
4311 depsgraph, scene, brushOb, brush, &brushVelocity, timescale);
4315 if (!runtime_data) {
4318 std::lock_guard
lock(runtime_data->brush_mutex);
4319 const Mesh *brush_mesh = runtime_data->brush_mesh;
4320 if (brush_mesh ==
nullptr) {
4325 float avg_brushNor[3] = {0.0f};
4342 for (ii = 0; ii < numOfVerts; ii++) {
4343 mul_m4_v3(brushOb->object_to_world().ptr(), positions[ii]);
4357 mesh->tag_positions_changed();
4360 mul_v3_fl(avg_brushNor, 1.0f /
float(numOfVerts));
4363 avg_brushNor[2] = 1.0f;
4371 if (treeData.
tree !=
nullptr) {
4373 int total_cells = grid->
dim[0] * grid->
dim[1] * grid->
dim[2];
4376 for (c_index = 0; c_index < total_cells; c_index++) {
4378 if (!grid->
s_num[c_index] ||
4386 data.surface = surface;
4388 data.brushOb = brushOb;
4390 data.timescale = timescale;
4391 data.c_index = c_index;
4393 data.positions = positions;
4394 data.corner_verts = corner_verts;
4395 data.corner_tris = corner_tris;
4396 data.brush_radius = brush_radius;
4397 data.avg_brushNor = avg_brushNor;
4398 data.brushVelocity = brushVelocity;
4399 data.treeData = &treeData;
4405 grid->
s_num[c_index],
4416 if (brushVelocity) {
4427 void *__restrict userdata,
const int id,
const TaskParallelTLS *__restrict )
4440 const float timescale =
data->timescale;
4441 const int c_index =
data->c_index;
4443 KDTree_3d *
tree =
static_cast<KDTree_3d *
>(
data->treeData);
4445 const float solidradius =
data->solidradius;
4447 const float range = solidradius + smooth;
4448 const float particle_timestep = 0.04f * psys->
part->
timetweak;
4450 const int index = grid->
t_index[grid->
s_pos[c_index] + id];
4451 float disp_intersect = 0.0f;
4452 float radius = 0.0f;
4453 float strength = 0.0f;
4454 int part_index = -1;
4461 KDTreeNearest_3d nearest;
4462 float smooth_range, part_solidradius;
4467 if (nearest.dist > range) {
4474 part_solidradius = pa->
size;
4477 part_solidradius = solidradius;
4479 radius = part_solidradius + smooth;
4480 if (nearest.dist < radius) {
4482 smooth_range =
max_ff(0.0f, (nearest.dist - part_solidradius));
4485 smooth_range /= smooth;
4488 strength = 1.0f - smooth_range;
4489 disp_intersect = radius - nearest.dist;
4490 part_index = nearest.index;
4499 KDTreeNearest_3d *nearest;
4501 float smooth_range = smooth * (1.0f - strength), dist;
4503 const float max_range = smooth - strength * smooth + solidradius;
4507 const int particles = BLI_kdtree_3d_range_search(
4511 for (
int n = 0; n < particles; n++) {
4515 if (nearest[n].dist > (pa->
size + smooth)) {
4520 const float s_range = nearest[n].dist - pa->
size;
4522 if (smooth_range < s_range) {
4527 smooth_range = s_range;
4528 dist = nearest[n].dist;
4529 part_index = nearest[n].index;
4532 if ((s_range < 0.0f) &&
4544 const float rad = radius + smooth;
4545 if ((rad - dist) > disp_intersect) {
4546 disp_intersect = radius - dist;
4553 smooth_range /= smooth;
4556 const float str = 1.0f - smooth_range;
4558 strength = std::max(
str, strength);
4561 if (strength > 0.001f) {
4562 float paintColor[4] = {0.0f};
4564 float velocity_val = 0.0f;
4592 disp_intersect = (1.0f -
sqrtf(disp_intersect / radius)) * radius;
4597 surface, index, brush, paintColor, strength, depth, velocity_val, timescale);
4612 int particlesAdded = 0;
4613 int invalidParticles = 0;
4621 const float range = solidradius + smooth;
4646 if (
isnan(pa->state.co[0]) ||
isnan(pa->state.co[1]) ||
isnan(pa->state.co[2])) {
4656 BLI_kdtree_3d_insert(
tree, p, pa->state.co);
4663 if (invalidParticles) {
4668 if (particlesAdded < 1) {
4669 BLI_kdtree_3d_free(
tree);
4676 int total_cells = grid->
dim[0] * grid->
dim[1] * grid->
dim[2];
4679 BLI_kdtree_3d_balance(
tree);
4682 for (c_index = 0; c_index < total_cells; c_index++) {
4690 data.surface = surface;
4693 data.solidradius = solidradius;
4694 data.timescale = timescale;
4695 data.c_index = c_index;
4702 grid->
s_num[c_index],
4708 BLI_kdtree_3d_free(
tree);
4726 const float timescale =
data->timescale;
4728 const float brush_radius =
data->brush_radius;
4729 const Vec3f *brushVelocity =
data->brushVelocity;
4731 float *pointCoord =
data->pointCoord;
4734 float colorband[4] = {0.0f};
4743 strength = 1.0f -
distance / brush_radius;
4744 CLAMP(strength, 0.0f, 1.0f);
4750 if (strength >= 0.001f) {
4751 float paintColor[3] = {0.0f};
4753 float velocity_val = 0.0f;
4759 strength = colorband[3];
4772 velocity_val =
len_v3(velocity);
4787 paintColor[0] = colorband[0];
4788 paintColor[1] = colorband[1];
4789 paintColor[2] = colorband[2];
4792 paintColor[0] = brush->
r;
4793 paintColor[1] = brush->
g;
4794 paintColor[2] = brush->
b;
4799 const float disp_intersect = (1.0f -
sqrtf((brush_radius -
distance) / brush_radius)) *
4804 surface, index, brush, paintColor, strength, depth, velocity_val, timescale);
4828 std::lock_guard
lock(runtime_data->brush_mutex);
4829 const Mesh *brush_mesh = runtime_data->brush_mesh;
4835 data.surface = surface;
4837 data.brushOb = brushOb;
4839 data.timescale = timescale;
4840 data.positions = brush_mesh->vert_positions();
4841 data.brush_radius = brush_radius;
4842 data.brushVelocity = &brushVel;
4843 data.pointCoord = pointCoord;
4870 const int num_neighs = adj_data->
n_num[index];
4872 for (
int i = 0;
i < num_neighs;
i++) {
4873 const int n_index = adj_data->
n_index[index] +
i;
4874 const int t_index = adj_data->
n_target[n_index];
4878 realCoord[bData->
s_pos[t_index]].
v,
4879 realCoord[bData->
s_pos[index]].
v);
4917 for (index = 0; index < sData->
total_points; index++) {
4918 int numOfNeighs = adj_data->
n_num[index];
4920 for (
int i = 0;
i < numOfNeighs;
i++) {
4931 const float force[3],
4938 closest_id[0] = closest_id[1] = -1;
4939 closest_d[0] = closest_d[1] = -1.0f;
4942 for (
int i = 0;
i < numOfNeighs;
i++) {
4944 const float dir_dot =
dot_v3v3(bNeighs[n_index].dir, force);
4946 if (dir_dot > closest_d[0] && dir_dot > 0.0f) {
4947 closest_d[0] = dir_dot;
4948 closest_id[0] = n_index;
4952 if (closest_d[0] < 0.0f) {
4957 for (
int i = 0;
i < numOfNeighs;
i++) {
4960 if (n_index == closest_id[0]) {
4964 const float dir_dot =
dot_v3v3(bNeighs[n_index].dir, force);
4965 const float closest_dot =
dot_v3v3(bNeighs[n_index].dir, bNeighs[closest_id[0]].dir);
4969 if (dir_dot > closest_d[1] && closest_dot < closest_d[0] && dir_dot > 0.0f) {
4970 closest_d[1] = dir_dot;
4971 closest_id[1] = n_index;
4977 if (closest_id[1] != -1) {
4978 float force_proj[3];
4980 const float neigh_diff =
acosf(
4981 dot_v3v3(bNeighs[closest_id[0]].dir, bNeighs[closest_id[1]].dir));
4982 float force_intersect;
4987 cross_v3_v3v3(tangent, bNeighs[closest_id[0]].dir, bNeighs[closest_id[1]].dir);
4989 force_intersect =
dot_v3v3(force, tangent);
4990 madd_v3_v3v3fl(force_proj, force, tangent, (-1.0f) * force_intersect);
4994 temp =
dot_v3v3(bNeighs[closest_id[0]].dir, force_proj);
4995 CLAMP(temp, -1.0f, 1.0f);
4996 closest_d[1] =
acosf(temp) / neigh_diff;
4997 closest_d[0] = 1.0f - closest_d[1];
5000 temp =
fabsf(force_intersect);
5001 CLAMP(temp, 0.0f, 1.0f);
5006 closest_d[0] = 1.0f -
acosf(closest_d[0]) / float(
M_PI_2);
5017 float max_velocity = 0.0f;
5024 for (
int index = 0; index < sData->
total_points; index++) {
5034 for (
int index = 0; index < sData->
total_points; index++) {
5053 sData, index, &bData->
brush_velocity[index * 4], closest_d, closest_id);
5056 for (
int i = 0;
i < 2;
i++) {
5057 int n_index = closest_id[
i];
5058 if (n_index != -1 && closest_d[
i] > 0.0f) {
5059 float dir_dot = closest_d[
i], dir_factor;
5060 float speed_scale = eff_scale * smudge_str / bNeighs[n_index].
dist;
5065 if (dir_dot <= 0.0f) {
5069 dir_factor = dir_dot * speed_scale;
5074 ePoint->
color[3] = ePoint->
color[3] * (1.0f - dir_factor) +
5075 pPoint->
color[3] * dir_factor;
5084 pPoint->
e_color[3] * dir_factor;
5085 pPoint->
wetness *= (1.0f - dir_factor);
5130 float *force =
data->force;
5133 float forc[3] = {0};
5142 effectors,
nullptr, surface->
effector_weights, &epoint, forc,
nullptr,
nullptr);
5181 double average_force = 0.0f;
5182 float shrink_speed = 0.0f, spread_speed = 0.0f;
5183 float fastest_effect, avg_dist;
5198 data.surface = surface;
5200 data.force = *force;
5201 data.effectors = effectors;
5210 for (
int index = 0; index < sData->
total_points; index++) {
5211 average_force += double((*force)[index * 4 + 3]);
5229 fastest_effect =
max_fff(spread_speed, shrink_speed, average_force);
5258 const float eff_scale =
data->eff_scale;
5264 for (
int i = 0;
i < numOfNeighs;
i++) {
5265 const int n_idx = n_index[index] +
i;
5267 const PaintPoint *pPoint_prev = &prevPoint[n_target[n_idx]];
5268 const float speed_scale = (bNeighs[n_idx].
dist < eff_scale) ? 1.0f :
5269 eff_scale / bNeighs[n_idx].
dist;
5287 w_factor = 1.0f / numOfNeighs *
min_ff(pPoint_prev->
wetness, 1.0f) * speed_scale;
5288 CLAMP(w_factor, 0.0f, 1.0f);
5317 const float eff_scale =
data->eff_scale;
5323 for (
int i = 0;
i < numOfNeighs;
i++) {
5324 const int n_idx = n_index[index] +
i;
5325 const float speed_scale = (bNeighs[n_idx].
dist < eff_scale) ? 1.0f :
5326 eff_scale / bNeighs[n_idx].
dist;
5327 const PaintPoint *pPoint_prev = &prevPoint[n_target[n_idx]];
5328 float a_factor, ea_factor, w_factor;
5337 a_factor =
max_ff((1.0f - pPoint_prev->
color[3]) / numOfNeighs *
5338 (pPoint->
color[3] - pPoint_prev->
color[3]) * speed_scale,
5349 pPoint->
color[3] -= a_factor;
5351 pPoint->
e_color[3] -= ea_factor;
5374 const PaintPoint *pPoint_prev = &prevPoint[index];
5375 const float *force =
data->force;
5376 const float eff_scale =
data->eff_scale;
5380 uint8_t *point_locks =
data->point_locks;
5386 float w_factor = pPoint_prev->
wetness - 0.025f;
5387 if (w_factor <= 0) {
5390 CLAMP(w_factor, 0.0f, 1.0f);
5392 float ppoint_wetness_diff = 0.0f;
5398 for (
int i = 0;
i < 2;
i++) {
5399 const int n_idx = closest_id[
i];
5400 if (n_idx != -1 && closest_d[
i] > 0.0f) {
5401 const float dir_dot = closest_d[
i];
5404 if (dir_dot <= 0.0f) {
5408 float dir_factor, a_factor;
5409 const float speed_scale = eff_scale * force[index * 4 + 3] / bNeighs[n_idx].
dist;
5411 const uint n_trgt =
uint(n_target[n_idx]);
5416 const uint epointlock_idx = n_trgt / 8;
5417 const uint8_t epointlock_bitmask = 1 << (n_trgt & 7);
5425 const float e_wet = ePoint->
wetness;
5427 dir_factor =
min_ff(0.5f, dir_dot *
min_ff(speed_scale, 1.0f) * w_factor);
5430 ePoint->
wetness += dir_factor;
5434 a_factor = dir_factor / pPoint_prev->
wetness;
5435 CLAMP(a_factor, 0.0f, 1.0f);
5449 ppoint_wetness_diff += (ePoint->
wetness - e_wet);
5454 ~epointlock_bitmask);
5464 const uint ppointlock_idx = index / 8;
5465 const uint8_t ppointlock_bitmask = 1 << (index & 7);
5472 pPoint->
wetness -= ppoint_wetness_diff;
5515 data.surface = surface;
5516 data.prevPoint = prevPoint;
5517 data.eff_scale = eff_scale;
5537 data.surface = surface;
5538 data.prevPoint = prevPoint;
5539 data.eff_scale = eff_scale;
5555 const size_t point_locks_size = (sData->
total_points / 8) + 1;
5562 data.surface = surface;
5563 data.prevPoint = prevPoint;
5564 data.eff_scale = eff_scale;
5566 data.point_locks = point_locks;
5596 float mix_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5597 float mix_e_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5598 float mix_wetness = 0.0f;
5600 for (
int i = 0;
i < numOfNeighs;
i++) {
5601 const int n_idx = n_index[index] +
i;
5602 const int target = n_target[n_idx];
5609 mix_color[3] += pPoint2->
color[3];
5612 mix_e_color[3] += pPoint2->
e_color[3];
5614 mix_wetness += pPoint2->
wetness;
5617 const float divisor = 1.0f / numOfNeighs;
5620 pPoint->
color[3] = mix_color[3] * divisor;
5624 pPoint->
color[3] = 0.0f;
5627 if (mix_e_color[3]) {
5628 pPoint->
e_color[3] = mix_e_color[3] * divisor;
5635 pPoint->
wetness = mix_wetness / numOfNeighs;
5648 data.surface = surface;
5668 const float wave_speed =
data->wave_speed;
5669 const float wave_scale =
data->wave_scale;
5670 const float wave_max_slope =
data->wave_max_slope;
5672 const float dt =
data->dt;
5673 const float min_dist =
data->min_dist;
5674 const float damp_factor =
data->damp_factor;
5678 float force = 0.0f, avg_dist = 0.0f, avg_height = 0.0f, avg_n_height = 0.0f;
5679 int numOfN = 0, numOfRN = 0;
5681 if (wPoint->
state > 0) {
5690 for (
int i = 0;
i < numOfNeighs;
i++) {
5691 const int n_idx = n_index[index] +
i;
5692 float dist = bNeighs[n_idx].
dist * wave_scale;
5695 if (!dist || tPoint->
state > 0) {
5705 avg_n_height += tPoint->
height;
5709 force += (tPoint->
height - wPoint->
height) / (dist * dist);
5710 avg_height += tPoint->
height;
5712 avg_dist = (numOfN) ? avg_dist / numOfN : 0.0f;
5716 avg_n_height = (numOfRN) ? avg_n_height / numOfRN : 0.0f;
5717 wPoint->
height = (dt * wave_speed * avg_n_height + wPoint->
height * avg_dist) /
5718 (avg_dist + dt * wave_speed);
5724 force += (0.0f - wPoint->
height) * surface->
wave_spring / (avg_dist * avg_dist) / 2.0f;
5728 wPoint->
velocity += force * dt * wave_speed * wave_speed;
5735 if (wave_max_slope && avg_dist) {
5736 const float max_offset = wave_max_slope * avg_dist;
5737 const float offset = (numOfN) ? (avg_height / numOfN - wPoint->
height) : 0.0f;
5738 if (offset > max_offset) {
5739 wPoint->
height += offset - max_offset;
5741 else if (offset < -max_offset) {
5742 wPoint->
height += offset + max_offset;
5747 if (
data->reset_wave) {
5762 float dt, min_dist, damp_factor;
5763 const float wave_speed = surface->
wave_speed;
5767 double average_dist = 0.0f;
5779 for (index = 0; index < sData->
total_points; index++) {
5782 for (
int i = 0;
i < numOfNeighs;
i++) {
5790 (average_dist /
double(wave_speed) / 3)));
5796 min_dist = wave_speed * dt * 1.5f;
5799 for (ss = 0; ss <
steps; ss++) {
5804 data.surface = surface;
5805 data.prevPoint = prevPoint;
5806 data.wave_speed = wave_speed;
5807 data.wave_scale = wave_scale;
5808 data.wave_max_slope = wave_max_slope;
5810 data.min_dist = min_dist;
5811 data.damp_factor = damp_factor;
5846 const float timescale =
data->timescale;
5855 float p_wetness = pPoint->
wetness;
5864 float dry_ratio = pPoint->
wetness / p_wetness;
5877 pPoint->
e_color[3] *= dry_ratio;
5883 if (pPoint->
color[3]) {
5884 for (
int i = 0;
i < 3;
i++) {
5885 pPoint->
color[
i] = (f_color[
i] * f_color[3] -
5895 else if (pPoint->
state > 0) {
5924 float *point = &((
float *)sData->
type_data)[index];
5951 for (
int i = 0;
i < numOfVerts;
i++) {
5987 const Vec3f *canvas_verts =
data->canvas_verts;
5989 const bool do_velocity_data =
data->do_velocity_data;
5990 const bool new_bdata =
data->new_bdata;
5992 float prev_point[3] = {0.0f, 0.0f, 0.0f};
5995 if (do_velocity_data && !new_bdata) {
6003 float n1[3], n2[3], n3[3];
6008 bData->
s_pos[index] = index * bData->
s_num[index];
6011 for (
int ss = 0; ss < bData->
s_num[index]; ss++) {
6013 canvas_verts[tPoint->
v1].
v,
6014 canvas_verts[tPoint->
v2].
v,
6015 canvas_verts[tPoint->
v3].
v,
6030 float scaled_nor[3];
6041 bData->
s_num[index] = adj_data->
n_num[index] + 1;
6042 bData->
s_pos[index] = adj_data->
n_index[index] + index;
6045 bData->
s_num[index] = 1;
6046 bData->
s_pos[index] = index;
6050 for (ss = 0; ss < bData->
s_num[index]; ss++) {
6054 int t_index = adj_data->
n_index[index] + (ss - 1);
6058 canvas_verts[adj_data->
n_target[t_index]].
v,
6068 float scaled_nor[3];
6078 if (do_velocity_data && !new_bdata && !bData->
clear) {
6091 bool new_bdata =
false;
6099 Vec3f *canvas_verts;
6110 if (do_velocity_data && bData->
velocity && (bData->
clear || !surface_moved)) {
6115 if (!surface_moved) {
6121 "Dynamic Paint transformed canvas verts");
6122 if (!canvas_verts) {
6138 "Dynamic Paint step data");
6140 "Dynamic Paint bData s_pos");
6142 "Dynamic Paint bData s_num");
6144 "Dynamic Paint point coords");
6146 "Dynamic Paint bData prev_positions");
6172 if (do_velocity_data && !bData->
velocity) {
6177 "Dynamic Paint prev velocity");
6188 for (index = 0; index < canvasNumOfVerts; index++) {
6189 copy_v3_v3(canvas_verts[index].
v, positions[index]);
6190 mul_m4_v3(ob->object_to_world().ptr(), canvas_verts[index].
v);
6198 data.surface = surface;
6200 data.positions = positions;
6201 data.vert_normals = mesh->vert_normals();
6202 data.canvas_verts = canvas_verts;
6203 data.do_velocity_data = do_velocity_data;
6204 data.new_bdata = new_bdata;
6221 memcpy(bData->
prev_positions, positions.
data(), canvasNumOfVerts *
sizeof(
float[3]));
6250 data.surface = surface;
6251 data.timescale = timescale;
6269 int scene_frame = scene->
r.
cfra;
6270 float scene_subframe = scene->
r.
subframe;
6272 for (
int i = 0;
i < numobjects;
i++) {
6273 Object *brushObj = objects[
i];
6286 "Dynamic Paint brush velocity");
6330 depsgraph, surface, brushObj->
loc, brush, brushObj, scene, timescale);
6333 else if (brushObj != ob) {
6339 scene->
r.
cfra = scene_frame;
6377 float *force =
nullptr;
6381 "PaintSurfaceDataCopy");
6383 return setError(canvas,
N_(
"Not enough free memory"));
6388 for (s = 0; s <
steps; s++) {
6413 float timescale = 1.0f;
6426 timescale = 1.0f / (surface->
substeps + 1);
6428 for (st = 1; st <= surface->
substeps; st++) {
6429 float subframe = float(st) / (surface->
substeps + 1);
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)
#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)
void BKE_id_free(Main *bmain, void *idv)
@ LIB_ID_COPY_SET_COPIED_ON_WRITE
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.
void BKE_object_modifier_update_subframe(Depsgraph *depsgraph, Scene *scene, Object *ob, bool update_mesh, int parent_recursion_limit, float frame, int modifier_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)
File and directory operations.
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 ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(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
ATTR_WARN_UNUSED_RESULT const size_t num
bool BLI_path_abs(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1
#define SNPRINTF(dst, format,...)
char * STRNCPY(char(&dst)[N], const char *src)
#define STRNCPY_UTF8(dst, src)
size_t void BLI_uniquename_cb(blender::FunctionRef< bool(blender::StringRefNull)> unique_check, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(2
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)
#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)
@ MOD_DPAINT_INITIAL_NONE
@ MOD_DPAINT_INITIAL_VERTEXCOLOR
@ MOD_DPAINT_INITIAL_COLOR
@ MOD_DPAINT_INITIAL_TEXTURE
@ MOD_DPAINT_PRFALL_CONSTANT
@ MOD_DPAINT_PRFALL_SMOOTH
@ MOD_DPAINT_DISP_DISPLACE
@ MOD_DPAINT_SURFACE_F_PTEX
@ MOD_DPAINT_SURFACE_F_VERTEX
@ MOD_DPAINT_SURFACE_F_IMAGESEQ
@ 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_RAY_BRUSH_AVG
@ MOD_DPAINT_IMGFORMAT_OPENEXR
@ MOD_DPAINT_IMGFORMAT_PNG
@ MOD_DPAINT_WAVEB_REFLECT
@ MOD_DPAINT_WAVEB_CHANGE
@ MOD_DPAINT_EFFECT_DO_DRIP
@ MOD_DPAINT_EFFECT_DO_SPREAD
@ MOD_DPAINT_EFFECT_DO_SHRINK
@ MOD_DPAINT_WAVE_OPEN_BORDERS
@ MOD_DPAINT_DISP_INCREMENTAL
@ MOD_DPAINT_DISSOLVE_LOG
@ eModifierFlag_SharedCaches
@ eModifierType_DynamicPaint
@ MOD_DYNAMICPAINT_TYPE_BRUSH
@ MOD_DYNAMICPAINT_TYPE_CANVAS
Object is a sort of wrapper for general info.
@ PART_FLUID_SPRAYFOAMBUBBLE
void IMB_freeImBuf(ImBuf *ibuf)
ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
bool IMB_save_image(ImBuf *ibuf, const char *filepath, const int flags)
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)
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
BPy_StructRNA * depsgraph
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
constexpr const char * c_str() const
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
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 bool surface_duplicateNameExists(DynamicPaintSurface *t_surface, const blender::StringRefNull name)
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 bool surface_duplicateOutputExists(DynamicPaintSurface *t_surface, const blender::StringRefNull name)
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 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)
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 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)
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
float distance(VecOp< float, D >, VecOp< float, D >) RET
#define MAX_CUSTOMDATA_LAYER_NAME
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
MINLINE unsigned char unit_float_to_uchar_clamp(float val)
static void error(const char *str)
float bvhtree_ray_tri_intersection(const BVHTreeRay *ray, float m_dist, const float v0[3], const float v1[3], const float v2[3])
VecBase< int32_t, 3 > int3
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
blender::Mutex brush_mutex
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
struct PhysicsSettings physics_settings
TaskParallelReduceFunc func_reduce
size_t userdata_chunk_size
int multitex_ext_safe(Tex *tex, const float texvec[3], TexResult *texres, ImagePool *pool, bool scene_color_manage, const bool skip_load_image)