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;
373 for (; surface; surface = surface->
next) {
374 if (surface != t_surface && surface->
type == t_surface->
type &&
410 for (; surface; surface = surface->
next) {
411 if (surface != t_surface &&
STREQ(
name.c_str(), surface->
name)) {
429 sizeof(surface->
name));
434 const char *name_prefix =
"";
435 const char *name_suffix_1 =
"";
436 const char *name_suffix_2 =
"";
451 name_suffix_1 =
"paintmap";
452 name_suffix_2 =
"wetmap";
455 name_suffix_1 = name_suffix_2 =
"displace";
458 name_suffix_1 = name_suffix_2 =
"weight";
461 name_suffix_1 = name_suffix_2 =
"wave";
469 if (!output_name_equal) {
490 const float s_color[3],
495 float i_alpha = 1.0f - s_alpha;
496 float f_alpha = t_alpha * i_alpha + s_alpha;
500 for (
int i = 0;
i < 3;
i++) {
501 result[
i] = (t_color[
i] * t_alpha * i_alpha + s_color[
i] * s_alpha) / f_alpha;
513 float a_color[3],
float a_weight,
const float b_color[3],
float b_weight,
float ratio)
515 float weight_ratio, factor;
520 return b_weight * ratio;
522 weight_ratio = b_weight / (a_weight + b_weight);
525 return a_weight * (1.0f - ratio);
530 factor = weight_ratio * (ratio * 2.0f);
533 ratio = (ratio * 2.0f - 1.0f);
534 factor = weight_ratio * (1.0f - ratio) + ratio;
538 return (1.0f - factor) * a_weight + factor * b_weight;
556 for (
int i = 0;
i < numobjects;
i++) {
584 for (
int i = 2;
i--;) {
598 for (
int i = 2;
i--;) {
599 if (!(b1->
min[
i] <= (b2->
max[
i] + dist) && b1->
max[
i] >= (b2->
min[
i] - dist))) {
612 for (
int i = 2;
i--;) {
613 if (!(
b->min[
i] <= (point[
i] + radius) &&
b->max[
i] >= (point[
i] - radius))) {
658 bData->
grid =
nullptr;
673 void *__restrict chunk_join,
674 void *__restrict chunk)
690 int *s_num =
static_cast<int *
>(tls->userdata_chunk);
694 for (
int j = 3; j--;) {
696 bData->
dim[j] * grid->
dim[j]));
700 temp_t_index[
i] = co[0] + co[1] * grid->
dim[0] + co[2] * grid->
dim[0] * grid->
dim[1];
701 s_num[temp_t_index[
i]]++;
705 void *__restrict chunk_join,
706 void *__restrict chunk)
710 const int grid_cells = grid->
dim[0] * grid->
dim[1] * grid->
dim[2];
712 int *join_s_num =
static_cast<int *
>(chunk_join);
713 int *s_num =
static_cast<int *
>(chunk);
716 for (
int i = 0;
i < grid_cells;
i++) {
717 join_s_num[
i] += s_num[
i];
727 float *dim = bData->
dim;
728 int *grid_dim = grid->
dim;
730 for (
int y = 0;
y < grid_dim[1];
y++) {
731 for (
int z = 0;
z < grid_dim[2];
z++) {
732 const int b_index =
x +
y * grid_dim[0] +
z * grid_dim[0] * grid_dim[1];
734 for (
int j = 3; j--;) {
735 const int s = (j == 0) ?
x : ((j == 1) ?
y :
z);
749 int grid_cells, axis = 3;
750 int *temp_t_index =
nullptr;
751 int *temp_s_num =
nullptr;
762 float dim_factor, volume, dim[3];
782 min_dim =
max_fff(td[0], td[1], td[2]) / 1000.0f;
785 for (
i = 0;
i < 3;
i++) {
786 if (td[
i] < min_dim) {
792 if (axis == 0 ||
max_fff(td[0], td[1], td[2]) < 0.0001f) {
794 bData->
grid =
nullptr;
799 volume = td[0] * td[1] * td[2];
803 pow(
double(volume) / (
double(sData->
total_points) / 10000.0), 1.0 /
double(axis)));
806 for (
i = 0;
i < 3;
i++) {
807 grid->
dim[
i] = int(
floor(td[
i] / dim_factor));
808 CLAMP(grid->
dim[
i], (dim[
i] >= min_dim) ? 3 : 1, 100);
810 grid_cells = grid->
dim[0] * grid->
dim[1] * grid->
dim[2];
820 "Temp Surface Grid Target Ids");
842 for (
i = 1;
i < grid_cells;
i++) {
848 int pos = grid->
s_pos[temp_t_index[
i]] + temp_s_num[temp_t_index[
i]];
851 temp_s_num[temp_t_index[
i]]++;
888 pmd->
brush =
nullptr;
894 if (
data->adj_data) {
895 if (
data->adj_data->n_index) {
898 if (
data->adj_data->n_num) {
901 if (
data->adj_data->n_target) {
904 if (
data->adj_data->flags) {
907 if (
data->adj_data->border) {
911 data->adj_data =
nullptr;
948 data->bData =
nullptr;
955 if (!surface->
data) {
974 if (
data->format_data) {
978 if (format_data->
uv_p) {
988 if (
data->type_data) {
996 surface->
data =
nullptr;
1022 next_surface = surface->
next;
1024 surface = next_surface;
1034 if (pmd ==
nullptr) {
1052 surface->
canvas = canvas;
1153 brush->psys =
nullptr;
1161 brush->alpha = 1.0f;
1162 brush->wetness = 1.0f;
1164 brush->paint_distance = 1.0f;
1167 brush->particle_radius = 0.2f;
1168 brush->particle_smooth = 0.05f;
1171 brush->wave_factor = 1.0f;
1172 brush->wave_clamp = 0.0f;
1173 brush->smudge_strength = 0.3f;
1174 brush->max_velocity = 1.0f;
1181 if (!
brush->paint_ramp) {
1184 ramp =
brush->paint_ramp->data;
1186 ramp[0].
r = ramp[0].
g = ramp[0].
b = ramp[0].
a = 1.0f;
1188 ramp[1].
r = ramp[1].
g = ramp[1].
b = ramp[1].
pos = 1.0f;
1198 if (!
brush->vel_ramp) {
1201 ramp =
brush->vel_ramp->data;
1202 ramp[0].
r = ramp[0].
g = ramp[0].
b = ramp[0].
a = ramp[0].
pos = 0.0f;
1203 ramp[1].
r = ramp[1].
g = ramp[1].
b = ramp[1].
a = ramp[1].
pos = 1.0f;
1204 brush->paint_ramp->tot = 2;
1242 surface = surface->
next)
1308 t_brush->
pmd = tpmd;
1310 t_brush->flags =
brush->flags;
1311 t_brush->collision =
brush->collision;
1313 t_brush->r =
brush->r;
1314 t_brush->g =
brush->g;
1315 t_brush->b =
brush->b;
1316 t_brush->alpha =
brush->alpha;
1317 t_brush->wetness =
brush->wetness;
1319 t_brush->particle_radius =
brush->particle_radius;
1320 t_brush->particle_smooth =
brush->particle_smooth;
1321 t_brush->paint_distance =
brush->paint_distance;
1326 t_brush->psys =
brush->psys;
1328 if (
brush->paint_ramp) {
1329 memcpy(t_brush->paint_ramp,
brush->paint_ramp,
sizeof(
ColorBand));
1331 if (
brush->vel_ramp) {
1335 t_brush->proximity_falloff =
brush->proximity_falloff;
1336 t_brush->wave_type =
brush->wave_type;
1337 t_brush->ray_dir =
brush->ray_dir;
1339 t_brush->wave_factor =
brush->wave_factor;
1340 t_brush->wave_clamp =
brush->wave_clamp;
1341 t_brush->max_velocity =
brush->max_velocity;
1342 t_brush->smudge_strength =
brush->smudge_strength;
1351 switch (surface->
type) {
1354 "DynamicPaintSurface Data");
1358 "DynamicPaintSurface DepthData");
1362 "DynamicPaintSurface WeightData");
1366 "DynamicPaintSurface WaveData");
1394 int neigh_points = 0;
1402 neigh_points = 2 *
mesh->edges_num;
1408 if (!neigh_points) {
1438 int numOfEdges =
mesh->edges_num;
1439 int numOfPolys =
mesh->faces_num;
1445 for (
int i = 0;
i < numOfEdges;
i++) {
1446 ad->
n_num[edges[
i][0]]++;
1447 ad->
n_num[edges[
i][1]]++;
1449 temp_data[edges[
i][0]]++;
1450 temp_data[edges[
i][1]]++;
1455 for (
int i = 0;
i < numOfPolys;
i++) {
1456 for (
const int vert : corner_verts.
slice(
faces[
i])) {
1464 if ((temp_data[
i] % 2) || (temp_data[
i] < 4)) {
1480 for (
int i = 0;
i < numOfEdges;
i++) {
1482 int index = edges[
i][0];
1483 n_pos = ad->
n_index[index] + temp_data[index];
1488 index = edges[
i][1];
1489 n_pos = ad->
n_index[index] + temp_data[index];
1525 Tex *tex =
data->surface->init_texture;
1527 float uv[3] = {0.0f};
1529 for (
int j = 3; j--;) {
1531 const int vert = corner_verts[corner_tris[
i][j]];
1534 uv[0] = uv_map[corner_tris[
i][j]][0] * 2.0f - 1.0f;
1535 uv[1] = uv_map[corner_tris[
i][j]][1] * 2.0f - 1.0f;
1539 if (texres.
tin > pPoint[vert].
color[3]) {
1541 pPoint[vert].
color[3] = texres.
tin;
1557 Tex *tex =
data->surface->init_texture;
1561 float uv[9] = {0.0f};
1562 float uv_final[3] = {0.0f};
1567 for (
int j = 3; j--;) {
1574 uv_final[0] = uv_final[0] * 2.0f - 1.0f;
1575 uv_final[1] = uv_final[1] * 2.0f - 1.0f;
1585 void *__restrict userdata,
const int i,
const TaskParallelTLS *__restrict )
1599 float final_color[4];
1602 for (
int j = 3; j--;) {
1663 data.surface = surface;
1664 data.corner_verts = corner_verts;
1665 data.corner_tris = corner_tris;
1666 data.uv_map = uv_map;
1678 data.surface = surface;
1679 data.corner_tris = corner_tris;
1680 data.uv_map = uv_map;
1697 if (
col.is_empty()) {
1709 if (
col.is_empty()) {
1714 data.surface = surface;
1715 data.corner_tris = corner_tris;
1740 data_size =
sizeof(
float);
1760 if (surface->
data) {
1768 if (numOfPoints < 1) {
1774 if (!surface->
data) {
1844 data.surface = surface;
1845 data.vert_positions =
result->vert_positions_for_write();
1868 pPoint[
i].
color, pPoint[
i].
color[3], pPoint[
i].e_color, pPoint[
i].e_color[3], fcolor[
i]);
1887 for (
const int l_index :
data->faces[p_index]) {
1888 const int v_index = corner_verts[l_index];
1898 mloopcol_wet[l_index].r = c;
1899 mloopcol_wet[l_index].g = c;
1900 mloopcol_wet[l_index].b = c;
1901 mloopcol_wet[l_index].a = 255;
1935 surface = surface->
next)
1954 "Temp paint color");
1957 data.surface = surface;
1958 data.fcolor = fcolor;
2000 data.corner_verts = corner_verts;
2003 data.mloopcol_wet = mloopcol_wet.
span;
2021 float *weight = (
float *)sData->
type_data;
2025 if (defgrp_index != -1) {
2031 if ((def_weight !=
nullptr) || (weight[
i] != 0.0f)) {
2033 if (def_weight ==
nullptr) {
2038 def_weight->
weight = weight[
i];
2046 data.surface = surface;
2047 data.vert_positions =
result->vert_positions_for_write();
2055 result->tag_positions_changed();
2061 result->tag_positions_changed();
2118 for (; surface; surface = surface->
next) {
2119 int current_frame = scene->
r.
cfra;
2120 bool no_surface_data;
2133 no_surface_data = surface->
data ==
nullptr;
2141 if (no_surface_data || current_frame != surface->
current_frame ||
2168 else if (can_simulate) {
2204#define JITTER_SAMPLES \
2254 for (
int tx = 0; tx <
w; tx++) {
2255 const int index = tx +
w * ty;
2265 point[0][0] = (
float(tx) + 0.5f) /
w;
2266 point[0][1] = (
float(ty) + 0.5f) / h;
2272 point[1][0] =
float(tx) /
w;
2273 point[1][1] =
float(ty) / h;
2275 point[2][0] = (
float(tx) + 1) /
w;
2276 point[2][1] =
float(ty) / h;
2278 point[3][0] =
float(tx) /
w;
2279 point[3][1] = (
float(ty) + 1) / h;
2281 point[4][0] = (
float(tx) + 1) /
w;
2282 point[4][1] = (
float(ty) + 1) / h;
2297 const float *uv1 = uv_map[corner_tris[
i][0]];
2298 const float *uv2 = uv_map[corner_tris[
i][1]];
2299 const float *uv3 = uv_map[corner_tris[
i][2]];
2306 for (
int j = 0; j < aa_samples; j++) {
2307 uv[0] = point[0][0] + jitter5sample[j * 2] /
w;
2308 uv[1] = point[0][1] + jitter5sample[j * 2 + 1] / h;
2317 tPoint->
v1 = corner_verts[corner_tris[
i][0]];
2318 tPoint->
v2 = corner_verts[corner_tris[
i][1]];
2319 tPoint->
v3 = corner_verts[corner_tris[
i][2]];
2344 uint32_t *active_points =
data->active_points;
2351 for (
int tx = 0; tx <
w; tx++) {
2352 const int index = tx +
w * ty;
2360 const int u_min = (tx > 0) ? -1 : 0;
2361 const int u_max = (tx < (
w - 1)) ? 1 : 0;
2362 const int v_min = (ty > 0) ? -1 : 0;
2363 const int v_max = (ty < (h - 1)) ? 1 : 0;
2365 point[0] = (
float(tx) + 0.5f) /
w;
2366 point[1] = (
float(ty) + 0.5f) / h;
2369 for (
int ni = 0; ni < 8; ni++) {
2373 if (u >= u_min && u <= u_max && v >= v_min &&
v <= v_max) {
2375 if (u != 0 ||
v != 0) {
2376 const int ind = (tx + u) +
w * (ty +
v);
2379 if (tempPoints[ind].neighbor_pixel == -1 && tempPoints[ind].tri_index != -1) {
2382 const float *uv1 = uv_map[corner_tris[
i][0]];
2383 const float *uv2 = uv_map[corner_tris[
i][1]];
2384 const float *uv3 = uv_map[corner_tris[
i][2]];
2400 for (
int j = 0; j < aa_samples; j++) {
2401 uv[0] = point[0] + jitter5sample[j * 2] /
w;
2402 uv[1] = point[1] + jitter5sample[j * 2 + 1] / h;
2407 tPoint->
v1 = corner_verts[corner_tris[
i][0]];
2408 tPoint->
v2 = corner_verts[corner_tris[
i][1]];
2409 tPoint->
v3 = corner_verts[corner_tris[
i][2]];
2425#undef JITTER_SAMPLES
2430 const float point[2])
2436 for (
int i = 0;
i < 3;
i++) {
2439 uv_map[corner_tris[tri_index][(
i + 0)]],
2440 uv_map[corner_tris[tri_index][(
i + 1) % 3]]);
2442 min_distance = std::min(dist_squared, min_distance);
2445 return min_distance;
2459 const float pixel[2],
2483 const int x = px +
neighX[n_index];
2484 const int y = py +
neighY[n_index];
2531 pixel[0] = (
float(px +
neighX[n_index]) + 0.5f) /
float(
w);
2532 pixel[1] = (
float(py +
neighY[n_index]) + 0.5f) /
float(h);
2544 const float pixel[2],
2552 const int3 loop_idx = corner_tris[tri_index];
2555 for (
int edge_idx = 0; edge_idx < 3; edge_idx++) {
2557 if (edge_idx == in_edge) {
2561 float uv0[2], uv1[2], uv2[2];
2563 copy_v2_v2(uv0, uv_map[loop_idx[(edge_idx + 0)]]);
2564 copy_v2_v2(uv1, uv_map[loop_idx[(edge_idx + 1) % 3]]);
2565 copy_v2_v2(uv2, uv_map[loop_idx[(edge_idx + 2) % 3]]);
2572 if (side2 == 0.0f) {
2577 const bool correct_side = (in_edge == -1) || (sidep < 0 && side2 > 0) ||
2578 (sidep > 0 && side2 < 0);
2581 if (!correct_side && sidep != 0.0f) {
2586 const int vert0 = corner_verts[loop_idx[(edge_idx + 0)]];
2587 const int vert1 = corner_verts[loop_idx[(edge_idx + 1) % 3]];
2593 bool found_other =
false;
2594 int target_tri = -1;
2595 int target_edge = -1;
2597 float ouv0[2], ouv1[2];
2599 for (
int i = 0;
i < map->count && !found_other;
i++) {
2600 const int tri_other_index = map->indices[
i];
2602 if (tri_other_index == tri_index) {
2606 const int3 other_tri = corner_tris[tri_other_index];
2609 for (
int j = 0; j < 3; j++) {
2610 const int overt0 = corner_verts[other_tri[(j + 0)]];
2611 const int overt1 = corner_verts[other_tri[(j + 1) % 3]];
2614 if (overt0 == vert0 && overt1 == vert1) {
2616 copy_v2_v2(ouv0, uv_map[other_tri[(j + 0)]]);
2617 copy_v2_v2(ouv1, uv_map[other_tri[(j + 1) % 3]]);
2619 else if (overt0 == vert1 && overt1 == vert0) {
2621 copy_v2_v2(ouv1, uv_map[other_tri[(j + 0)]]);
2622 copy_v2_v2(ouv0, uv_map[other_tri[(j + 1) % 3]]);
2626 target_tri = tri_other_index;
2643 if (depth > 0 && correct_side) {
2662 float closest_point[2], dir_vec[2], tgt_pixel[2];
2665 CLAMP(lambda, 0.0f, 1.0f);
2670 int w = bdata->
w, h = bdata->
h, px = bdata->
px, py = bdata->
py;
2672 const int final_pixel[2] = {int(
floorf(tgt_pixel[0] *
w)), int(
floorf(tgt_pixel[1] * h))};
2675 if (final_pixel[0] < 0 || final_pixel[0] >=
w || final_pixel[1] < 0 || final_pixel[1] >= h) {
2684 int final_index = final_pixel[0] +
w * final_pixel[1];
2687 if (final_index == (px +
w * py)) {
2692 if (tempPoints[final_index].neighbor_pixel != -1) {
2696 if (final_index == (px +
w * py)) {
2701 const int final_tri_index = tempPoints[final_index].
tri_index;
2703 if (!
ELEM(final_tri_index, target_tri, -1)) {
2706 const float final_pt[2] = {((final_index %
w) + 0.5f) /
w, ((final_index /
w) + 0.5f) / h};
2707 const float threshold =
square_f(0.7f) / (
w * h);
2723 const int idx =
ed->n_index[index];
2725 for (
int i = 0;
i <
ed->n_num[index];
i++) {
2726 if (
ed->n_target[idx +
i] == neighbor) {
2741 if (new_n_num && new_n_index) {
2743 int total_targets = 0;
2745 for (
int index = 0; index < active_points; index++) {
2746 total_targets +=
ed->n_num[index];
2747 new_n_num[index] =
ed->n_num[index];
2750 for (
int index = 0; index < active_points; index++) {
2755 for (
int i = 0, idx =
ed->n_index[index];
i < ed->n_num[index];
i++) {
2756 const int target =
ed->n_target[idx +
i];
2761 new_n_num[target]++;
2774 for (
int index = 0; index < active_points; index++) {
2775 new_n_index[index] = n_pos;
2776 memcpy(&new_n_target[n_pos],
2777 &
ed->n_target[
ed->n_index[index]],
2778 sizeof(
int) *
ed->n_num[index]);
2781 n_pos += new_n_num[index];
2782 new_n_num[index] =
ed->n_num[index];
2788 for (
int index = 0; index < active_points; index++) {
2793 for (
int i = 0, idx =
ed->n_index[index];
i < ed->n_num[index];
i++) {
2794 const int target =
ed->n_target[idx +
i];
2797 const int num = new_n_num[target]++;
2798 new_n_target[new_n_index[target] +
num] = index;
2805 ed->n_target = new_n_target;
2808 ed->n_index = new_n_index;
2811 ed->n_num = new_n_num;
2813 ed->total_targets = total_targets;
2837 uint32_t active_points = 0;
2845 Vec3f *tempWeights =
nullptr;
2855 return setError(canvas,
N_(
"Canvas mesh not updated"));
2858 return setError(canvas,
N_(
"Cannot bake non-'image sequence' formats"));
2874 return setError(canvas,
N_(
"No UV data on canvas"));
2877 return setError(canvas,
N_(
"Invalid resolution"));
2887 &
LOG,
"Preparing UV surface of %ix%i pixels and %i tris.",
w, h,
int(corner_tris.
size()));
2890 if (surface->
data) {
2894 if (!surface->
data) {
2895 return setError(canvas,
N_(
"Not enough free memory"));
2933 for (
int j = 1; j < 3; j++) {
2943 data.surface = surface;
2944 data.tempPoints = tempPoints;
2945 data.tempWeights = tempWeights;
2946 data.corner_tris = corner_tris;
2947 data.uv_map = uv_map;
2948 data.corner_verts = corner_verts;
2949 data.faceBB = faceBB;
2967 data.active_points = &active_points;
2984 for (
int i = 0;
i <
w * h;
i++) {
2985 if (tempPoints[
i].tri_index != -1) {
2986 final_index[
i] = cursor;
2999 int *vert_to_tri_map_mem;
3002 &vert_to_tri_map_mem,
3006 corner_verts.
data(),
3009 int total_border = 0;
3011 for (
int ty = 0; ty < h; ty++) {
3012 for (
int tx = 0; tx <
w; tx++) {
3013 const int index = tx +
w * ty;
3015 if (tempPoints[index].tri_index != -1) {
3016 ed->n_index[final_index[index]] = n_pos;
3017 ed->n_num[final_index[index]] = 0;
3019 if (tempPoints[index].neighbor_pixel != -1) {
3024 for (
int i = 0;
i < 8;
i++) {
3028 &
data, vert_to_tri_map,
w, h, tx, ty,
i);
3030 if (n_target >= 0 && n_target != index) {
3032 ed, final_index[index], final_index[n_target]))
3034 ed->n_target[n_pos] = final_index[n_target];
3035 ed->n_num[final_index[index]]++;
3059 ed->total_border = total_border;
3061 for (
int i = 0,
next = 0;
i < active_points;
i++) {
3072 FILE *dump_file = fopen(
"dynpaint-adj-data.txt",
"w");
3074 for (
int ty = 0; ty < h; ty++) {
3075 for (
int tx = 0; tx <
w; tx++) {
3076 const int index = tx +
w * ty;
3077 if (tempPoints[index].tri_index != -1) {
3078 tmp[final_index[index]] = index;
3082 for (
int ty = 0; ty < h; ty++) {
3083 for (
int tx = 0; tx <
w; tx++) {
3084 const int index = tx +
w * ty;
3085 const int fidx = final_index[index];
3087 if (tempPoints[index].tri_index != -1) {
3090 "%d\t%d,%d\t%u\t%d,%d\t%d\t",
3094 tempPoints[index].tri_index,
3095 nidx < 0 ? -1 : (nidx %
w),
3096 nidx < 0 ? -1 : h - 1 - (nidx /
w),
3098 for (
int i = 0;
i <
ed->n_num[fidx];
i++) {
3099 int tgt = tmp[
ed->n_target[
ed->n_index[fidx] +
i]];
3100 fprintf(dump_file,
"%s%d,%d",
i ?
" " :
"", tgt %
w, h - 1 - tgt /
w);
3102 fprintf(dump_file,
"\n");
3147 for (
int index = 0, cursor = 0; index < (
w * h); index++) {
3148 if (tempPoints[index].tri_index != -1) {
3151 &tempWeights[index * aa_samples],
3152 sizeof(*tempWeights) * aa_samples);
3159 setError(canvas,
N_(
"Not enough free memory"));
3183 for (index = 0; index < sData->
total_points; index++) {
3187 pPoint->alpha = 1.0f;
3191 pPoint->
color[2] = 1.0f;
3196 pPoint->
color[0] = 1.0f;
3208 return (
error == 0);
3247 void *__restrict userdata,
const int index,
const TaskParallelTLS *__restrict )
3264 depth = (0.5f - depth / 2.0f);
3267 CLAMP(depth, 0.0f, 1.0f);
3282 float depth = wPoint->
height;
3292 depth = (0.5f + depth / 2.0f);
3293 CLAMP(depth, 0.0f, 1.0f);
3318 const char *filepath,
3321 ImBuf *ibuf =
nullptr;
3333#ifndef WITH_IMAGE_OPENEXR
3338 STRNCPY(output_file, filepath);
3347 if (ibuf ==
nullptr) {
3348 setError(surface->
canvas,
N_(
"Image save failed: not enough free memory"));
3353 data.surface = surface;
3356 switch (surface->
type) {
3358 switch (output_layer) {
3387 switch (output_layer) {
3407 switch (output_layer) {
3432#ifdef WITH_IMAGE_OPENEXR
3466 const int3 *corner_tris =
data->corner_tris.data();
3467 const int *corner_verts =
data->corner_verts.data();
3469 const float *t0, *t1, *t2;
3472 t0 = positions[corner_verts[corner_tris[index][0]]];
3473 t1 = positions[corner_verts[corner_tris[index][1]]];
3474 t2 = positions[corner_verts[corner_tris[index][2]]];
3478 if (dist >= 0 && dist < hit->dist) {
3498 const int3 *corner_tris =
data->corner_tris.data();
3499 const int *corner_verts =
data->corner_verts.data();
3500 float nearest_tmp[3], dist_sq;
3502 const float *t0, *t1, *t2;
3503 t0 = positions[corner_verts[corner_tris[index][0]]];
3504 t1 = positions[corner_verts[corner_tris[index][1]]];
3505 t2 = positions[corner_verts[corner_tris[index][2]]];
3510 if (dist_sq < nearest->dist_sq) {
3511 nearest->
index = index;
3514 nearest->
no[0] = 0.0f;
3532 const int paintFlags,
3533 const float paintColor[3],
3534 const float paintAlpha,
3535 const float paintWetness,
3536 const float timescale)
3556 float wetness = paintWetness;
3557 CLAMP(wetness, 0.0f, 1.0f);
3568 float a_ratio, a_highest;
3570 float invFact = 1.0f - paintAlpha;
3578 if (a_highest > invFact) {
3579 a_ratio = invFact / a_highest;
3581 pPoint->
e_color[3] *= a_ratio;
3582 pPoint->
color[3] *= a_ratio;
3586 pPoint->
e_color[3] -= paintAlpha * timescale;
3588 pPoint->
color[3] -= paintAlpha * timescale;
3592 wetness = (1.0f - paintWetness) * pPoint->
e_color[3];
3602 const float isect_change = isect_height - wPoint->
brush_isect;
3603 const float wave_factor =
brush->wave_factor;
3610 isect_height *= wave_factor;
3613 if (wave_factor > 0.0f && wPoint->
height > isect_height) {
3616 else if (wave_factor < 0.0f && wPoint->height < isect_height) {
3621 switch (
brush->wave_type) {
3623 wPoint->
height = isect_height;
3634 if (isect_change < 0.0f) {
3635 wPoint->
height += isect_change * wave_factor;
3655 const float timescale)
3664 strength = influence *
brush->alpha;
3665 CLAMP(strength, 0.0f, 1.0f);
3672 vel_factor /=
brush->max_velocity;
3673 CLAMP(vel_factor, 0.0f, 1.0f);
3680 strength *= coba_res[3];
3683 depth *= coba_res[3];
3690 float paintWetness =
brush->wetness * strength;
3691 float paintAlpha = strength;
3694 surface, index,
brush->flags,
paint, paintAlpha, paintWetness, timescale);
3698 float *value = (
float *)sData->
type_data;
3701 depth = value[index] + depth;
3709 value[index] *= (1.0f - strength);
3718 float *value = (
float *)sData->
type_data;
3721 value[index] *= (1.0f - strength);
3730 if (
brush->wave_clamp) {
3780 const float (*positions_p)[3] =
data->positions_p;
3781 const float (*positions_c)[3] =
data->positions_c;
3784 float (*prev_obmat)[4] =
data->prev_obmat;
3786 const float timescale =
data->timescale;
3807 float prev_obmat[4][4];
3808 Mesh *mesh_p, *mesh_c;
3809 int numOfVerts_p, numOfVerts_c;
3812 int cur_fra = scene->
r.
cfra;
3813 float prev_sfra = cur_sfra - timescale;
3814 int prev_fra = cur_fra;
3816 if (prev_sfra < 0.0f) {
3818 prev_fra = cur_fra - 1;
3822 scene->
r.
cfra = prev_fra;
3835 if (!runtime_data) {
3838 std::lock_guard
lock(runtime_data->brush_mutex);
3843 float (*positions_p)[3] =
reinterpret_cast<float (*)[3]
>(
3844 mesh_p->vert_positions_for_write().
data());
3845 copy_m4_m4(prev_obmat, ob->object_to_world().ptr());
3848 scene->
r.
cfra = cur_fra;
3859 if (!runtime_data) {
3862 std::lock_guard
lock(runtime_data->brush_mutex);
3863 mesh_c = runtime_data->brush_mesh;
3866 float (*positions_c)[3] =
reinterpret_cast<float (*)[3]
>(
3867 mesh_c->vert_positions_for_write().
data());
3876 if (numOfVerts_p != numOfVerts_c) {
3877 positions_p = positions_c;
3882 data.brush_vel = *brushVel;
3883 data.positions_p = positions_p;
3884 data.positions_c = positions_c;
3885 data.obmat = ob->object_to_world().ptr();
3886 data.prev_obmat = prev_obmat;
3887 data.timescale = timescale;
3902 float prev_obmat[4][4];
3903 float cur_loc[3] = {0.0f}, prev_loc[3] = {0.0f};
3906 int cur_fra = scene->
r.
cfra;
3907 float prev_sfra = cur_sfra - timescale;
3908 int prev_fra = cur_fra;
3910 if (prev_sfra < 0.0f) {
3912 prev_fra = cur_fra - 1;
3916 scene->
r.
cfra = prev_fra;
3925 copy_m4_m4(prev_obmat, ob->object_to_world().ptr());
3928 scene->
r.
cfra = cur_fra;
3940 mul_m4_v3(ob->object_to_world().ptr(), cur_loc);
3986 const float timescale =
data->timescale;
3987 const int c_index =
data->c_index;
3992 const float brush_radius =
data->brush_radius;
3993 const float *avg_brushNor =
data->avg_brushNor;
3994 const Vec3f *brushVelocity =
data->brushVelocity;
4000 const int samples = bData->
s_num[index];
4002 float total_sample =
float(samples);
4003 float brushStrength = 0.0f;
4005 float velocity_val = 0.0f;
4007 float paintColor[3] = {0.0f};
4016 for (ss = 0; ss < samples; ss++) {
4017 float ray_start[3], ray_dir[3];
4018 float sample_factor = 0.0f;
4019 float sampleStrength = 0.0f;
4022 short hit_found = 0;
4025 float volume_factor = 0.0f;
4027 float proximity_factor = 0.0f;
4028 float prox_colorband[4] = {0.0f};
4041 sample_factor = 1.0f;
4054 nearest.
dist_sq = brush_radius * brush_radius;
4060 if (hit.
index != -1) {
4064 const int vtri[3] = {
4065 corner_verts[corner_tris[hit.
index][0]],
4066 corner_verts[corner_tris[hit.
index][1]],
4067 corner_verts[corner_tris[hit.
index][2]],
4071 normal_tri_v3(hit.
no, positions[vtri[0]], positions[vtri[1]], positions[vtri[2]]);
4077 const float dist = hit.
dist;
4078 const int f_index = hit.
index;
4089 if (hit.
index != -1) {
4091 volume_factor = 1.0f;
4099 depth += dist * sample_factor;
4110 float proxDist = -1.0f;
4111 float hitCo[3] = {0.0f, 0.0f, 0.0f};
4115 if (inner_proximity && !hit_found) {
4123 if (nearest.
index != -1) {
4126 tri = nearest.
index;
4130 float proj_ray[3] = {0.0f};
4143 hit.
dist = brush_radius;
4148 if (hit.
index != -1) {
4149 proxDist = hit.
dist;
4159 if (proxDist >= 0.0f && proxDist <= brush_radius) {
4160 proximity_factor = proxDist / brush_radius;
4161 CLAMP(proximity_factor, 0.0f, 1.0f);
4162 if (!inner_proximity) {
4163 proximity_factor = 1.0f - proximity_factor;
4180 volume_factor = 1.0f - volume_factor;
4181 if (inner_proximity) {
4182 proximity_factor = 1.0f - proximity_factor;
4188 sampleStrength = volume_factor;
4195 proximity_factor = prox_colorband[3];
4202 sampleStrength = proximity_factor;
4205 sampleStrength *= sample_factor;
4214 float brushPointVelocity[3];
4217 const int v1 = corner_verts[corner_tris[hitTri][0]];
4218 const int v2 = corner_verts[corner_tris[hitTri][1]];
4219 const int v3 = corner_verts[corner_tris[hitTri][2]];
4229 brushVelocity[v1].
v,
4230 brushVelocity[
v2].
v,
4231 brushVelocity[v3].
v,
4256 float sampleColor[3];
4257 float alpha_factor = 1.0f;
4259 sampleColor[0] =
brush->r;
4260 sampleColor[1] =
brush->g;
4261 sampleColor[2] =
brush->b;
4266 sampleColor[0] = prox_colorband[0];
4267 sampleColor[1] = prox_colorband[1];
4268 sampleColor[2] = prox_colorband[2];
4273 paintColor[0] += sampleColor[0];
4274 paintColor[1] += sampleColor[1];
4275 paintColor[2] += sampleColor[2];
4276 sampleStrength *= alpha_factor;
4281 brushStrength += sampleStrength;
4285 if (brushStrength > 0.0f || depth > 0.0f) {
4288 brushStrength /= total_sample;
4290 CLAMP(brushStrength, 0.0f, 1.0f);
4294 paintColor[0] /= numOfHits;
4295 paintColor[1] /= numOfHits;
4296 paintColor[2] /= numOfHits;
4304 surface, index,
brush, paintColor, brushStrength, depth, velocity_val, timescale);
4318 Vec3f *brushVelocity =
nullptr;
4326 if (!runtime_data) {
4329 std::lock_guard
lock(runtime_data->brush_mutex);
4330 const Mesh *brush_mesh = runtime_data->brush_mesh;
4331 if (brush_mesh ==
nullptr) {
4336 float avg_brushNor[3] = {0.0f};
4348 numOfVerts =
mesh->verts_num;
4353 for (ii = 0; ii < numOfVerts; ii++) {
4354 mul_m4_v3(brushOb->object_to_world().ptr(), positions[ii]);
4368 mesh->tag_positions_changed();
4371 mul_v3_fl(avg_brushNor, 1.0f /
float(numOfVerts));
4374 avg_brushNor[2] = 1.0f;
4382 if (treeData.
tree !=
nullptr) {
4384 int total_cells = grid->
dim[0] * grid->
dim[1] * grid->
dim[2];
4387 for (c_index = 0; c_index < total_cells; c_index++) {
4389 if (!grid->
s_num[c_index] ||
4397 data.surface = surface;
4399 data.brushOb = brushOb;
4401 data.timescale = timescale;
4402 data.c_index = c_index;
4404 data.positions = positions;
4405 data.corner_verts = corner_verts;
4406 data.corner_tris = corner_tris;
4407 data.brush_radius = brush_radius;
4408 data.avg_brushNor = avg_brushNor;
4409 data.brushVelocity = brushVelocity;
4410 data.treeData = &treeData;
4416 grid->
s_num[c_index],
4427 if (brushVelocity) {
4438 void *__restrict userdata,
const int id,
const TaskParallelTLS *__restrict )
4451 const float timescale =
data->timescale;
4452 const int c_index =
data->c_index;
4454 KDTree_3d *
tree =
static_cast<KDTree_3d *
>(
data->treeData);
4456 const float solidradius =
data->solidradius;
4458 const float range = solidradius + smooth;
4459 const float particle_timestep = 0.04f * psys->
part->
timetweak;
4462 float disp_intersect = 0.0f;
4463 float radius = 0.0f;
4464 float strength = 0.0f;
4465 int part_index = -1;
4472 KDTreeNearest_3d nearest;
4473 float smooth_range, part_solidradius;
4478 if (nearest.dist > range) {
4485 part_solidradius = pa->
size;
4488 part_solidradius = solidradius;
4490 radius = part_solidradius + smooth;
4491 if (nearest.dist < radius) {
4493 smooth_range =
max_ff(0.0f, (nearest.dist - part_solidradius));
4496 smooth_range /= smooth;
4499 strength = 1.0f - smooth_range;
4500 disp_intersect = radius - nearest.dist;
4501 part_index = nearest.index;
4510 KDTreeNearest_3d *nearest;
4512 float smooth_range = smooth * (1.0f - strength), dist;
4514 const float max_range = smooth - strength * smooth + solidradius;
4518 const int particles = BLI_kdtree_3d_range_search(
4522 for (
int n = 0; n < particles; n++) {
4526 if (nearest[n].dist > (pa->
size + smooth)) {
4531 const float s_range = nearest[n].dist - pa->
size;
4533 if (smooth_range < s_range) {
4538 smooth_range = s_range;
4539 dist = nearest[n].dist;
4540 part_index = nearest[n].index;
4543 if ((s_range < 0.0f) &&
4555 const float rad = radius + smooth;
4556 if ((rad - dist) > disp_intersect) {
4557 disp_intersect = radius - dist;
4564 smooth_range /= smooth;
4567 const float str = 1.0f - smooth_range;
4569 strength = std::max(
str, strength);
4572 if (strength > 0.001f) {
4573 float paintColor[4] = {0.0f};
4575 float velocity_val = 0.0f;
4603 disp_intersect = (1.0f -
sqrtf(disp_intersect / radius)) * radius;
4608 surface, index,
brush, paintColor, strength, depth, velocity_val, timescale);
4623 int particlesAdded = 0;
4624 int invalidParticles = 0;
4629 brush->particle_radius);
4632 const float range = solidradius + smooth;
4657 if (
isnan(pa->state.co[0]) ||
isnan(pa->state.co[1]) ||
isnan(pa->state.co[2])) {
4667 BLI_kdtree_3d_insert(
tree, p, pa->state.co);
4674 if (invalidParticles) {
4679 if (particlesAdded < 1) {
4680 BLI_kdtree_3d_free(
tree);
4687 int total_cells = grid->
dim[0] * grid->
dim[1] * grid->
dim[2];
4690 BLI_kdtree_3d_balance(
tree);
4693 for (c_index = 0; c_index < total_cells; c_index++) {
4701 data.surface = surface;
4704 data.solidradius = solidradius;
4705 data.timescale = timescale;
4706 data.c_index = c_index;
4713 grid->
s_num[c_index],
4719 BLI_kdtree_3d_free(
tree);
4737 const float timescale =
data->timescale;
4739 const float brush_radius =
data->brush_radius;
4740 const Vec3f *brushVelocity =
data->brushVelocity;
4742 float *pointCoord =
data->pointCoord;
4745 float colorband[4] = {0.0f};
4754 strength = 1.0f -
distance / brush_radius;
4755 CLAMP(strength, 0.0f, 1.0f);
4761 if (strength >= 0.001f) {
4762 float paintColor[3] = {0.0f};
4764 float velocity_val = 0.0f;
4770 strength = colorband[3];
4783 velocity_val =
len_v3(velocity);
4798 paintColor[0] = colorband[0];
4799 paintColor[1] = colorband[1];
4800 paintColor[2] = colorband[2];
4803 paintColor[0] =
brush->r;
4804 paintColor[1] =
brush->g;
4805 paintColor[2] =
brush->b;
4810 const float disp_intersect = (1.0f -
sqrtf((brush_radius -
distance) / brush_radius)) *
4815 surface, index,
brush, paintColor, strength, depth, velocity_val, timescale);
4839 std::lock_guard
lock(runtime_data->brush_mutex);
4840 const Mesh *brush_mesh = runtime_data->brush_mesh;
4846 data.surface = surface;
4848 data.brushOb = brushOb;
4850 data.timescale = timescale;
4851 data.positions = brush_mesh->vert_positions();
4852 data.brush_radius = brush_radius;
4853 data.brushVelocity = &brushVel;
4854 data.pointCoord = pointCoord;
4881 const int num_neighs = adj_data->
n_num[index];
4883 for (
int i = 0;
i < num_neighs;
i++) {
4884 const int n_index = adj_data->
n_index[index] +
i;
4885 const int t_index = adj_data->
n_target[n_index];
4889 realCoord[bData->
s_pos[t_index]].
v,
4890 realCoord[bData->
s_pos[index]].
v);
4928 for (index = 0; index < sData->
total_points; index++) {
4929 int numOfNeighs = adj_data->
n_num[index];
4931 for (
int i = 0;
i < numOfNeighs;
i++) {
4942 const float force[3],
4949 closest_id[0] = closest_id[1] = -1;
4950 closest_d[0] = closest_d[1] = -1.0f;
4953 for (
int i = 0;
i < numOfNeighs;
i++) {
4955 const float dir_dot =
dot_v3v3(bNeighs[n_index].dir, force);
4957 if (dir_dot > closest_d[0] && dir_dot > 0.0f) {
4958 closest_d[0] = dir_dot;
4959 closest_id[0] = n_index;
4963 if (closest_d[0] < 0.0f) {
4968 for (
int i = 0;
i < numOfNeighs;
i++) {
4971 if (n_index == closest_id[0]) {
4975 const float dir_dot =
dot_v3v3(bNeighs[n_index].dir, force);
4976 const float closest_dot =
dot_v3v3(bNeighs[n_index].dir, bNeighs[closest_id[0]].dir);
4980 if (dir_dot > closest_d[1] && closest_dot < closest_d[0] && dir_dot > 0.0f) {
4981 closest_d[1] = dir_dot;
4982 closest_id[1] = n_index;
4988 if (closest_id[1] != -1) {
4989 float force_proj[3];
4991 const float neigh_diff =
acosf(
4992 dot_v3v3(bNeighs[closest_id[0]].dir, bNeighs[closest_id[1]].dir));
4993 float force_intersect;
4998 cross_v3_v3v3(tangent, bNeighs[closest_id[0]].dir, bNeighs[closest_id[1]].dir);
5000 force_intersect =
dot_v3v3(force, tangent);
5001 madd_v3_v3v3fl(force_proj, force, tangent, (-1.0f) * force_intersect);
5005 temp =
dot_v3v3(bNeighs[closest_id[0]].dir, force_proj);
5006 CLAMP(temp, -1.0f, 1.0f);
5007 closest_d[1] =
acosf(temp) / neigh_diff;
5008 closest_d[0] = 1.0f - closest_d[1];
5011 temp =
fabsf(force_intersect);
5012 CLAMP(temp, 0.0f, 1.0f);
5028 float max_velocity = 0.0f;
5035 for (
int index = 0; index < sData->
total_points; index++) {
5040 int steps = int(
ceil(
double(max_velocity) / bData->
average_dist *
double(timescale)));
5041 CLAMP(steps, 0, 12);
5042 float eff_scale =
brush->smudge_strength /
float(steps) * timescale;
5045 for (
int index = 0; index < sData->
total_points; index++) {
5064 sData, index, &bData->
brush_velocity[index * 4], closest_d, closest_id);
5067 for (
int i = 0;
i < 2;
i++) {
5068 int n_index = closest_id[
i];
5069 if (n_index != -1 && closest_d[
i] > 0.0f) {
5070 float dir_dot = closest_d[
i], dir_factor;
5071 float speed_scale = eff_scale * smudge_str / bNeighs[n_index].
dist;
5076 if (dir_dot <= 0.0f) {
5080 dir_factor = dir_dot * speed_scale;
5085 ePoint->
color[3] = ePoint->
color[3] * (1.0f - dir_factor) +
5086 pPoint->
color[3] * dir_factor;
5095 pPoint->
e_color[3] * dir_factor;
5096 pPoint->
wetness *= (1.0f - dir_factor);
5141 float *force =
data->force;
5144 float forc[3] = {0};
5153 effectors,
nullptr, surface->
effector_weights, &epoint, forc,
nullptr,
nullptr);
5192 double average_force = 0.0f;
5193 float shrink_speed = 0.0f, spread_speed = 0.0f;
5194 float fastest_effect, avg_dist;
5209 data.surface = surface;
5211 data.force = *force;
5212 data.effectors = effectors;
5221 for (
int index = 0; index < sData->
total_points; index++) {
5222 average_force += double((*force)[index * 4 + 3]);
5240 fastest_effect =
max_fff(spread_speed, shrink_speed, average_force);
5244 CLAMP(steps, 1, 20);
5269 const float eff_scale =
data->eff_scale;
5275 for (
int i = 0;
i < numOfNeighs;
i++) {
5276 const int n_idx = n_index[index] +
i;
5278 const PaintPoint *pPoint_prev = &prevPoint[n_target[n_idx]];
5279 const float speed_scale = (bNeighs[n_idx].
dist < eff_scale) ? 1.0f :
5280 eff_scale / bNeighs[n_idx].
dist;
5298 w_factor = 1.0f / numOfNeighs *
min_ff(pPoint_prev->
wetness, 1.0f) * speed_scale;
5299 CLAMP(w_factor, 0.0f, 1.0f);
5328 const float eff_scale =
data->eff_scale;
5334 for (
int i = 0;
i < numOfNeighs;
i++) {
5335 const int n_idx = n_index[index] +
i;
5336 const float speed_scale = (bNeighs[n_idx].
dist < eff_scale) ? 1.0f :
5337 eff_scale / bNeighs[n_idx].
dist;
5338 const PaintPoint *pPoint_prev = &prevPoint[n_target[n_idx]];
5339 float a_factor, ea_factor, w_factor;
5348 a_factor =
max_ff((1.0f - pPoint_prev->
color[3]) / numOfNeighs *
5349 (pPoint->
color[3] - pPoint_prev->
color[3]) * speed_scale,
5360 pPoint->
color[3] -= a_factor;
5362 pPoint->
e_color[3] -= ea_factor;
5385 const PaintPoint *pPoint_prev = &prevPoint[index];
5386 const float *force =
data->force;
5387 const float eff_scale =
data->eff_scale;
5391 uint8_t *point_locks =
data->point_locks;
5397 float w_factor = pPoint_prev->
wetness - 0.025f;
5398 if (w_factor <= 0) {
5401 CLAMP(w_factor, 0.0f, 1.0f);
5403 float ppoint_wetness_diff = 0.0f;
5409 for (
int i = 0;
i < 2;
i++) {
5410 const int n_idx = closest_id[
i];
5411 if (n_idx != -1 && closest_d[
i] > 0.0f) {
5412 const float dir_dot = closest_d[
i];
5415 if (dir_dot <= 0.0f) {
5419 float dir_factor, a_factor;
5420 const float speed_scale = eff_scale * force[index * 4 + 3] / bNeighs[n_idx].
dist;
5422 const uint n_trgt =
uint(n_target[n_idx]);
5427 const uint epointlock_idx = n_trgt / 8;
5428 const uint8_t epointlock_bitmask = 1 << (n_trgt & 7);
5436 const float e_wet = ePoint->
wetness;
5438 dir_factor =
min_ff(0.5f, dir_dot *
min_ff(speed_scale, 1.0f) * w_factor);
5441 ePoint->
wetness += dir_factor;
5445 a_factor = dir_factor / pPoint_prev->
wetness;
5446 CLAMP(a_factor, 0.0f, 1.0f);
5460 ppoint_wetness_diff += (ePoint->
wetness - e_wet);
5465 ~epointlock_bitmask);
5475 const uint ppointlock_idx = index / 8;
5476 const uint8_t ppointlock_bitmask = 1 << (index & 7);
5483 pPoint->
wetness -= ppoint_wetness_diff;
5526 data.surface = surface;
5527 data.prevPoint = prevPoint;
5528 data.eff_scale = eff_scale;
5548 data.surface = surface;
5549 data.prevPoint = prevPoint;
5550 data.eff_scale = eff_scale;
5566 const size_t point_locks_size = (sData->
total_points / 8) + 1;
5573 data.surface = surface;
5574 data.prevPoint = prevPoint;
5575 data.eff_scale = eff_scale;
5577 data.point_locks = point_locks;
5607 float mix_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5608 float mix_e_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5609 float mix_wetness = 0.0f;
5611 for (
int i = 0;
i < numOfNeighs;
i++) {
5612 const int n_idx = n_index[index] +
i;
5613 const int target = n_target[n_idx];
5620 mix_color[3] += pPoint2->
color[3];
5623 mix_e_color[3] += pPoint2->
e_color[3];
5625 mix_wetness += pPoint2->
wetness;
5628 const float divisor = 1.0f / numOfNeighs;
5631 pPoint->
color[3] = mix_color[3] * divisor;
5635 pPoint->
color[3] = 0.0f;
5638 if (mix_e_color[3]) {
5639 pPoint->
e_color[3] = mix_e_color[3] * divisor;
5646 pPoint->
wetness = mix_wetness / numOfNeighs;
5659 data.surface = surface;
5679 const float wave_speed =
data->wave_speed;
5680 const float wave_scale =
data->wave_scale;
5681 const float wave_max_slope =
data->wave_max_slope;
5683 const float dt =
data->dt;
5684 const float min_dist =
data->min_dist;
5685 const float damp_factor =
data->damp_factor;
5689 float force = 0.0f, avg_dist = 0.0f, avg_height = 0.0f, avg_n_height = 0.0f;
5690 int numOfN = 0, numOfRN = 0;
5692 if (wPoint->
state > 0) {
5701 for (
int i = 0;
i < numOfNeighs;
i++) {
5702 const int n_idx = n_index[index] +
i;
5703 float dist = bNeighs[n_idx].
dist * wave_scale;
5706 if (!dist || tPoint->
state > 0) {
5716 avg_n_height += tPoint->
height;
5720 force += (tPoint->
height - wPoint->
height) / (dist * dist);
5721 avg_height += tPoint->
height;
5723 avg_dist = (numOfN) ? avg_dist / numOfN : 0.0f;
5727 avg_n_height = (numOfRN) ? avg_n_height / numOfRN : 0.0f;
5728 wPoint->
height = (dt * wave_speed * avg_n_height + wPoint->
height * avg_dist) /
5729 (avg_dist + dt * wave_speed);
5735 force += (0.0f - wPoint->
height) * surface->
wave_spring / (avg_dist * avg_dist) / 2.0f;
5739 wPoint->
velocity += force * dt * wave_speed * wave_speed;
5746 if (wave_max_slope && avg_dist) {
5747 const float max_offset = wave_max_slope * avg_dist;
5748 const float offset = (numOfN) ? (avg_height / numOfN - wPoint->
height) : 0.0f;
5749 if (offset > max_offset) {
5750 wPoint->
height += offset - max_offset;
5752 else if (offset < -max_offset) {
5753 wPoint->
height += offset + max_offset;
5758 if (
data->reset_wave) {
5773 float dt, min_dist, damp_factor;
5774 const float wave_speed = surface->
wave_speed;
5778 double average_dist = 0.0f;
5790 for (index = 0; index < sData->
total_points; index++) {
5793 for (
int i = 0;
i < numOfNeighs;
i++) {
5801 (average_dist /
double(wave_speed) / 3)));
5802 CLAMP(steps, 1, 20);
5807 min_dist = wave_speed * dt * 1.5f;
5810 for (ss = 0; ss < steps; ss++) {
5815 data.surface = surface;
5816 data.prevPoint = prevPoint;
5817 data.wave_speed = wave_speed;
5818 data.wave_scale = wave_scale;
5819 data.wave_max_slope = wave_max_slope;
5821 data.min_dist = min_dist;
5822 data.damp_factor = damp_factor;
5823 data.reset_wave = (ss == steps - 1);
5857 const float timescale =
data->timescale;
5866 float p_wetness = pPoint->
wetness;
5875 float dry_ratio = pPoint->
wetness / p_wetness;
5888 pPoint->
e_color[3] *= dry_ratio;
5894 if (pPoint->
color[3]) {
5895 for (
int i = 0;
i < 3;
i++) {
5896 pPoint->
color[
i] = (f_color[
i] * f_color[3] -
5906 else if (pPoint->
state > 0) {
5935 float *point = &((
float *)sData->
type_data)[index];
5950 int numOfVerts =
mesh->verts_num;
5962 for (
int i = 0;
i < numOfVerts;
i++) {
5998 const Vec3f *canvas_verts =
data->canvas_verts;
6000 const bool do_velocity_data =
data->do_velocity_data;
6001 const bool new_bdata =
data->new_bdata;
6003 float prev_point[3] = {0.0f, 0.0f, 0.0f};
6006 if (do_velocity_data && !new_bdata) {
6014 float n1[3], n2[3], n3[3];
6019 bData->
s_pos[index] = index * bData->
s_num[index];
6022 for (
int ss = 0; ss < bData->
s_num[index]; ss++) {
6024 canvas_verts[tPoint->
v1].
v,
6025 canvas_verts[tPoint->
v2].
v,
6026 canvas_verts[tPoint->
v3].
v,
6041 float scaled_nor[3];
6052 bData->
s_num[index] = adj_data->
n_num[index] + 1;
6053 bData->
s_pos[index] = adj_data->
n_index[index] + index;
6056 bData->
s_num[index] = 1;
6057 bData->
s_pos[index] = index;
6061 for (ss = 0; ss < bData->
s_num[index]; ss++) {
6065 int t_index = adj_data->
n_index[index] + (ss - 1);
6069 canvas_verts[adj_data->
n_target[t_index]].
v,
6079 float scaled_nor[3];
6089 if (do_velocity_data && !new_bdata && !bData->
clear) {
6102 bool new_bdata =
false;
6108 int canvasNumOfVerts =
mesh->verts_num;
6110 Vec3f *canvas_verts;
6121 if (do_velocity_data && bData->
velocity && (bData->
clear || !surface_moved)) {
6126 if (!surface_moved) {
6132 "Dynamic Paint transformed canvas verts");
6133 if (!canvas_verts) {
6149 "Dynamic Paint step data");
6151 "Dynamic Paint bData s_pos");
6153 "Dynamic Paint bData s_num");
6155 "Dynamic Paint point coords");
6157 "Dynamic Paint bData prev_positions");
6183 if (do_velocity_data && !bData->
velocity) {
6188 "Dynamic Paint prev velocity");
6199 for (index = 0; index < canvasNumOfVerts; index++) {
6200 copy_v3_v3(canvas_verts[index].
v, positions[index]);
6201 mul_m4_v3(ob->object_to_world().ptr(), canvas_verts[index].
v);
6209 data.surface = surface;
6211 data.positions = positions;
6212 data.vert_normals =
mesh->vert_normals();
6213 data.canvas_verts = canvas_verts;
6214 data.do_velocity_data = do_velocity_data;
6215 data.new_bdata = new_bdata;
6232 memcpy(bData->
prev_positions, positions.
data(), canvasNumOfVerts *
sizeof(
float[3]));
6261 data.surface = surface;
6262 data.timescale = timescale;
6280 int scene_frame = scene->
r.
cfra;
6281 float scene_subframe = scene->
r.
subframe;
6283 for (
int i = 0;
i < numobjects;
i++) {
6284 Object *brushObj = objects[
i];
6297 "Dynamic Paint brush velocity");
6344 else if (brushObj != ob) {
6350 scene->
r.
cfra = scene_frame;
6388 float *force =
nullptr;
6392 "PaintSurfaceDataCopy");
6394 return setError(canvas,
N_(
"Not enough free memory"));
6399 for (s = 0; s < steps; s++) {
6424 float timescale = 1.0f;
6437 timescale = 1.0f / (surface->
substeps + 1);
6439 for (st = 1; st <= surface->
substeps; st++) {
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_validate_layer_name(const CustomData *data, eCustomDataType type, blender::StringRef name, char *outname)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
#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 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)
MINLINE void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
MINLINE void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[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_DEBUG(clg_ref,...)
#define CLOG_WARN(clg_ref,...)
#define CLOG_STR_ERROR(clg_ref, str)
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
#define MAX_CUSTOMDATA_LAYER_NAME
@ MOD_DPAINT_INITIAL_NONE
@ MOD_DPAINT_INITIAL_VERTEXCOLOR
@ MOD_DPAINT_INITIAL_COLOR
@ MOD_DPAINT_INITIAL_TEXTURE
@ 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_WAVE_OPEN_BORDERS
@ MOD_DPAINT_DISP_INCREMENTAL
@ MOD_DPAINT_DISSOLVE_LOG
@ MOD_DPAINT_DISP_DISPLACE
@ MOD_DPAINT_WAVEB_REFLECT
@ MOD_DPAINT_WAVEB_CHANGE
@ MOD_DPAINT_RAY_BRUSH_AVG
@ MOD_DPAINT_PRFALL_CONSTANT
@ MOD_DPAINT_PRFALL_SMOOTH
@ MOD_DPAINT_EFFECT_DO_DRIP
@ MOD_DPAINT_EFFECT_DO_SPREAD
@ MOD_DPAINT_EFFECT_DO_SHRINK
@ MOD_DPAINT_SURFACE_T_WEIGHT
@ MOD_DPAINT_SURFACE_T_PAINT
@ MOD_DPAINT_SURFACE_T_DISPLACE
@ MOD_DPAINT_SURFACE_T_WAVE
@ MOD_DPAINT_IMGFORMAT_OPENEXR
@ MOD_DPAINT_IMGFORMAT_PNG
@ MOD_DPAINT_SURFACE_F_PTEX
@ MOD_DPAINT_SURFACE_F_VERTEX
@ MOD_DPAINT_SURFACE_F_IMAGESEQ
@ eModifierFlag_SharedCaches
@ MOD_DYNAMICPAINT_TYPE_BRUSH
@ MOD_DYNAMICPAINT_TYPE_CANVAS
@ eModifierType_DynamicPaint
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 bool is_empty() const
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 bool is_empty() const
GAttributeReader lookup(const StringRef attribute_id) const
std::optional< AttributeMetaData > lookup_meta_data(StringRef attribute_id) const
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, AttrType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
GSpanAttributeWriter lookup_for_write_span(StringRef attribute_id)
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 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)
static float dist_squared_to_corner_tris_uv_edges(const blender::Span< int3 > corner_tris, const blender::Span< blender::float2 > uv_map, int tri_index, const float point[2])
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
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
ColorSceneLinearByteEncoded4b< eAlpha::Premultiplied > ColorGeometry4b
struct ColorBand * vel_ramp
struct DynamicPaintModifierData * pmd
struct ColorBand * paint_ramp
const float(* positions_c)[3]
const float(* positions_p)[3]
struct DynamicPaintModifierData * pmd
blender::Span< blender::float2 > uv_map
blender::Span< int3 > corner_tris
blender::Span< int > corner_verts
PaintUVPoint * tempPoints
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::MutableSpan< blender::ColorGeometry4b > mloopcol_wet
blender::MutableSpan< blender::ColorGeometry4b > mloopcol
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
blender::Span< blender::ColorGeometry4b > mloopcol
blender::Span< blender::float2 > uv_map
const DynamicPaintSurface * surface
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
MutableVArraySpan< T > span
int multitex_ext_safe(Tex *tex, const float texvec[3], TexResult *texres, ImagePool *pool, bool scene_color_manage, const bool skip_load_image)