98static int neighX[8] = {1, 1, 0, -1, -1, -1, 0, 1};
99static int neighY[8] = {0, 1, 1, 1, 0, -1, -1, -1};
106#define SUBFRAME_RECURSION 5
108#define BRUSH_USES_VELOCITY (1 << 0)
111#define HIT_PROXIMITY 2
114#define ON_MESH_EDGE -2
115#define OUT_OF_TEXTURE -3
117#define EFF_MOVEMENT_PER_FRAME 0.05f
119#define WAVE_TIME_FAC (1.0f / 24.0f)
120#define CANVAS_REL_SIZE 5.0f
122#define MIN_WETNESS 0.001f
123#define MAX_WETNESS 5.0f
131 *r_value = (is_log) ? (*r_value) *
powf(
MIN_WETNESS, 1.0f / (1.2f * time / scale)) :
132 (*r_value) - 1.0f / time * scale;
237#define ADJ_ON_MESH_EDGE (1 << 0)
238#define ADJ_BORDER_PIXEL (1 << 1)
261 if (runtime_data ==
nullptr) {
318 return (canvas_mesh) ? canvas_mesh->
verts_num : 0;
363 for (; surface; surface = surface->
next) {
364 if (surface != t_surface && surface->
type == t_surface->
type &&
405 for (; surface; surface = surface->
next) {
406 if (surface != t_surface &&
STREQ(name, surface->
name)) {
423 const char *name_prefix =
"";
424 const char *name_suffix_1 =
"";
425 const char *name_suffix_2 =
"";
440 name_suffix_1 =
"paintmap";
441 name_suffix_2 =
"wetmap";
444 name_suffix_1 = name_suffix_2 =
"displace";
447 name_suffix_1 = name_suffix_2 =
"weight";
450 name_suffix_1 = name_suffix_2 =
"wave";
458 if (!output_name_equal) {
479 const float s_color[3],
484 float i_alpha = 1.0f - s_alpha;
485 float f_alpha = t_alpha * i_alpha + s_alpha;
489 for (
int i = 0; i < 3; i++) {
490 result[i] = (t_color[i] * t_alpha * i_alpha + s_color[i] * s_alpha) / f_alpha;
502 float a_color[3],
float a_weight,
const float b_color[3],
float b_weight,
float ratio)
504 float weight_ratio, factor;
509 return b_weight * ratio;
511 weight_ratio = b_weight / (a_weight + b_weight);
514 return a_weight * (1.0f - ratio);
519 factor = weight_ratio * (ratio * 2.0f);
522 ratio = (ratio * 2.0f - 1.0f);
523 factor = weight_ratio * (1.0f - ratio) + ratio;
527 return (1.0f - factor) * a_weight + factor * b_weight;
545 for (
int i = 0; i < numobjects; i++) {
546 Object *brushObj = objects[i];
573 for (
int i = 2; i--;) {
574 if (!(b1->
min[i] <= b2->
max[i] && b1->
max[i] >= b2->
min[i])) {
587 for (
int i = 2; i--;) {
588 if (!(b1->
min[i] <= (b2->
max[i] + dist) && b1->
max[i] >= (b2->
min[i] - dist))) {
601 for (
int i = 2; i--;) {
602 if (!(
b->min[i] <= (
point[i] + radius) &&
b->max[i] >= (
point[i] - radius))) {
647 bData->
grid =
nullptr;
662 void *__restrict chunk_join,
663 void *__restrict chunk)
679 int *s_num =
static_cast<int *
>(tls->userdata_chunk);
683 for (
int j = 3; j--;) {
685 bData->
dim[j] * grid->
dim[j]));
689 temp_t_index[i] = co[0] + co[1] * grid->
dim[0] + co[2] * grid->
dim[0] * grid->
dim[1];
690 s_num[temp_t_index[i]]++;
694 void *__restrict chunk_join,
695 void *__restrict chunk)
699 const int grid_cells = grid->
dim[0] * grid->
dim[1] * grid->
dim[2];
701 int *join_s_num =
static_cast<int *
>(chunk_join);
702 int *s_num =
static_cast<int *
>(chunk);
705 for (
int i = 0; i < grid_cells; i++) {
706 join_s_num[i] += s_num[i];
716 float *dim = bData->
dim;
717 int *grid_dim = grid->
dim;
719 for (
int y = 0;
y < grid_dim[1];
y++) {
720 for (
int z = 0;
z < grid_dim[2];
z++) {
721 const int b_index =
x +
y * grid_dim[0] +
z * grid_dim[0] * grid_dim[1];
723 for (
int j = 3; j--;) {
724 const int s = (j == 0) ?
x : ((j == 1) ?
y :
z);
738 int grid_cells, axis = 3;
739 int *temp_t_index =
nullptr;
740 int *temp_s_num =
nullptr;
746 bData->
grid = MEM_cnew<DynamicPaintVolumeGrid>(__func__);
751 float dim_factor, volume, dim[3];
771 min_dim =
max_fff(td[0], td[1], td[2]) / 1000.0f;
774 for (i = 0; i < 3; i++) {
775 if (td[i] < min_dim) {
781 if (axis == 0 ||
max_fff(td[0], td[1], td[2]) < 0.0001f) {
783 bData->
grid =
nullptr;
788 volume = td[0] * td[1] * td[2];
792 pow(
double(volume) / (
double(sData->
total_points) / 10000.0), 1.0 /
double(axis)));
795 for (i = 0; i < 3; i++) {
797 CLAMP(grid->
dim[i], (dim[i] >= min_dim) ? 3 : 1, 100);
799 grid_cells = grid->
dim[0] * grid->
dim[1] * grid->
dim[2];
804 grid->
s_pos =
static_cast<int *
>(
805 MEM_callocN(
sizeof(
int) * grid_cells,
"Surface Grid Position"));
807 grid->
s_num =
static_cast<int *
>(
MEM_callocN(
sizeof(
int) * grid_cells,
"Surface Grid Points"));
808 temp_s_num =
static_cast<int *
>(
809 MEM_callocN(
sizeof(
int) * grid_cells,
"Temp Surface Grid Points"));
810 grid->
t_index =
static_cast<int *
>(
835 for (i = 1; i < grid_cells; i++) {
841 int pos = grid->
s_pos[temp_t_index[i]] + temp_s_num[temp_t_index[i]];
844 temp_s_num[temp_t_index[i]]++;
881 pmd->
brush =
nullptr;
887 if (
data->adj_data) {
888 if (
data->adj_data->n_index) {
891 if (
data->adj_data->n_num) {
894 if (
data->adj_data->n_target) {
897 if (
data->adj_data->flags) {
900 if (
data->adj_data->border) {
904 data->adj_data =
nullptr;
941 data->bData =
nullptr;
948 if (!surface->
data) {
967 if (
data->format_data) {
971 if (format_data->
uv_p) {
981 if (
data->type_data) {
989 surface->
data =
nullptr;
1015 next_surface = surface->
next;
1017 surface = next_surface;
1027 if (pmd ==
nullptr) {
1045 surface->
canvas = canvas;
1123 canvas = pmd->
canvas = MEM_cnew<DynamicPaintCanvasSettings>(__func__);
1140 brush = pmd->
brush = MEM_cnew<DynamicPaintBrushSettings>(__func__);
1146 brush->
psys =
nullptr;
1154 brush->
alpha = 1.0f;
1179 ramp[0].
r = ramp[0].
g = ramp[0].
b = ramp[0].
a = 1.0f;
1181 ramp[1].
r = ramp[1].
g = ramp[1].
b = ramp[1].
pos = 1.0f;
1195 ramp[0].
r = ramp[0].
g = ramp[0].
b = ramp[0].
a = ramp[0].
pos = 0.0f;
1196 ramp[1].
r = ramp[1].
g = ramp[1].
b = ramp[1].
a = ramp[1].
pos = 1.0f;
1235 surface = surface->
next)
1301 t_brush->
pmd = tpmd;
1303 t_brush->flags = brush->
flags;
1306 t_brush->r = brush->
r;
1307 t_brush->g = brush->
g;
1308 t_brush->b = brush->
b;
1309 t_brush->alpha = brush->
alpha;
1310 t_brush->wetness = brush->
wetness;
1319 t_brush->psys = brush->
psys;
1330 t_brush->ray_dir = brush->
ray_dir;
1344 switch (surface->
type) {
1347 "DynamicPaintSurface Data");
1351 "DynamicPaintSurface DepthData");
1355 "DynamicPaintSurface WeightData");
1359 "DynamicPaintSurface WaveData");
1387 int neigh_points = 0;
1401 if (!neigh_points) {
1406 ad = sData->
adj_data = MEM_cnew<PaintAdjData>(__func__);
1410 ad->
n_index =
static_cast<int *
>(
1412 ad->
n_num =
static_cast<int *
>(
1416 MEM_callocN(
sizeof(
int) * neigh_points,
"Surface Adj Targets"));
1417 ad->
flags =
static_cast<int *
>(
1442 for (
int i = 0; i < numOfEdges; i++) {
1443 ad->
n_num[edges[i][0]]++;
1444 ad->
n_num[edges[i][1]]++;
1446 temp_data[edges[i][0]]++;
1447 temp_data[edges[i][1]]++;
1452 for (
int i = 0; i < numOfPolys; i++) {
1453 for (
const int vert : corner_verts.
slice(
faces[i])) {
1461 if ((temp_data[i] % 2) || (temp_data[i] < 4)) {
1473 n_pos += ad->
n_num[i];
1477 for (
int i = 0; i < numOfEdges; i++) {
1479 int index = edges[i][0];
1480 n_pos = ad->
n_index[index] + temp_data[index];
1485 index = edges[i][1];
1486 n_pos = ad->
n_index[index] + temp_data[index];
1520 const float(*mloopuv)[2] =
data->mloopuv;
1522 Tex *tex =
data->surface->init_texture;
1524 float uv[3] = {0.0f};
1526 for (
int j = 3; j--;) {
1528 const int vert = corner_verts[corner_tris[i][j]];
1531 uv[0] = mloopuv[corner_tris[i][j]][0] * 2.0f - 1.0f;
1532 uv[1] = mloopuv[corner_tris[i][j]][1] * 2.0f - 1.0f;
1536 if (texres.
tin > pPoint[vert].
color[3]) {
1538 pPoint[vert].
color[3] = texres.
tin;
1553 const float(*mloopuv)[2] =
data->mloopuv;
1554 Tex *tex =
data->surface->init_texture;
1558 float uv[9] = {0.0f};
1559 float uv_final[3] = {0.0f};
1564 for (
int j = 3; j--;) {
1571 uv_final[0] = uv_final[0] * 2.0f - 1.0f;
1572 uv_final[1] = uv_final[1] * 2.0f - 1.0f;
1582 void *__restrict userdata,
const int i,
const TaskParallelTLS *__restrict )
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) {
1769 surface->
data = MEM_cnew<PaintSurfaceData>(__func__);
1770 if (!surface->
data) {
1823 const float val = value[i] * surface->
disp_factor;
1840 data.surface = surface;
1841 data.vert_positions =
result->vert_positions_for_write();
1864 pPoint[i].
color, pPoint[i].
color[3], pPoint[i].e_color, pPoint[i].e_color[3], fcolor[i]);
1883 for (
const int l_index :
data->faces[p_index]) {
1884 const int v_index = corner_verts[l_index];
1894 mloopcol_wet[l_index].
r = c;
1895 mloopcol_wet[l_index].
g = c;
1896 mloopcol_wet[l_index].
b = c;
1897 mloopcol_wet[l_index].
a = 255;
1929 surface = surface->
next)
1947 float(*fcolor)[4] =
static_cast<float(*)[4]
>(
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();
2115 for (; surface; surface = surface->
next) {
2116 int current_frame =
int(scene->
r.
cfra);
2117 bool no_surface_data;
2130 no_surface_data = surface->
data ==
nullptr;
2138 if (no_surface_data || current_frame != surface->
current_frame ||
2159 bool can_simulate = (
int(scene->
r.
cfra) == current_frame) &&
2166 else if (can_simulate) {
2202#define JITTER_SAMPLES \
2204 0.0f, 0.0f, -0.2f, -0.4f, 0.2f, 0.4f, 0.4f, -0.2f, -0.4f, 0.3f, \
2233 const float(*mloopuv)[2] =
data->mloopuv;
2243 for (
int tx = 0; tx <
w; tx++) {
2244 const int index = tx +
w * ty;
2286 const float *uv1 = mloopuv[corner_tris[i][0]];
2287 const float *uv2 = mloopuv[corner_tris[i][1]];
2288 const float *uv3 = mloopuv[corner_tris[i][2]];
2295 for (
int j = 0; j < aa_samples; j++) {
2296 uv[0] =
point[0][0] + jitter5sample[j * 2] /
w;
2297 uv[1] =
point[0][1] + jitter5sample[j * 2 + 1] / h;
2306 tPoint->
v1 = corner_verts[corner_tris[i][0]];
2307 tPoint->
v2 = corner_verts[corner_tris[i][1]];
2308 tPoint->
v3 = corner_verts[corner_tris[i][2]];
2330 const float(*mloopuv)[2] =
data->mloopuv;
2340 for (
int tx = 0; tx <
w; tx++) {
2341 const int index = tx +
w * ty;
2349 const int u_min = (tx > 0) ? -1 : 0;
2350 const int u_max = (tx < (
w - 1)) ? 1 : 0;
2351 const int v_min = (ty > 0) ? -1 : 0;
2352 const int v_max = (ty < (h - 1)) ? 1 : 0;
2358 for (
int ni = 0; ni < 8; ni++) {
2362 if (u >= u_min && u <= u_max && v >= v_min &&
v <= v_max) {
2364 if (u != 0 ||
v != 0) {
2365 const int ind = (tx + u) +
w * (ty +
v);
2368 if (tempPoints[ind].neighbor_pixel == -1 && tempPoints[ind].tri_index != -1) {
2370 const int i = tempPoints[ind].
tri_index;
2371 const float *uv1 = mloopuv[corner_tris[i][0]];
2372 const float *uv2 = mloopuv[corner_tris[i][1]];
2373 const float *uv3 = mloopuv[corner_tris[i][2]];
2389 for (
int j = 0; j < aa_samples; j++) {
2390 uv[0] =
point[0] + jitter5sample[j * 2] /
w;
2391 uv[1] =
point[1] + jitter5sample[j * 2 + 1] / h;
2396 tPoint->
v1 = corner_verts[corner_tris[i][0]];
2397 tPoint->
v2 = corner_verts[corner_tris[i][1]];
2398 tPoint->
v3 = corner_verts[corner_tris[i][2]];
2414#undef JITTER_SAMPLES
2417 const float (*mloopuv)[2],
2419 const float point[2])
2425 for (
int i = 0; i < 3; i++) {
2428 mloopuv[corner_tris[tri_index][(i + 0)]],
2429 mloopuv[corner_tris[tri_index][(i + 1) % 3]]);
2431 if (dist_squared < min_distance) {
2432 min_distance = dist_squared;
2436 return min_distance;
2450 const float pixel[2],
2474 const int x = px +
neighX[n_index];
2475 const int y = py +
neighY[n_index];
2522 pixel[0] = (
float(px +
neighX[n_index]) + 0.5f) /
float(
w);
2523 pixel[1] = (
float(py +
neighY[n_index]) + 0.5f) /
float(h);
2535 const float pixel[2],
2541 const float(*mloopuv)[2] =
data->mloopuv;
2543 const int3 loop_idx = corner_tris[tri_index];
2546 for (
int edge_idx = 0; edge_idx < 3; edge_idx++) {
2548 if (edge_idx == in_edge) {
2552 float uv0[2], uv1[2], uv2[2];
2554 copy_v2_v2(uv0, mloopuv[loop_idx[(edge_idx + 0)]]);
2555 copy_v2_v2(uv1, mloopuv[loop_idx[(edge_idx + 1) % 3]]);
2556 copy_v2_v2(uv2, mloopuv[loop_idx[(edge_idx + 2) % 3]]);
2563 if (side2 == 0.0f) {
2568 const bool correct_side = (in_edge == -1) || (sidep < 0 && side2 > 0) ||
2569 (sidep > 0 && side2 < 0);
2572 if (!correct_side && sidep != 0.0f) {
2577 const int vert0 = corner_verts[loop_idx[(edge_idx + 0)]];
2578 const int vert1 = corner_verts[loop_idx[(edge_idx + 1) % 3]];
2584 bool found_other =
false;
2585 int target_tri = -1;
2586 int target_edge = -1;
2588 float ouv0[2], ouv1[2];
2590 for (
int i = 0; i < map->count && !found_other; i++) {
2591 const int tri_other_index = map->indices[i];
2593 if (tri_other_index == tri_index) {
2597 const int3 other_tri = corner_tris[tri_other_index];
2600 for (
int j = 0; j < 3; j++) {
2601 const int overt0 = corner_verts[other_tri[(j + 0)]];
2602 const int overt1 = corner_verts[other_tri[(j + 1) % 3]];
2605 if (overt0 == vert0 && overt1 == vert1) {
2607 copy_v2_v2(ouv0, mloopuv[other_tri[(j + 0)]]);
2608 copy_v2_v2(ouv1, mloopuv[other_tri[(j + 1) % 3]]);
2610 else if (overt0 == vert1 && overt1 == vert0) {
2612 copy_v2_v2(ouv1, mloopuv[other_tri[(j + 0)]]);
2613 copy_v2_v2(ouv0, mloopuv[other_tri[(j + 1) % 3]]);
2617 target_tri = tri_other_index;
2634 if (depth > 0 && correct_side) {
2653 float closest_point[2], dir_vec[2], tgt_pixel[2];
2656 CLAMP(lambda, 0.0f, 1.0f);
2661 int w = bdata->
w, h = bdata->
h, px = bdata->
px, py = bdata->
py;
2663 const int final_pixel[2] = {
int(
floorf(tgt_pixel[0] *
w)),
int(
floorf(tgt_pixel[1] * h))};
2666 if (final_pixel[0] < 0 || final_pixel[0] >=
w || final_pixel[1] < 0 || final_pixel[1] >= h) {
2675 int final_index = final_pixel[0] +
w * final_pixel[1];
2678 if (final_index == (px +
w * py)) {
2683 if (tempPoints[final_index].neighbor_pixel != -1) {
2687 if (final_index == (px +
w * py)) {
2692 const int final_tri_index = tempPoints[final_index].
tri_index;
2694 if (!
ELEM(final_tri_index, target_tri, -1)) {
2697 const float final_pt[2] = {((final_index %
w) + 0.5f) /
w, ((final_index /
w) + 0.5f) / h};
2698 const float threshold =
square_f(0.7f) / (
w * h);
2714 const int idx = ed->
n_index[index];
2716 for (
int i = 0; i < ed->
n_num[index]; i++) {
2717 if (ed->
n_target[idx + i] == neighbor) {
2729 int *new_n_index =
static_cast<int *
>(
2730 MEM_callocN(
sizeof(
int) * active_points,
"Surface Adj Index"));
2731 int *new_n_num =
static_cast<int *
>(
2732 MEM_callocN(
sizeof(
int) * active_points,
"Surface Adj Counts"));
2734 if (new_n_num && new_n_index) {
2736 int total_targets = 0;
2738 for (
int index = 0; index < active_points; index++) {
2739 total_targets += ed->
n_num[index];
2740 new_n_num[index] = ed->
n_num[index];
2743 for (
int index = 0; index < active_points; index++) {
2748 for (
int i = 0, idx = ed->
n_index[index]; i < ed->n_num[index]; i++) {
2749 const int target = ed->
n_target[idx + i];
2754 new_n_num[target]++;
2761 int *new_n_target =
static_cast<int *
>(
2762 MEM_callocN(
sizeof(
int) * total_targets,
"Surface Adj Targets"));
2768 for (
int index = 0; index < active_points; index++) {
2769 new_n_index[index] = n_pos;
2770 memcpy(&new_n_target[n_pos],
2772 sizeof(
int) * ed->
n_num[index]);
2775 n_pos += new_n_num[index];
2776 new_n_num[index] = ed->
n_num[index];
2782 for (
int index = 0; index < active_points; index++) {
2787 for (
int i = 0, idx = ed->
n_index[index]; i < ed->n_num[index]; i++) {
2788 const int target = ed->
n_target[idx + i];
2791 const int num = new_n_num[target]++;
2792 new_n_target[new_n_index[target] + num] = index;
2805 ed->
n_num = new_n_num;
2838 Vec3f *tempWeights =
nullptr;
2839 const float(*mloopuv)[2] =
nullptr;
2848 return setError(canvas,
N_(
"Canvas mesh not updated"));
2851 return setError(canvas,
N_(
"Cannot bake non-'image sequence' formats"));
2861 mloopuv =
static_cast<const float(*)[2]
>(
2867 return setError(canvas,
N_(
"No UV data on canvas"));
2870 return setError(canvas,
N_(
"Invalid resolution"));
2880 &
LOG, 1,
"Preparing UV surface of %ix%i pixels and %i tris.",
w, h,
int(corner_tris.
size()));
2883 if (surface->
data) {
2886 sData = surface->
data = MEM_cnew<PaintSurfaceData>(__func__);
2887 if (!surface->
data) {
2888 return setError(canvas,
N_(
"Not enough free memory"));
2892 MEM_callocN(
w * h *
sizeof(*tempPoints),
"Temp PaintUVPoint"));
2897 final_index =
static_cast<int *
>(
2898 MEM_callocN(
w * h *
sizeof(*final_index),
"Temp UV Final Indexes"));
2903 tempWeights =
static_cast<Vec3f *
>(
2904 MEM_mallocN(
w * h * aa_samples *
sizeof(*tempWeights),
"Temp bWeights"));
2929 for (
int j = 1; j < 3; j++) {
2939 data.surface = surface;
2940 data.tempPoints = tempPoints;
2941 data.tempWeights = tempWeights;
2942 data.corner_tris = corner_tris;
2943 data.mloopuv = mloopuv;
2944 data.corner_verts = corner_verts;
2945 data.faceBB = faceBB;
2963 data.active_points = &active_points;
2980 for (
int i = 0; i <
w * h; i++) {
2981 if (tempPoints[i].tri_index != -1) {
2982 final_index[i] = cursor;
2995 int *vert_to_tri_map_mem;
2998 &vert_to_tri_map_mem,
3002 corner_verts.
data(),
3005 int total_border = 0;
3007 for (
int ty = 0; ty < h; ty++) {
3008 for (
int tx = 0; tx <
w; tx++) {
3009 const int index = tx +
w * ty;
3011 if (tempPoints[index].tri_index != -1) {
3012 ed->
n_index[final_index[index]] = n_pos;
3013 ed->
n_num[final_index[index]] = 0;
3015 if (tempPoints[index].neighbor_pixel != -1) {
3020 for (
int i = 0; i < 8; i++) {
3024 &
data, vert_to_tri_map,
w, h, tx, ty, i);
3026 if (n_target >= 0 && n_target != index) {
3028 ed, final_index[index], final_index[n_target]))
3030 ed->
n_target[n_pos] = final_index[n_target];
3031 ed->
n_num[final_index[index]]++;
3052 ed->
border =
static_cast<int *
>(
3053 MEM_callocN(
sizeof(
int) * total_border,
"Border Pixel Index"));
3058 for (
int i = 0,
next = 0; i < active_points; i++) {
3069 FILE *dump_file = fopen(
"dynpaint-adj-data.txt",
"w");
3070 int *tmp =
MEM_callocN(
sizeof(
int) * active_points,
"tmp");
3071 for (
int ty = 0; ty < h; ty++) {
3072 for (
int tx = 0; tx <
w; tx++) {
3073 const int index = tx +
w * ty;
3074 if (tempPoints[index].tri_index != -1) {
3075 tmp[final_index[index]] = index;
3079 for (
int ty = 0; ty < h; ty++) {
3080 for (
int tx = 0; tx <
w; tx++) {
3081 const int index = tx +
w * ty;
3082 const int fidx = final_index[index];
3084 if (tempPoints[index].tri_index != -1) {
3087 "%d\t%d,%d\t%u\t%d,%d\t%d\t",
3091 tempPoints[index].tri_index,
3092 nidx < 0 ? -1 : (nidx %
w),
3093 nidx < 0 ? -1 : h - 1 - (nidx /
w),
3095 for (
int i = 0; i < ed->
n_num[fidx]; i++) {
3097 fprintf(dump_file,
"%s%d,%d", i ?
" " :
"", tgt %
w, h - 1 - tgt /
w);
3099 fprintf(dump_file,
"\n");
3145 for (
int index = 0, cursor = 0; index < (
w * h); index++) {
3146 if (tempPoints[index].tri_index != -1) {
3149 &tempWeights[index * aa_samples],
3150 sizeof(*tempWeights) * aa_samples);
3157 setError(canvas,
N_(
"Not enough free memory"));
3181 for (index = 0; index < sData->
total_points; index++) {
3185 pPoint->alpha = 1.0f;
3189 pPoint->
color[2] = 1.0f;
3194 pPoint->
color[0] = 1.0f;
3206 return (
error == 0);
3245 void *__restrict userdata,
const int index,
const TaskParallelTLS *__restrict )
3262 depth = (0.5f - depth / 2.0f);
3265 CLAMP(depth, 0.0f, 1.0f);
3280 float depth = wPoint->
height;
3290 depth = (0.5f + depth / 2.0f);
3291 CLAMP(depth, 0.0f, 1.0f);
3316 const char *filepath,
3319 ImBuf *ibuf =
nullptr;
3336 STRNCPY(output_file, filepath);
3345 if (ibuf ==
nullptr) {
3346 setError(surface->
canvas,
N_(
"Image save failed: not enough free memory"));
3351 data.surface = surface;
3354 switch (surface->
type) {
3356 switch (output_layer) {
3385 switch (output_layer) {
3405 switch (output_layer) {
3464 const int3 *corner_tris =
data->corner_tris.data();
3465 const int *corner_verts =
data->corner_verts.data();
3467 const float *t0, *t1, *t2;
3470 t0 = positions[corner_verts[corner_tris[index][0]]];
3471 t1 = positions[corner_verts[corner_tris[index][1]]];
3472 t2 = positions[corner_verts[corner_tris[index][2]]];
3476 if (dist >= 0 && dist < hit->dist) {
3496 const int3 *corner_tris =
data->corner_tris.data();
3497 const int *corner_verts =
data->corner_verts.data();
3498 float nearest_tmp[3], dist_sq;
3500 const float *t0, *t1, *t2;
3501 t0 = positions[corner_verts[corner_tris[index][0]]];
3502 t1 = positions[corner_verts[corner_tris[index][1]]];
3503 t2 = positions[corner_verts[corner_tris[index][2]]];
3508 if (dist_sq < nearest->dist_sq) {
3509 nearest->
index = index;
3512 nearest->
no[0] = 0.0f;
3530 const int paintFlags,
3531 const float paintColor[3],
3532 const float paintAlpha,
3533 const float paintWetness,
3534 const float timescale)
3554 float wetness = paintWetness;
3555 CLAMP(wetness, 0.0f, 1.0f);
3566 float a_ratio, a_highest;
3568 float invFact = 1.0f - paintAlpha;
3576 if (a_highest > invFact) {
3577 a_ratio = invFact / a_highest;
3579 pPoint->
e_color[3] *= a_ratio;
3580 pPoint->
color[3] *= a_ratio;
3584 pPoint->
e_color[3] -= paintAlpha * timescale;
3586 pPoint->
color[3] -= paintAlpha * timescale;
3590 wetness = (1.0f - paintWetness) * pPoint->
e_color[3];
3600 const float isect_change = isect_height - wPoint->
brush_isect;
3608 isect_height *= wave_factor;
3611 if (wave_factor > 0.0f && wPoint->
height > isect_height) {
3614 else if (wave_factor < 0.0f && wPoint->height < isect_height) {
3621 wPoint->
height = isect_height;
3632 if (isect_change < 0.0f) {
3633 wPoint->
height += isect_change * wave_factor;
3653 const float timescale)
3662 strength = influence * brush->
alpha;
3663 CLAMP(strength, 0.0f, 1.0f);
3671 CLAMP(vel_factor, 0.0f, 1.0f);
3678 strength *= coba_res[3];
3681 depth *= coba_res[3];
3688 float paintWetness = brush->
wetness * strength;
3689 float paintAlpha = strength;
3692 surface, index, brush->
flags, paint, paintAlpha, paintWetness, timescale);
3696 float *value = (
float *)sData->
type_data;
3699 depth = value[index] + depth;
3707 value[index] *= (1.0f - strength);
3716 float *value = (
float *)sData->
type_data;
3719 value[index] *= (1.0f - strength);
3778 const float(*positions_p)[3] =
data->positions_p;
3779 const float(*positions_c)[3] =
data->positions_c;
3782 float(*prev_obmat)[4] =
data->prev_obmat;
3784 const float timescale =
data->timescale;
3805 float prev_obmat[4][4];
3806 Mesh *mesh_p, *mesh_c;
3807 int numOfVerts_p, numOfVerts_c;
3810 int cur_fra = scene->
r.
cfra;
3811 float prev_sfra = cur_sfra - timescale;
3812 int prev_fra = cur_fra;
3814 if (prev_sfra < 0.0f) {
3816 prev_fra = cur_fra - 1;
3820 scene->
r.
cfra = prev_fra;
3833 float(*positions_p)[3] =
reinterpret_cast<float(*)[3]
>(
3834 mesh_p->vert_positions_for_write().
data());
3835 copy_m4_m4(prev_obmat, ob->object_to_world().ptr());
3838 scene->
r.
cfra = cur_fra;
3850 float(*positions_c)[3] =
reinterpret_cast<float(*)[3]
>(
3851 mesh_c->vert_positions_for_write().
data());
3860 if (numOfVerts_p != numOfVerts_c) {
3861 positions_p = positions_c;
3866 data.brush_vel = *brushVel;
3867 data.positions_p = positions_p;
3868 data.positions_c = positions_c;
3869 data.obmat = ob->object_to_world().
ptr();
3870 data.prev_obmat = prev_obmat;
3871 data.timescale = timescale;
3886 float prev_obmat[4][4];
3887 float cur_loc[3] = {0.0f}, prev_loc[3] = {0.0f};
3890 int cur_fra = scene->
r.
cfra;
3891 float prev_sfra = cur_sfra - timescale;
3892 int prev_fra = cur_fra;
3894 if (prev_sfra < 0.0f) {
3896 prev_fra = cur_fra - 1;
3900 scene->
r.
cfra = prev_fra;
3909 copy_m4_m4(prev_obmat, ob->object_to_world().ptr());
3912 scene->
r.
cfra = cur_fra;
3924 mul_m4_v3(ob->object_to_world().ptr(), cur_loc);
3970 const float timescale =
data->timescale;
3971 const int c_index =
data->c_index;
3976 const float brush_radius =
data->brush_radius;
3977 const float *avg_brushNor =
data->avg_brushNor;
3978 const Vec3f *brushVelocity =
data->brushVelocity;
3982 const int index = grid->
t_index[grid->
s_pos[c_index] + id];
3983 const int samples = bData->
s_num[index];
3985 float total_sample =
float(samples);
3986 float brushStrength = 0.0f;
3988 float velocity_val = 0.0f;
3990 float paintColor[3] = {0.0f};
3999 for (ss = 0; ss < samples; ss++) {
4000 float ray_start[3], ray_dir[3];
4001 float sample_factor = 0.0f;
4002 float sampleStrength = 0.0f;
4005 short hit_found = 0;
4008 float volume_factor = 0.0f;
4010 float proximity_factor = 0.0f;
4011 float prox_colorband[4] = {0.0f};
4024 sample_factor = 1.0f;
4037 nearest.
dist_sq = brush_radius * brush_radius;
4043 if (hit.
index != -1) {
4047 const int vtri[3] = {
4048 corner_verts[corner_tris[hit.
index][0]],
4049 corner_verts[corner_tris[hit.
index][1]],
4050 corner_verts[corner_tris[hit.
index][2]],
4054 normal_tri_v3(hit.
no, positions[vtri[0]], positions[vtri[1]], positions[vtri[2]]);
4060 const float dist = hit.
dist;
4061 const int f_index = hit.
index;
4072 if (hit.
index != -1) {
4074 volume_factor = 1.0f;
4082 depth += dist * sample_factor;
4093 float proxDist = -1.0f;
4094 float hitCo[3] = {0.0f, 0.0f, 0.0f};
4098 if (inner_proximity && !hit_found) {
4106 if (nearest.
index != -1) {
4109 tri = nearest.
index;
4113 float proj_ray[3] = {0.0f};
4126 hit.
dist = brush_radius;
4131 if (hit.
index != -1) {
4132 proxDist = hit.
dist;
4142 if (proxDist >= 0.0f && proxDist <= brush_radius) {
4143 proximity_factor = proxDist / brush_radius;
4144 CLAMP(proximity_factor, 0.0f, 1.0f);
4145 if (!inner_proximity) {
4146 proximity_factor = 1.0f - proximity_factor;
4163 volume_factor = 1.0f - volume_factor;
4164 if (inner_proximity) {
4165 proximity_factor = 1.0f - proximity_factor;
4171 sampleStrength = volume_factor;
4178 proximity_factor = prox_colorband[3];
4185 sampleStrength = proximity_factor;
4188 sampleStrength *= sample_factor;
4197 float brushPointVelocity[3];
4200 const int v1 = corner_verts[corner_tris[hitTri][0]];
4201 const int v2 = corner_verts[corner_tris[hitTri][1]];
4202 const int v3 = corner_verts[corner_tris[hitTri][2]];
4212 brushVelocity[v1].
v,
4213 brushVelocity[
v2].
v,
4214 brushVelocity[v3].
v,
4239 float sampleColor[3];
4240 float alpha_factor = 1.0f;
4242 sampleColor[0] = brush->
r;
4243 sampleColor[1] = brush->
g;
4244 sampleColor[2] = brush->
b;
4249 sampleColor[0] = prox_colorband[0];
4250 sampleColor[1] = prox_colorband[1];
4251 sampleColor[2] = prox_colorband[2];
4256 paintColor[0] += sampleColor[0];
4257 paintColor[1] += sampleColor[1];
4258 paintColor[2] += sampleColor[2];
4259 sampleStrength *= alpha_factor;
4264 brushStrength += sampleStrength;
4268 if (brushStrength > 0.0f || depth > 0.0f) {
4271 brushStrength /= total_sample;
4273 CLAMP(brushStrength, 0.0f, 1.0f);
4277 paintColor[0] /= numOfHits;
4278 paintColor[1] /= numOfHits;
4279 paintColor[2] /= numOfHits;
4287 surface, index, brush, paintColor, brushStrength, depth, velocity_val, timescale);
4300 Mesh *mesh =
nullptr;
4301 Vec3f *brushVelocity =
nullptr;
4305 depsgraph, scene, brushOb, brush, &brushVelocity, timescale);
4309 if (brush_mesh ==
nullptr) {
4315 float avg_brushNor[3] = {0.0f};
4332 for (ii = 0; ii < numOfVerts; ii++) {
4333 mul_m4_v3(brushOb->object_to_world().ptr(), positions[ii]);
4348 mul_v3_fl(avg_brushNor, 1.0f /
float(numOfVerts));
4351 avg_brushNor[2] = 1.0f;
4360 int total_cells = grid->
dim[0] * grid->
dim[1] * grid->
dim[2];
4363 for (c_index = 0; c_index < total_cells; c_index++) {
4365 if (!grid->
s_num[c_index] ||
4373 data.surface = surface;
4375 data.brushOb = brushOb;
4377 data.timescale = timescale;
4378 data.c_index = c_index;
4380 data.positions = positions;
4381 data.corner_verts = corner_verts;
4382 data.corner_tris = corner_tris;
4383 data.brush_radius = brush_radius;
4384 data.avg_brushNor = avg_brushNor;
4385 data.brushVelocity = brushVelocity;
4386 data.treeData = &treeData;
4392 grid->
s_num[c_index],
4405 if (brushVelocity) {
4416 void *__restrict userdata,
const int id,
const TaskParallelTLS *__restrict )
4429 const float timescale =
data->timescale;
4430 const int c_index =
data->c_index;
4432 KDTree_3d *
tree =
static_cast<KDTree_3d *
>(
data->treeData);
4434 const float solidradius =
data->solidradius;
4436 const float range = solidradius +
smooth;
4437 const float particle_timestep = 0.04f * psys->
part->
timetweak;
4439 const int index = grid->
t_index[grid->
s_pos[c_index] + id];
4440 float disp_intersect = 0.0f;
4441 float radius = 0.0f;
4442 float strength = 0.0f;
4443 int part_index = -1;
4450 KDTreeNearest_3d nearest;
4451 float smooth_range, part_solidradius;
4456 if (nearest.dist > range) {
4463 part_solidradius = pa->
size;
4466 part_solidradius = solidradius;
4468 radius = part_solidradius +
smooth;
4469 if (nearest.dist < radius) {
4471 smooth_range =
max_ff(0.0f, (nearest.dist - part_solidradius));
4477 strength = 1.0f - smooth_range;
4478 disp_intersect = radius - nearest.dist;
4479 part_index = nearest.index;
4488 KDTreeNearest_3d *nearest;
4490 float smooth_range =
smooth * (1.0f - strength), dist;
4492 const float max_range =
smooth - strength *
smooth + solidradius;
4496 const int particles = BLI_kdtree_3d_range_search(
4500 for (
int n = 0; n < particles; n++) {
4509 const float s_range = nearest[n].dist - pa->
size;
4511 if (smooth_range < s_range) {
4516 smooth_range = s_range;
4517 dist = nearest[n].dist;
4518 part_index = nearest[n].index;
4521 if ((s_range < 0.0f) &&
4533 const float rad = radius +
smooth;
4534 if ((rad - dist) > disp_intersect) {
4535 disp_intersect = radius - dist;
4545 const float str = 1.0f - smooth_range;
4547 if (
str > strength) {
4552 if (strength > 0.001f) {
4553 float paintColor[4] = {0.0f};
4555 float velocity_val = 0.0f;
4583 disp_intersect = (1.0f -
sqrtf(disp_intersect / radius)) * radius;
4588 surface, index, brush, paintColor, strength, depth, velocity_val, timescale);
4603 int particlesAdded = 0;
4604 int invalidParticles = 0;
4612 const float range = solidradius +
smooth;
4637 if (isnan(pa->state.co[0]) || isnan(pa->state.co[1]) || isnan(pa->state.co[2])) {
4647 BLI_kdtree_3d_insert(
tree, p, pa->state.co);
4654 if (invalidParticles) {
4659 if (particlesAdded < 1) {
4660 BLI_kdtree_3d_free(
tree);
4667 int total_cells = grid->
dim[0] * grid->
dim[1] * grid->
dim[2];
4670 BLI_kdtree_3d_balance(
tree);
4673 for (c_index = 0; c_index < total_cells; c_index++) {
4681 data.surface = surface;
4684 data.solidradius = solidradius;
4685 data.timescale = timescale;
4686 data.c_index = c_index;
4693 grid->
s_num[c_index],
4699 BLI_kdtree_3d_free(
tree);
4717 const float timescale =
data->timescale;
4719 const float brush_radius =
data->brush_radius;
4720 const Vec3f *brushVelocity =
data->brushVelocity;
4722 float *pointCoord =
data->pointCoord;
4725 float colorband[4] = {0.0f};
4734 strength = 1.0f -
distance / brush_radius;
4735 CLAMP(strength, 0.0f, 1.0f);
4741 if (strength >= 0.001f) {
4742 float paintColor[3] = {0.0f};
4744 float velocity_val = 0.0f;
4750 strength = colorband[3];
4763 velocity_val =
len_v3(velocity);
4778 paintColor[0] = colorband[0];
4779 paintColor[1] = colorband[1];
4780 paintColor[2] = colorband[2];
4783 paintColor[0] = brush->
r;
4784 paintColor[1] = brush->
g;
4785 paintColor[2] = brush->
b;
4790 const float disp_intersect = (1.0f -
sqrtf((brush_radius -
distance) / brush_radius)) *
4795 surface, index, brush, paintColor, strength, depth, velocity_val, timescale);
4824 data.surface = surface;
4826 data.brushOb = brushOb;
4828 data.timescale = timescale;
4829 data.positions = brush_mesh->vert_positions();
4830 data.brush_radius = brush_radius;
4831 data.brushVelocity = &brushVel;
4832 data.pointCoord = pointCoord;
4859 const int num_neighs = adj_data->
n_num[index];
4861 for (
int i = 0; i < num_neighs; i++) {
4862 const int n_index = adj_data->
n_index[index] + i;
4863 const int t_index = adj_data->
n_target[n_index];
4867 realCoord[bData->
s_pos[t_index]].
v,
4868 realCoord[bData->
s_pos[index]].
v);
4906 for (index = 0; index < sData->
total_points; index++) {
4907 int numOfNeighs = adj_data->
n_num[index];
4909 for (
int i = 0; i < numOfNeighs; i++) {
4920 const float force[3],
4927 closest_id[0] = closest_id[1] = -1;
4928 closest_d[0] = closest_d[1] = -1.0f;
4931 for (
int i = 0; i < numOfNeighs; i++) {
4933 const float dir_dot =
dot_v3v3(bNeighs[n_index].dir, force);
4935 if (dir_dot > closest_d[0] && dir_dot > 0.0f) {
4936 closest_d[0] = dir_dot;
4937 closest_id[0] = n_index;
4941 if (closest_d[0] < 0.0f) {
4946 for (
int i = 0; i < numOfNeighs; i++) {
4949 if (n_index == closest_id[0]) {
4953 const float dir_dot =
dot_v3v3(bNeighs[n_index].dir, force);
4954 const float closest_dot =
dot_v3v3(bNeighs[n_index].dir, bNeighs[closest_id[0]].dir);
4958 if (dir_dot > closest_d[1] && closest_dot < closest_d[0] && dir_dot > 0.0f) {
4959 closest_d[1] = dir_dot;
4960 closest_id[1] = n_index;
4966 if (closest_id[1] != -1) {
4967 float force_proj[3];
4969 const float neigh_diff =
acosf(
4970 dot_v3v3(bNeighs[closest_id[0]].dir, bNeighs[closest_id[1]].dir));
4971 float force_intersect;
4976 cross_v3_v3v3(tangent, bNeighs[closest_id[0]].dir, bNeighs[closest_id[1]].dir);
4978 force_intersect =
dot_v3v3(force, tangent);
4979 madd_v3_v3v3fl(force_proj, force, tangent, (-1.0f) * force_intersect);
4983 temp =
dot_v3v3(bNeighs[closest_id[0]].dir, force_proj);
4984 CLAMP(temp, -1.0f, 1.0f);
4985 closest_d[1] =
acosf(temp) / neigh_diff;
4986 closest_d[0] = 1.0f - closest_d[1];
4989 temp =
fabsf(force_intersect);
4990 CLAMP(temp, 0.0f, 1.0f);
5006 float max_velocity = 0.0f;
5013 for (
int index = 0; index < sData->
total_points; index++) {
5022 for (
int step = 0; step <
steps; step++) {
5023 for (
int index = 0; index < sData->
total_points; index++) {
5042 sData, index, &bData->
brush_velocity[index * 4], closest_d, closest_id);
5045 for (
int i = 0; i < 2; i++) {
5046 int n_index = closest_id[i];
5047 if (n_index != -1 && closest_d[i] > 0.0f) {
5048 float dir_dot = closest_d[i], dir_factor;
5049 float speed_scale = eff_scale * smudge_str / bNeighs[n_index].
dist;
5054 if (dir_dot <= 0.0f) {
5058 dir_factor = dir_dot * speed_scale;
5063 ePoint->
color[3] = ePoint->
color[3] * (1.0f - dir_factor) +
5064 pPoint->
color[3] * dir_factor;
5073 pPoint->
e_color[3] * dir_factor;
5074 pPoint->
wetness *= (1.0f - dir_factor);
5119 float *force =
data->force;
5122 float forc[3] = {0};
5131 effectors,
nullptr, surface->
effector_weights, &epoint, forc,
nullptr,
nullptr);
5170 double average_force = 0.0f;
5171 float shrink_speed = 0.0f, spread_speed = 0.0f;
5172 float fastest_effect, avg_dist;
5183 *force =
static_cast<float *
>(
5188 data.surface = surface;
5190 data.force = *force;
5191 data.effectors = effectors;
5200 for (
int index = 0; index < sData->
total_points; index++) {
5201 average_force +=
double((*force)[index * 4 + 3]);
5219 fastest_effect =
max_fff(spread_speed, shrink_speed, average_force);
5248 const float eff_scale =
data->eff_scale;
5254 for (
int i = 0; i < numOfNeighs; i++) {
5255 const int n_idx = n_index[index] + i;
5257 const PaintPoint *pPoint_prev = &prevPoint[n_target[n_idx]];
5258 const float speed_scale = (bNeighs[n_idx].
dist < eff_scale) ? 1.0f :
5259 eff_scale / bNeighs[n_idx].
dist;
5277 w_factor = 1.0f / numOfNeighs *
min_ff(pPoint_prev->
wetness, 1.0f) * speed_scale;
5278 CLAMP(w_factor, 0.0f, 1.0f);
5307 const float eff_scale =
data->eff_scale;
5313 for (
int i = 0; i < numOfNeighs; i++) {
5314 const int n_idx = n_index[index] + i;
5315 const float speed_scale = (bNeighs[n_idx].
dist < eff_scale) ? 1.0f :
5316 eff_scale / bNeighs[n_idx].
dist;
5317 const PaintPoint *pPoint_prev = &prevPoint[n_target[n_idx]];
5318 float a_factor, ea_factor, w_factor;
5327 a_factor =
max_ff((1.0f - pPoint_prev->
color[3]) / numOfNeighs *
5328 (pPoint->
color[3] - pPoint_prev->
color[3]) * speed_scale,
5339 pPoint->
color[3] -= a_factor;
5341 pPoint->
e_color[3] -= ea_factor;
5364 const PaintPoint *pPoint_prev = &prevPoint[index];
5365 const float *force =
data->force;
5366 const float eff_scale =
data->eff_scale;
5376 float w_factor = pPoint_prev->
wetness - 0.025f;
5377 if (w_factor <= 0) {
5380 CLAMP(w_factor, 0.0f, 1.0f);
5382 float ppoint_wetness_diff = 0.0f;
5388 for (
int i = 0; i < 2; i++) {
5389 const int n_idx = closest_id[i];
5390 if (n_idx != -1 && closest_d[i] > 0.0f) {
5391 const float dir_dot = closest_d[i];
5394 if (dir_dot <= 0.0f) {
5398 float dir_factor, a_factor;
5399 const float speed_scale = eff_scale * force[index * 4 + 3] / bNeighs[n_idx].
dist;
5401 const uint n_trgt =
uint(n_target[n_idx]);
5406 const uint epointlock_idx = n_trgt / 8;
5407 const uint8_t epointlock_bitmask = 1 << (n_trgt & 7);
5415 const float e_wet = ePoint->
wetness;
5417 dir_factor =
min_ff(0.5f, dir_dot *
min_ff(speed_scale, 1.0f) * w_factor);
5420 ePoint->
wetness += dir_factor;
5424 a_factor = dir_factor / pPoint_prev->
wetness;
5425 CLAMP(a_factor, 0.0f, 1.0f);
5439 ppoint_wetness_diff += (ePoint->
wetness - e_wet);
5444 ~epointlock_bitmask);
5454 const uint ppointlock_idx = index / 8;
5455 const uint8_t ppointlock_bitmask = 1 << (index & 7);
5462 pPoint->
wetness -= ppoint_wetness_diff;
5505 data.surface = surface;
5506 data.prevPoint = prevPoint;
5507 data.eff_scale = eff_scale;
5527 data.surface = surface;
5528 data.prevPoint = prevPoint;
5529 data.eff_scale = eff_scale;
5545 const size_t point_locks_size = (sData->
total_points / 8) + 1;
5547 MEM_callocN(
sizeof(*point_locks) * point_locks_size, __func__));
5553 data.surface = surface;
5554 data.prevPoint = prevPoint;
5555 data.eff_scale = eff_scale;
5557 data.point_locks = point_locks;
5587 float mix_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5588 float mix_e_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5589 float mix_wetness = 0.0f;
5591 for (
int i = 0; i < numOfNeighs; i++) {
5592 const int n_idx = n_index[index] + i;
5593 const int target = n_target[n_idx];
5600 mix_color[3] += pPoint2->
color[3];
5603 mix_e_color[3] += pPoint2->
e_color[3];
5605 mix_wetness += pPoint2->
wetness;
5608 const float divisor = 1.0f / numOfNeighs;
5611 pPoint->
color[3] = mix_color[3] * divisor;
5615 pPoint->
color[3] = 0.0f;
5618 if (mix_e_color[3]) {
5619 pPoint->
e_color[3] = mix_e_color[3] * divisor;
5626 pPoint->
wetness = mix_wetness / numOfNeighs;
5639 data.surface = surface;
5659 const float wave_speed =
data->wave_speed;
5660 const float wave_scale =
data->wave_scale;
5661 const float wave_max_slope =
data->wave_max_slope;
5663 const float dt =
data->dt;
5664 const float min_dist =
data->min_dist;
5665 const float damp_factor =
data->damp_factor;
5669 float force = 0.0f, avg_dist = 0.0f, avg_height = 0.0f, avg_n_height = 0.0f;
5670 int numOfN = 0, numOfRN = 0;
5672 if (wPoint->
state > 0) {
5681 for (
int i = 0; i < numOfNeighs; i++) {
5682 const int n_idx = n_index[index] + i;
5683 float dist = bNeighs[n_idx].
dist * wave_scale;
5686 if (!dist || tPoint->
state > 0) {
5696 avg_n_height += tPoint->
height;
5700 force += (tPoint->
height - wPoint->
height) / (dist * dist);
5701 avg_height += tPoint->
height;
5703 avg_dist = (numOfN) ? avg_dist / numOfN : 0.0f;
5707 avg_n_height = (numOfRN) ? avg_n_height / numOfRN : 0.0f;
5708 wPoint->
height = (dt * wave_speed * avg_n_height + wPoint->
height * avg_dist) /
5709 (avg_dist + dt * wave_speed);
5715 force += (0.0f - wPoint->
height) * surface->
wave_spring / (avg_dist * avg_dist) / 2.0f;
5719 wPoint->
velocity += force * dt * wave_speed * wave_speed;
5726 if (wave_max_slope && avg_dist) {
5727 const float max_offset = wave_max_slope * avg_dist;
5728 const float offset = (numOfN) ? (avg_height / numOfN - wPoint->
height) : 0.0f;
5729 if (offset > max_offset) {
5730 wPoint->
height += offset - max_offset;
5732 else if (offset < -max_offset) {
5733 wPoint->
height += offset + max_offset;
5738 if (
data->reset_wave) {
5753 float dt, min_dist, damp_factor;
5754 const float wave_speed = surface->
wave_speed;
5758 double average_dist = 0.0f;
5770 for (index = 0; index < sData->
total_points; index++) {
5773 for (
int i = 0; i < numOfNeighs; i++) {
5781 (average_dist /
double(wave_speed) / 3)));
5787 min_dist = wave_speed * dt * 1.5f;
5790 for (ss = 0; ss <
steps; ss++) {
5795 data.surface = surface;
5796 data.prevPoint = prevPoint;
5797 data.wave_speed = wave_speed;
5798 data.wave_scale = wave_scale;
5799 data.wave_max_slope = wave_max_slope;
5801 data.min_dist = min_dist;
5802 data.damp_factor = damp_factor;
5837 const float timescale =
data->timescale;
5846 float p_wetness = pPoint->
wetness;
5855 float dry_ratio = pPoint->
wetness / p_wetness;
5868 pPoint->
e_color[3] *= dry_ratio;
5874 if (pPoint->
color[3]) {
5875 for (
int i = 0; i < 3; i++) {
5876 pPoint->
color[i] = (f_color[i] * f_color[3] -
5886 else if (pPoint->
state > 0) {
5942 for (
int i = 0; i < numOfVerts; i++) {
5978 const Vec3f *canvas_verts =
data->canvas_verts;
5980 const bool do_velocity_data =
data->do_velocity_data;
5981 const bool new_bdata =
data->new_bdata;
5983 float prev_point[3] = {0.0f, 0.0f, 0.0f};
5986 if (do_velocity_data && !new_bdata) {
5994 float n1[3], n2[3], n3[3];
5999 bData->
s_pos[index] = index * bData->
s_num[index];
6002 for (
int ss = 0; ss < bData->
s_num[index]; ss++) {
6004 canvas_verts[tPoint->
v1].
v,
6005 canvas_verts[tPoint->
v2].
v,
6006 canvas_verts[tPoint->
v3].
v,
6021 float scaled_nor[3];
6032 bData->
s_num[index] = adj_data->
n_num[index] + 1;
6033 bData->
s_pos[index] = adj_data->
n_index[index] + index;
6036 bData->
s_num[index] = 1;
6037 bData->
s_pos[index] = index;
6041 for (ss = 0; ss < bData->
s_num[index]; ss++) {
6045 int t_index = adj_data->
n_index[index] + (ss - 1);
6049 canvas_verts[adj_data->
n_target[t_index]].
v,
6059 float scaled_nor[3];
6069 if (do_velocity_data && !new_bdata && !bData->
clear) {
6082 bool new_bdata =
false;
6090 Vec3f *canvas_verts;
6101 if (do_velocity_data && bData->
velocity && (bData->
clear || !surface_moved)) {
6106 if (!surface_moved) {
6112 "Dynamic Paint transformed canvas verts");
6113 if (!canvas_verts) {
6120 "Dynamic Paint bake data");
6130 "Dynamic Paint step data");
6131 bData->
s_pos =
static_cast<int *
>(
6133 bData->
s_num =
static_cast<int *
>(
6136 "Dynamic Paint point coords");
6138 MEM_mallocN(canvasNumOfVerts *
sizeof(
float[3]),
"Dynamic Paint bData prev_positions"));
6142 if (bData->bNormal) {
6143 MEM_freeN(bData->bNormal);
6146 MEM_freeN(bData->s_pos);
6149 MEM_freeN(bData->s_num);
6152 MEM_freeN(bData->realCoord);
6164 if (do_velocity_data && !bData->velocity) {
6166 "Dynamic Paint velocity");
6168 if (do_accel_data && !bData->prev_velocity) {
6170 "Dynamic Paint prev velocity");
6172 if (bData->prev_velocity && bData->velocity) {
6173 memcpy(bData->prev_velocity, bData->velocity, sData->total_points *
sizeof(
Vec3f));
6180 bData->mesh_bounds.valid =
false;
6181 for (index = 0;
index < canvasNumOfVerts;
index++) {
6182 copy_v3_v3(canvas_verts[index].
v, positions[index]);
6183 mul_m4_v3(ob->object_to_world().ptr(), canvas_verts[index].v);
6184 boundInsert(&bData->mesh_bounds, canvas_verts[index].v);
6191 data.surface = surface;
6193 data.positions = positions;
6194 data.vert_normals = mesh->vert_normals();
6195 data.canvas_verts = canvas_verts;
6196 data.do_velocity_data = do_velocity_data;
6197 data.new_bdata = new_bdata;
6213 copy_m4_m4(bData->prev_obmat, ob->object_to_world().ptr());
6214 memcpy(bData->prev_positions, positions.data(), canvasNumOfVerts *
sizeof(
float[3]));
6243 data.surface = surface;
6244 data.timescale = timescale;
6262 int scene_frame = scene->
r.
cfra;
6263 float scene_subframe = scene->
r.
subframe;
6265 for (
int i = 0; i < numobjects; i++) {
6266 Object *brushObj = objects[i];
6279 sizeof(
float[4]) * sData->
total_points,
"Dynamic Paint brush velocity"));
6323 depsgraph, surface, brushObj->
loc, brush, brushObj, scene, timescale);
6326 else if (brushObj != ob) {
6332 scene->
r.
cfra = scene_frame;
6370 float *force =
nullptr;
6376 return setError(canvas,
N_(
"Not enough free memory"));
6381 for (s = 0; s <
steps; s++) {
6406 float timescale = 1.0f;
6419 timescale = 1.0f / (surface->
substeps + 1);
6421 for (st = 1; st <= surface->
substeps; st++) {
void free_bvhtree_from_mesh(BVHTreeFromMesh *data)
BVHTree * BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data, const Mesh *mesh, BVHCacheType bvh_cache_type, int tree_type)
@ BVHTREE_FROM_CORNER_TRIS
float bvhtree_ray_tri_intersection(const BVHTreeRay *ray, float m_dist, const float v0[3], const float v1[3], const float v2[3])
void BKE_collision_objects_free(struct Object **objects)
struct Object ** BKE_collision_objects_create(struct Depsgraph *depsgraph, struct Object *self, struct Collection *collection, unsigned int *numcollobj, unsigned int modifier_type)
bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
ColorBand * BKE_colorband_add(bool rangetype)
CustomData interface, see also DNA_customdata_types.h.
void * CustomData_get_layer_named_for_write(CustomData *data, eCustomDataType type, blender::StringRef name, int totelem)
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void * CustomData_add_layer_named(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem, blender::StringRef name)
void CustomData_validate_layer_name(const CustomData *data, eCustomDataType type, blender::StringRef name, char *outname)
int CustomData_get_named_layer_index(const CustomData *data, eCustomDataType type, blender::StringRef name)
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
void * CustomData_add_layer(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem)
#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.
bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph, Scene *scene, Object *ob, bool update_mesh, int parent_recursion, float frame, int type)
bool psys_check_enabled(struct Object *ob, struct ParticleSystem *psys, bool use_render_params)
void BKE_ptcache_id_time(PTCacheID *pid, struct Scene *scene, float cfra, int *startframe, int *endframe, float *timescale)
void BKE_ptcache_validate(struct PointCache *cache, int framenr)
void BKE_ptcache_id_from_dynamicpaint(PTCacheID *pid, struct Object *ob, struct DynamicPaintSurface *surface)
struct PointCache * BKE_ptcache_add(struct ListBase *ptcaches)
int BKE_ptcache_read(PTCacheID *pid, float cfra, bool no_extrapolate_old)
int BKE_ptcache_write(PTCacheID *pid, unsigned int cfra)
void BKE_ptcache_free_list(struct ListBase *ptcaches)
#define PTCACHE_RESET_OUTDATED
int BKE_ptcache_id_reset(struct Scene *scene, PTCacheID *pid, int mode)
float BKE_scene_ctime_get(const Scene *scene)
bool BLI_file_ensure_parent_dir_exists(const char *filepath) ATTR_NONNULL(1)
#define BVH_RAYCAST_DIST_MAX
int BLI_bvhtree_find_nearest(const BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
int BLI_bvhtree_ray_cast(const BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
A KD-tree for nearest neighbor search.
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
MINLINE float max_fff(float a, float b, float c)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
MINLINE float square_f(float a)
MINLINE float min_fff(float a, float b, float c)
void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4])
void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
void interp_weights_tri_v3(float w[3], const float v1[3], const float v2[3], const float v3[3], const float co[3])
void closest_on_tri_to_point_v3(float r[3], const float p[3], const float v1[3], const float v2[3], const float v3[3])
float closest_to_line_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2])
int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2])
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2])
void mul_m4_v3(const float M[4][4], float r[3])
bool equals_m4m4(const float mat1[4][4], const float mat2[4][4])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void mul_mat3_m4_v3(const float mat[4][4], float r[3])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_fl(float r[3], float f)
MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], float f)
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE bool equals_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3])
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
void minmax_v2v2_v2(float min[2], float max[2], const float vec[2])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE bool equals_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
void interp_v4_v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float w[3])
MINLINE void negate_v3(float r[3])
MINLINE void mul_v3_v3v3(float r[3], const float v1[3], const float v2[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE float line_point_side_v2(const float l1[2], const float l2[2], const float pt[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
bool BLI_path_abs(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1
#define STRNCPY(dst, src)
#define SNPRINTF(dst, format,...)
#define STRNCPY_UTF8(dst, src)
size_t void BLI_uniquename_cb(UniquenameCheckCallback unique_check, void *arg, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(1
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
#define BLT_I18NCONTEXT_ID_BRUSH
#define CTX_DATA_(context, msgid)
typedef double(DMatrix)[4][4]
#define CLOG_WARN(clg_ref,...)
#define CLOG_STR_ERROR(clg_ref, str)
#define CLOG_INFO(clg_ref, level,...)
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
Object groups, one object can be in many groups at once.
#define MAX_CUSTOMDATA_LAYER_NAME
@ MOD_DPAINT_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
@ 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_DISP_DISPLACE
@ MOD_DPAINT_SURFACE_T_WEIGHT
@ MOD_DPAINT_SURFACE_T_PAINT
@ MOD_DPAINT_SURFACE_T_DISPLACE
@ MOD_DPAINT_SURFACE_T_WAVE
@ MOD_DPAINT_WAVEB_REFLECT
@ MOD_DPAINT_WAVEB_CHANGE
@ MOD_DPAINT_RAY_BRUSH_AVG
@ MOD_DPAINT_PRFALL_CONSTANT
@ MOD_DPAINT_PRFALL_SMOOTH
@ MOD_DPAINT_INITIAL_NONE
@ MOD_DPAINT_INITIAL_VERTEXCOLOR
@ MOD_DPAINT_INITIAL_COLOR
@ MOD_DPAINT_INITIAL_TEXTURE
@ MOD_DPAINT_IMGFORMAT_OPENEXR
@ MOD_DPAINT_IMGFORMAT_PNG
@ MOD_DPAINT_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
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE uint8_t atomic_fetch_and_and_uint8(uint8_t *p, uint8_t b)
ATOMIC_INLINE uint8_t atomic_fetch_and_or_uint8(uint8_t *p, uint8_t b)
ATOMIC_INLINE uint32_t atomic_add_and_fetch_uint32(uint32_t *p, uint32_t x)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
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
local_group_size(16, 16) .push_constant(Type b
pow(value.r - subtrahend, 2.0)") .do_static_compilation(true)
static bool dynamicPaint_checkSurfaceData(const Scene *scene, DynamicPaintSurface *surface)
static bool dynamicPaint_paintMesh(Depsgraph *depsgraph, DynamicPaintSurface *surface, DynamicPaintBrushSettings *brush, Object *brushOb, Scene *scene, float timescale)
static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata, const int p_index, const TaskParallelTLS *__restrict)
void dynamicPaint_clearSurface(const Scene *scene, DynamicPaintSurface *surface)
static void dynamic_paint_set_init_color_tex_to_vcol_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
static void dynamic_paint_paint_single_point_cb_ex(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static void dynamic_paint_wave_step_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static void freeGrid(PaintSurfaceData *data)
static void dynamicPaint_mixPaintColors(const DynamicPaintSurface *surface, const int index, const int paintFlags, const float paintColor[3], const float paintAlpha, const float paintWetness, const float timescale)
static bool surface_usesAdjDistance(DynamicPaintSurface *surface)
DynamicPaintSurface * dynamicPaint_createNewSurface(DynamicPaintCanvasSettings *canvas, Scene *scene)
static Mesh * dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *ob, Mesh *mesh)
static void dynamicPaint_doSmudge(DynamicPaintSurface *surface, DynamicPaintBrushSettings *brush, float timescale)
static float dist_squared_to_corner_tris_uv_edges(const blender::Span< int3 > corner_tris, const float(*mloopuv)[2], int tri_index, const float point[2])
static void free_bakeData(PaintSurfaceData *data)
static void grid_cell_points_reduce(const void *__restrict userdata, void *__restrict chunk_join, void *__restrict chunk)
static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force, PaintPoint *prevPoint, float timescale, float steps)
static void scene_setSubframe(Scene *scene, float subframe)
static const float gaussianTotal
static void dynamic_paint_border_cb(void *__restrict userdata, const int b_index, const TaskParallelTLS *__restrict)
static void dynamicPaint_mixWaveHeight(PaintWavePoint *wPoint, const DynamicPaintBrushSettings *brush, float isect_height)
static bool boundsIntersect(Bounds3D *b1, Bounds3D *b2)
static bool dynamicPaint_surfaceHasMoved(DynamicPaintSurface *surface, Object *ob)
static void dynamic_paint_effect_drip_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
void dynamicPaint_freeSurface(const DynamicPaintModifierData *pmd, DynamicPaintSurface *surface)
static void grid_bound_insert_cb_ex(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict tls)
static const float gaussianFactors[5]
static void dynamic_paint_output_surface_image_wave_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static void dynamic_paint_output_surface_image_displace_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
bool dynamicPaint_createType(DynamicPaintModifierData *pmd, int type, Scene *scene)
static bool boundIntersectPoint(Bounds3D *b, const float point[3], const float radius)
static int dynamicPaint_prepareEffectStep(Depsgraph *depsgraph, DynamicPaintSurface *surface, Scene *scene, Object *ob, float **force, float timescale)
static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceData *data, DynamicPaintFindIslandBorderData *bdata, int tri_index, const float pixel[2], int in_edge, int depth)
static void dynamic_paint_brush_velocity_compute_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
static void surface_freeUnusedData(DynamicPaintSurface *surface)
static void surface_setUniqueOutputName(DynamicPaintSurface *surface, char *basename, int output)
void dynamicPaintSurface_setUniqueName(DynamicPaintSurface *surface, const char *basename)
void dynamicPaint_cacheUpdateFrames(DynamicPaintSurface *surface)
static void dynamic_paint_paint_mesh_cell_point_cb_ex(void *__restrict userdata, const int id, const TaskParallelTLS *__restrict)
static int dynamic_paint_find_neighbor_pixel(const DynamicPaintCreateUVSurfaceData *data, const MeshElemMap *vert_to_tri_map, const int w, const int h, const int px, const int py, const int n_index)
static bool dynamicPaint_symmetrizeAdjData(PaintAdjData *ed, int active_points)
static void dynamic_paint_paint_particle_cell_point_cb_ex(void *__restrict userdata, const int id, const TaskParallelTLS *__restrict)
static int neighStraightX[8]
static void dynamicPaint_allocateSurfaceType(DynamicPaintSurface *surface)
#define EFF_MOVEMENT_PER_FRAME
static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescale)
static Mesh * dynamicPaint_canvas_mesh_get(DynamicPaintCanvasSettings *canvas)
static void dynamicPaint_doBorderStep(DynamicPaintSurface *surface)
static void dynamic_paint_output_surface_image_paint_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, const char *filepath, short output_layer)
static void dynamic_paint_effect_spread_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static void mesh_tris_nearest_point_dp(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
static void dynamicPaint_prepareAdjacencyData(DynamicPaintSurface *surface, const bool force_init)
static void dynamic_paint_output_surface_image_wetmap_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static bool setError(DynamicPaintCanvasSettings *canvas, const char *string)
static DynamicPaintRuntime * dynamicPaint_Modifier_runtime_ensure(DynamicPaintModifierData *pmd)
static bool dynamic_paint_surface_needs_dry_dissolve(DynamicPaintSurface *surface)
static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph, Scene *scene, Object *ob, DynamicPaintBrushSettings *brush, Vec3f **brushVel, float timescale)
static void dynamic_paint_surface_pre_step_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static void dynamic_paint_prepare_effect_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static void surface_determineForceTargetPoints(const PaintSurfaceData *sData, const int index, const float force[3], float closest_d[2], int closest_id[2])
bool dynamicPaint_resetSurface(const Scene *scene, DynamicPaintSurface *surface)
BLI_INLINE void value_dissolve(float *r_value, const float time, const float scale, const bool is_log)
int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, Depsgraph *depsgraph, Scene *scene, Object *cObject, int frame)
static float getSurfaceDimension(PaintSurfaceData *sData)
static void dynamic_paint_set_init_color_tex_to_imseq_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
static int surface_totalSamples(DynamicPaintSurface *surface)
static void dynamic_paint_generate_bake_data_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface, Depsgraph *depsgraph, Object *ob)
#define SUBFRAME_RECURSION
void dynamicPaintSurface_updateType(DynamicPaintSurface *surface)
static void dynamic_paint_apply_surface_wave_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
static void dynamicPaint_brushObjectCalculateVelocity(Depsgraph *depsgraph, Scene *scene, Object *ob, Vec3f *brushVel, float timescale)
void dynamicPaint_Modifier_copy(const DynamicPaintModifierData *pmd, DynamicPaintModifierData *tpmd, int flag)
static void dynamic_paint_effect_shrink_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Mesh *result)
DynamicPaintSurface * get_activeSurface(DynamicPaintCanvasSettings *canvas)
static bool boundsIntersectDist(Bounds3D *b1, Bounds3D *b2, const float dist)
static Mesh * dynamicPaint_brush_mesh_get(DynamicPaintBrushSettings *brush)
static void grid_cell_points_cb_ex(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict tls)
static void mesh_tris_spherecast_dp(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
static void canvas_copyMesh(DynamicPaintCanvasSettings *canvas, Mesh *mesh)
int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface, float *progress, bool *do_update)
static void grid_bound_insert_reduce(const void *__restrict, void *__restrict chunk_join, void *__restrict chunk)
static void boundInsert(Bounds3D *b, const float point[3])
static void dynamic_paint_prepare_adjacency_cb(void *__restrict userdata, const int index, const TaskParallelTLS *__restrict)
static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const bool force_init)
static bool surface_duplicateOutputExists(void *arg, const char *name)
void dynamicPaint_freeSurfaceData(DynamicPaintSurface *surface)
static int surface_getBrushFlags(DynamicPaintSurface *surface, Depsgraph *depsgraph)
void dynamicPaint_freeBrush(DynamicPaintModifierData *pmd)
#define BRUSH_USES_VELOCITY
static bool dynamicPaint_paintParticles(DynamicPaintSurface *surface, ParticleSystem *psys, DynamicPaintBrushSettings *brush, float timescale)
static void dynamic_paint_create_uv_surface_direct_cb(void *__restrict userdata, const int ty, const TaskParallelTLS *__restrict)
static bool meshBrush_boundsIntersect(Bounds3D *b1, Bounds3D *b2, DynamicPaintBrushSettings *brush, float brush_radius)
static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Depsgraph *depsgraph, Scene *scene, Object *ob, Mesh *mesh)
void dynamicPaint_Modifier_free(DynamicPaintModifierData *pmd)
static void blendColors(const float t_color[3], const float t_alpha, const float s_color[3], const float s_alpha, float result[4])
static void surfaceGenerateGrid(DynamicPaintSurface *surface)
static int dynamicPaint_doStep(Depsgraph *depsgraph, Scene *scene, Object *ob, DynamicPaintSurface *surface, float timescale, float subframe)
static bool dynamicPaint_paintSinglePoint(Depsgraph *depsgraph, DynamicPaintSurface *surface, float *pointCoord, DynamicPaintBrushSettings *brush, Object *brushOb, Scene *scene, float timescale)
static int neighStraightY[8]
Mesh * dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, Depsgraph *depsgraph, Scene *scene, Object *ob, Mesh *mesh)
void dynamicPaint_freeCanvas(DynamicPaintModifierData *pmd)
bool dynamicPaint_outputLayerExists(DynamicPaintSurface *surface, Object *ob, int output)
static bool surface_duplicateNameExists(void *arg, const char *name)
static void dynamic_paint_set_init_color_vcol_to_imseq_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
static bool dynamicPaint_pointHasNeighbor(PaintAdjData *ed, int index, int neighbor)
static float mixColors(float a_color[3], float a_weight, const float b_color[3], float b_weight, float ratio)
void dynamicPaint_Modifier_free_runtime(DynamicPaintRuntime *runtime_data)
static bool surface_usesAdjData(DynamicPaintSurface *surface)
static int dynamicPaint_surfaceNumOfPoints(DynamicPaintSurface *surface)
static void dynamic_paint_create_uv_surface_neighbor_cb(void *__restrict userdata, const int ty, const TaskParallelTLS *__restrict)
static void dynamicPaint_setInitialColor(const Scene *, DynamicPaintSurface *surface)
static void dynamicPaint_updatePointData(const DynamicPaintSurface *surface, const int index, const DynamicPaintBrushSettings *brush, float paint[3], float influence, float depth, float vel_factor, const float timescale)
static void dynamicPaint_freeAdjData(PaintSurfaceData *data)
static void dynamic_paint_apply_surface_vpaint_blend_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
static void grid_cell_bounds_cb(void *__restrict userdata, const int x, const TaskParallelTLS *__restrict)
static void dynamic_paint_apply_surface_displace_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
smooth(Type::VEC3, "P") .flat(Type out_color storage_buf(0, Qualifier::READ, "Surfel", "surfels_buf[]") .push_constant(Type smooth(Type::VEC4, "interp_color")
struct ImBuf * IMB_allocImBuf(unsigned int, unsigned int, unsigned char, unsigned int)
bool IMB_saveiff(struct ImBuf *, const char *, int)
void IMB_freeImBuf(ImBuf *)
void *(* MEM_mallocN)(size_t len, const char *str)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_dupallocN)(const void *vmemh)
#define unit_float_to_uchar_clamp(val)
ccl_device_inline float2 floor(const float2 a)
ccl_device_inline float3 ceil(const float3 a)
static void error(const char *str)
VecBase< int32_t, 3 > int3
float distance(float a, float b)
Frequency::GEOMETRY nor[]
struct ColorBand * vel_ramp
struct DynamicPaintModifierData * pmd
struct ParticleSystem * psys
struct ColorBand * paint_ramp
const float(* positions_c)[3]
const float(* positions_p)[3]
struct DynamicPaintModifierData * pmd
blender::Span< int3 > corner_tris
blender::Span< int > corner_verts
PaintUVPoint * tempPoints
const float(* mloopuv)[2]
const DynamicPaintSurface * surface
const DynamicPaintSurface * surface
const DynamicPaintSurface * surface
const MeshElemMap * vert_to_tri_map
blender::Span< blender::float3 > positions
const DynamicPaintSurface * surface
blender::Span< blender::float3 > vert_normals
const Vec3f * canvas_verts
blender::Span< int > corner_verts
blender::MutableSpan< blender::float3 > vert_positions
const DynamicPaintSurface * surface
blender::Span< blender::float3 > vert_normals
blender::OffsetIndices< int > faces
struct DynamicPaintCanvasSettings * canvas
struct DynamicPaintBrushSettings * brush
const DynamicPaintSurface * surface
blender::Span< blender::float3 > positions
blender::Span< int > corner_verts
const DynamicPaintBrushSettings * brush
const float * avg_brushNor
const ParticleSystem * psys
const DynamicPaintSurface * surface
const Vec3f * brushVelocity
blender::Span< int3 > corner_tris
struct Mesh * canvas_mesh
const float(* mloopuv)[2]
const DynamicPaintSurface * surface
const MLoopCol * mloopcol
blender::Span< int > corner_verts
blender::Span< int3 > corner_tris
struct DynamicPaintCanvasSettings * canvas
struct Tex * init_texture
struct PaintSurfaceData * data
struct Collection * brush_group
float color_dry_threshold
struct DynamicPaintSurface * next
char image_output_path[1024]
struct EffectorWeights * effector_weights
struct PointCache * pointcache
ImBufFloatBuffer float_buffer
ImbFormatOptions foptions
struct PointCache * cache
DynamicPaintVolumeGrid * grid
float(* prev_positions)[3]
PaintBakeNormal * bNormal
struct PaintBakeData * bData
struct PaintAdjData * adj_data
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)