127 const int vert_index,
130 const int face_index = data->tri_faces[tri_num];
131 const bool smoothnormal = !(data->sharp_faces && data->sharp_faces[face_index]);
134 const int vi = data->corner_verts[data->corner_tris[tri_num][vert_index]];
138 copy_v3_v3(r_normal, data->face_normals[face_index]);
153 bake_rast->
w = ibuf->
x;
154 bake_rast->
h = ibuf->
y;
162 const float st[2] = {(x + 0.5f) / data->w + data->uv_offset[0],
163 (y + 0.5f) / data->h + data->uv_offset[1]};
164 const float *st0, *st1, *st2;
165 const float *tang0, *tang1, *tang2;
166 float no0[3], no1[3], no2[3];
167 float fUV[2], from_tang[3][3], to_tang[3][3];
171 st0 = data->uv_map[data->corner_tris[data->tri_index][0]];
172 st1 = data->uv_map[data->corner_tris[data->tri_index][1]];
173 st2 = data->uv_map[data->corner_tris[data->tri_index][2]];
185 if (data->pvtangent) {
186 tang0 = data->pvtangent + data->corner_tris[data->tri_index][0] * 4;
187 tang1 = data->pvtangent + data->corner_tris[data->tri_index][1] * 4;
188 tang2 = data->pvtangent + data->corner_tris[data->tri_index][2] * 4;
192 sign = (tang0[3] * u + tang1[3] *
v + tang2[3] *
w) < 0 ? (-1.0f) : 1.0f;
196 for (r = 0; r < 3; r++) {
197 from_tang[0][r] = tang0[r] * u + tang1[r] *
v + tang2[r] *
w;
198 from_tang[2][r] = no0[r] * u + no1[r] *
v + no2[r] *
w;
209 data->pass_data(data->vert_positions,
230 const int w = bake_rast->
w;
231 const int h = bake_rast->
h;
234 if ((bake_rast->
texels[y *
w + x]) == 0) {
255 const int is_mid_right)
257 const int s_stable =
fabsf(t1_s - t0_s) > FLT_EPSILON ? 1 : 0;
258 const int l_stable =
fabsf(t1_l - t0_l) > FLT_EPSILON ? 1 : 0;
259 const int w = bake_rast->
w;
260 const int h = bake_rast->
h;
263 if (y1_in <= 0 || y0_in >= h) {
267 y0 = y0_in < 0 ? 0 : y0_in;
268 y1 = y1_in >= h ? h : y1_in;
270 for (y = y0; y < y1; y++) {
273 float x_l = s_stable != 0 ? (s0_s + (((s1_s - s0_s) * (y - t0_s)) / (t1_s - t0_s))) : s0_s;
274 float x_r = l_stable != 0 ? (s0_l + (((s1_l - s0_l) * (y - t0_l)) / (t1_l - t0_l))) : s0_l;
276 if (is_mid_right != 0) {
283 if (iXr > 0 && iXl <
w) {
284 iXl = iXl < 0 ? 0 : iXl;
285 iXr = iXr >=
w ?
w : iXr;
287 for (x = iXl; x < iXr; x++) {
295 const float st0_in[2],
296 const float st1_in[2],
297 const float st2_in[2])
299 const int w = bake_rast->
w;
300 const int h = bake_rast->
h;
301 float slo = st0_in[0] *
w - 0.5f;
302 float tlo = st0_in[1] * h - 0.5f;
303 float smi = st1_in[0] *
w - 0.5f;
304 float tmi = st1_in[1] * h - 0.5f;
305 float shi = st2_in[0] *
w - 0.5f;
306 float thi = st2_in[1] * h - 0.5f;
307 int is_mid_right = 0, ylo, yhi, yhi_beg;
310 if ((slo == smi && tlo == tmi) || (slo == shi && tlo == thi) || (smi == shi && tmi == thi)) {
315 if (tlo > tmi && tlo > thi) {
319 else if (tmi > thi) {
330 is_mid_right = (-(shi - slo) * (tmi - thi) + (thi - tlo) * (smi - shi)) > 0 ? 1 : 0;
336 rasterize_half(bake_rast, slo, tlo, smi, tmi, slo, tlo, shi, thi, ylo, yhi_beg, is_mid_right);
337 rasterize_half(bake_rast, smi, tmi, shi, thi, slo, tlo, shi, thi, yhi_beg, yhi, is_mid_right);
347 return *bkr->
stop ||
G.is_break;
383 if (queue->cur_tri < queue->tot_tri) {
384 face = queue->cur_tri;
396 MBakeRast *bake_rast = &handle->bake_rast;
402 const int face_i = data->tri_faces[tri_index];
403 const short mat_nr = data->material_indices ==
nullptr ? 0 : data->material_indices[face_i];
410 if (tri_image != handle->image) {
414 data->tri_index = tri_index;
417 sub_v2_v2v2(uv[0], data->uv_map[tri[0]], data->uv_offset);
418 sub_v2_v2v2(uv[1], data->uv_map[tri[1]], data->uv_offset);
419 sub_v2_v2v2(uv[2], data->uv_map[tri[2]], data->uv_offset);
424 if (data->ibuf->float_buffer.data) {
458 const int *grid_offset;
474 bool require_tangent,
482 const int lvl = bkr->
lvl;
493 float *pvtangent =
nullptr;
498 void *bake_data =
nullptr;
502 temp_mesh->vert_positions_for_write().copy_from(
504 temp_mesh->edges_for_write().copy_from(
507 temp_mesh->corner_verts_for_write().copy_from(
509 temp_mesh->corner_edges_for_write().copy_from(
512 const Span<float3> positions = temp_mesh->vert_positions();
513 const OffsetIndices faces = temp_mesh->faces();
514 const Span<int> corner_verts = temp_mesh->corner_verts();
515 const Span<float3> vert_normals = temp_mesh->vert_normals();
516 const Span<float3> face_normals = temp_mesh->face_normals();
517 const Span<int3> corner_tris = temp_mesh->corner_tris();
518 const Span<int> tri_faces = temp_mesh->corner_tri_faces();
520 if (require_tangent) {
522 const bool *sharp_edges =
static_cast<const bool *
>(
524 const bool *sharp_faces =
static_cast<const bool *
>(
531 attributes.add<
bool>(
"sharp_edge",
532 bke::AttrDomain::Edge,
538 attributes.add<
bool>(
"sharp_face",
539 bke::AttrDomain::Face,
546 const Span<float3> corner_normals = temp_mesh->corner_normals();
573 bake_data = initBakeData(bkr, ibuf);
576 if (tot_thread > 1) {
586 queue.tot_tri = corner_tris.
size();
590 for (i = 0; i < tot_thread; i++) {
596 handle->queue = &queue;
598 handle->data.vert_positions = positions;
599 handle->data.faces =
faces;
600 handle->data.corner_verts = corner_verts;
601 handle->
data.corner_tris = corner_tris;
602 handle->
data.tri_faces = tri_faces;
603 handle->
data.vert_normals = vert_normals;
604 handle->
data.face_normals = face_normals;
605 handle->
data.material_indices =
static_cast<const int *
>(
607 handle->data.sharp_faces =
static_cast<const bool *
>(
609 handle->data.uv_map = uv_map;
611 handle->data.pvtangent = pvtangent;
612 handle->data.w = ibuf->
x;
613 handle->data.h = ibuf->
y;
614 handle->data.hires_dm = bkr->
hires_dm;
615 handle->data.lvl = lvl;
616 handle->data.pass_data = passKnownData;
617 handle->data.thread_data = handle;
618 handle->data.bake_data = bake_data;
619 handle->data.ibuf = ibuf;
626 if (tot_thread > 1) {
632 if (tot_thread > 1) {
639 for (i = 0; i < tot_thread; i++) {
640 result->height_min =
min_ff(result->height_min, handles[i].height_min);
641 result->height_max =
max_ff(result->height_max, handles[i].height_max);
648 freeBakeData(bake_data);
657 const CCGKey &key, CCGElem *grid,
float crn_x,
float crn_y,
int mode,
float res[3])
690 const int *index_mp_to_orig,
692 const int face_index,
701 int grid_size, S, face_side;
702 int *grid_offset, g_index;
710 face_side = (grid_size << 1) - 1;
712 g_index = grid_offset[face_index];
722 int polys_per_grid_side = (1 << (lvl - 1));
724 int cage_face_index = index_mp_to_orig ? index_mp_to_orig[face_index] : face_index;
727 int loc_cage_poly_ofs = face_index % (1 << (2 * lvl));
729 int cell_index = loc_cage_poly_ofs % (polys_per_grid_side * polys_per_grid_side);
730 int cell_side = (grid_size - 1) / polys_per_grid_side;
732 int row = cell_index / polys_per_grid_side;
733 int col = cell_index % polys_per_grid_side;
736 S = face_index / (1 << (2 * (lvl - 1))) - grid_offset[cage_face_index];
738 g_index = grid_offset[cage_face_index];
740 crn_y = (row * cell_side) + u * cell_side;
741 crn_x = (
col * cell_side) +
v * cell_side;
744 CLAMP(crn_x, 0.0f, grid_size);
745 CLAMP(crn_y, 0.0f, grid_size);
771 copy_v3_v3(data[0], vert_normals[corner_verts[face[0]]]);
772 copy_v3_v3(data[1], vert_normals[corner_verts[face[1]]]);
773 copy_v3_v3(data[2], vert_normals[corner_verts[face[2]]]);
774 copy_v3_v3(data[3], vert_normals[corner_verts[face[3]]]);
777 copy_v3_v3(data[0], vert_positions[corner_verts[face[0]]]);
778 copy_v3_v3(data[1], vert_positions[corner_verts[face[1]]]);
779 copy_v3_v3(data[2], vert_positions[corner_verts[face[2]]]);
780 copy_v3_v3(data[3], vert_positions[corner_verts[face[3]]]);
798 copy_v3_v3(data[0], vert_normals[corner_verts[corner_tri[0]]]);
799 copy_v3_v3(data[1], vert_normals[corner_verts[corner_tri[1]]]);
800 copy_v3_v3(data[2], vert_normals[corner_verts[corner_tri[2]]]);
803 copy_v3_v3(data[0], vert_positions[corner_verts[corner_tri[0]]]);
804 copy_v3_v3(data[1], vert_positions[corner_verts[corner_tri[1]]]);
805 copy_v3_v3(data[2], vert_positions[corner_verts[corner_tri[2]]]);
821 "MultiresBake heights");
824 height_data = MEM_cnew<MHeightBakeData>(
"MultiresBake heightData");
848 return (
void *)height_data;
855 if (height_data->
ssdm) {
887 const int face_i = tri_faces[tri_index];
892 const float *st0, *st1, *st2, *st3;
893 int pixel = ibuf->
x * y +
x;
894 float vec[3], p0[3], p1[3], n[3],
len;
898 if (face.size() == 4) {
899 st0 = uv_map[face[0]];
900 st1 = uv_map[face[1]];
901 st2 = uv_map[face[2]];
902 st3 = uv_map[face[3]];
906 st0 = uv_map[tri[0]];
907 st1 = uv_map[tri[1]];
908 st2 = uv_map[tri[2]];
917 if (height_data->
ssdm) {
929 if (face.size() == 4) {
935 vert_positions, vert_normals, corner_verts, tri, uv[0], uv[1], 1, p0);
937 vert_positions, vert_normals, corner_verts, tri, uv[0], uv[1], 0, n);
951 rrgbf[0] = rrgbf[1] = rrgbf[2] =
len;
968 normal_data = MEM_cnew<MNormalBakeData>(
"MultiresBake normalData");
973 return (
void *)normal_data;
1002 const int tri_index,
1005 float tangmat[3][3],
1010 const int face_i = tri_faces[tri_index];
1014 const float *st0, *st1, *st2, *st3;
1015 int pixel = ibuf->
x * y +
x;
1016 float n[3], vec[3], tmp[3] = {0.5, 0.5, 0.5};
1020 if (face.size() == 4) {
1021 st0 = uv_map[face[0]];
1022 st1 = uv_map[face[1]];
1023 st2 = uv_map[face[2]];
1024 st3 = uv_map[face[3]];
1028 st0 = uv_map[tri[0]];
1029 st1 = uv_map[tri[1]];
1030 st2 = uv_map[tri[2]];
1062# define MAX_NUMBER_OF_AO_RAYS 1024
1064static ushort ao_random_table_1[MAX_NUMBER_OF_AO_RAYS];
1065static ushort ao_random_table_2[MAX_NUMBER_OF_AO_RAYS];
1067static void init_ao_random()
1071 for (i = 0; i < MAX_NUMBER_OF_AO_RAYS; i++) {
1072 ao_random_table_1[i] = rand() & 0xffff;
1073 ao_random_table_2[i] = rand() & 0xffff;
1077static ushort get_ao_random1(
const int i)
1079 return ao_random_table_1[i & (MAX_NUMBER_OF_AO_RAYS - 1)];
1082static ushort get_ao_random2(
const int i)
1084 return ao_random_table_2[i & (MAX_NUMBER_OF_AO_RAYS - 1)];
1087static void build_permutation_table(
ushort permutation[],
1088 ushort temp_permutation[],
1089 const int number_of_rays,
1090 const int is_first_perm_table)
1094 for (i = 0; i < number_of_rays; i++) {
1095 temp_permutation[i] = i;
1098 for (i = 0; i < number_of_rays; i++) {
1099 const uint nr_entries_left = number_of_rays - i;
1100 ushort rnd = is_first_perm_table !=
false ? get_ao_random1(i) : get_ao_random2(i);
1101 const ushort entry = rnd % nr_entries_left;
1104 permutation[i] = temp_permutation[entry];
1107 for (k = entry; k < nr_entries_left - 1; k++) {
1108 temp_permutation[k] = temp_permutation[k + 1];
1116 for (i = 0; i < number_of_rays; i++)
1117 temp_permutation[i] = 0;
1118 for (i = 0; i < number_of_rays; i++)
1119 ++temp_permutation[permutation[i]];
1120 for (i = 0; i < number_of_rays; i++)
1130 CCGElem **grid_data;
1132 int grids_num, grid_size , faces_num;
1141 faces_num = grids_num * (grid_size - 1) * (grid_size - 1);
1143 raytree = ao_data->raytree = RE_rayobject_create(
1145 face = ao_data->rayfaces = (RayFace *)
MEM_callocN(faces_num *
sizeof(RayFace),
1148 for (i = 0; i < grids_num; i++) {
1150 for (x = 0; x < grid_size - 1; x++) {
1151 for (y = 0; y < grid_size - 1; y++) {
1159 RE_rayface_from_coords(face, ao_data, face, co[0], co[1], co[2], co[3]);
1160 RE_rayobject_add(raytree, RE_rayobject_unalignRayFace(face));
1167 RE_rayobject_done(raytree);
1172 MAOBakeData *ao_data;
1174 ushort *temp_permutation_table;
1175 size_t permutation_size;
1179 ao_data =
MEM_callocN(
sizeof(MAOBakeData),
"MultiresBake aoData");
1182 ao_data->bias = bkr->
bias;
1186 create_ao_raytree(bkr, ao_data);
1190 ao_data->permutation_table_1 =
MEM_callocN(permutation_size,
"multires AO baker perm1");
1191 ao_data->permutation_table_2 =
MEM_callocN(permutation_size,
"multires AO baker perm2");
1192 temp_permutation_table =
MEM_callocN(permutation_size,
"multires AO baker temp perm");
1194 build_permutation_table(
1195 ao_data->permutation_table_1, temp_permutation_table, bkr->
number_of_rays, 1);
1196 build_permutation_table(
1197 ao_data->permutation_table_2, temp_permutation_table, bkr->
number_of_rays, 0);
1201 return (
void *)ao_data;
1204static void free_ao_data(
void *bake_data)
1206 MAOBakeData *ao_data = (MAOBakeData *)bake_data;
1208 RE_rayobject_free(ao_data->raytree);
1211 MEM_freeN(ao_data->permutation_table_1);
1212 MEM_freeN(ao_data->permutation_table_2);
1218static void build_coordinate_frame(
float axisX[3],
float axisY[3],
const float axisZ[3])
1220 const float faX =
fabsf(axisZ[0]);
1221 const float faY =
fabsf(axisZ[1]);
1222 const float faZ =
fabsf(axisZ[2]);
1224 if (faX <= faY && faX <= faZ) {
1225 const float len =
sqrtf(axisZ[1] * axisZ[1] + axisZ[2] * axisZ[2]);
1227 axisY[1] = axisZ[2] /
len;
1228 axisY[2] = -axisZ[1] /
len;
1231 else if (faY <= faZ) {
1232 const float len =
sqrtf(axisZ[0] * axisZ[0] + axisZ[2] * axisZ[2]);
1233 axisX[0] = axisZ[2] /
len;
1235 axisX[2] = -axisZ[0] /
len;
1239 const float len =
sqrtf(axisZ[0] * axisZ[0] + axisZ[1] * axisZ[1]);
1240 axisX[0] = axisZ[1] /
len;
1241 axisX[1] = -axisZ[0] /
len;
1248static int trace_ao_ray(MAOBakeData *ao_data,
float ray_start[3],
float ray_direction[3])
1250 Isect isect = {{0}};
1252 isect.dist = RE_RAYTRACE_MAXDIST;
1259 return RE_rayobject_raycast(ao_data->raytree, &isect);
1262static void apply_ao_callback(
DerivedMesh *lores_dm,
1267 const int tri_index,
1274 const blender::int3 &tri = lores_dm->getcorner_triArray(lores_dm) + tri_index;
1276 MAOBakeData *ao_data = (MAOBakeData *)bake_data;
1279 float pos[3], nrm[3];
1281 float axisX[3], axisY[3], axisZ[3];
1284 int pixel = ibuf->
x * y +
x;
1285 float uv[2], *st0, *st1, *st2, *st3;
1289 if (face.size() == 4) {
1290 st0 = mloopuv[face[0]];
1291 st1 = mloopuv[face[1]];
1292 st2 = mloopuv[face[2]];
1293 st3 = mloopuv[face[3]];
1297 st0 = mloopuv[tri[0]];
1298 st1 = mloopuv[tri[1]];
1299 st2 = mloopuv[tri[2]];
1306 lores_dm, hires_dm, ao_data->orig_index_mp_to_orig, lvl, tri, uv[0], uv[1],
pos, nrm);
1309 for (i = 0; i < 3; i++) {
1310 cen[i] =
pos[i] + ao_data->bias * nrm[i];
1314 for (i = 0; i < 3; i++) {
1318 build_coordinate_frame(axisX, axisY, axisZ);
1321 perm_ofs = (get_ao_random2(get_ao_random1(x) + y)) & (MAX_NUMBER_OF_AO_RAYS - 1);
1324 for (i = 0; i < ao_data->number_of_rays; i++) {
1330 const ushort I = ao_data->permutation_table_1[(i + perm_ofs) % ao_data->number_of_rays];
1331 const ushort J = ao_data->permutation_table_2[i];
1333 const float JitPh = (get_ao_random2(
I + perm_ofs) & (MAX_NUMBER_OF_AO_RAYS - 1)) /
1334 float(MAX_NUMBER_OF_AO_RAYS);
1335 const float JitTh = (get_ao_random1(J + perm_ofs) & (MAX_NUMBER_OF_AO_RAYS - 1)) /
1336 float(MAX_NUMBER_OF_AO_RAYS);
1337 const float SiSqPhi = (
I + JitPh) / ao_data->number_of_rays;
1338 const float Theta =
float(2 *
M_PI) * ((J + JitTh) / ao_data->number_of_rays);
1343 float SiPhi =
sqrtf(SiSqPhi);
1344 float CoPhi = SiSqPhi < 1.0f ?
sqrtf(1.0f - SiSqPhi) : 0;
1345 float CoThe =
cosf(Theta);
1346 float SiThe =
sinf(Theta);
1348 const float dx = CoThe * CoPhi;
1349 const float dy = SiThe * CoPhi;
1350 const float dz = SiPhi;
1354 for (k = 0; k < 3; k++) {
1355 dv[k] = axisX[k] * dx + axisY[k] * dy + axisZ[k] * dz;
1358 hit_something = trace_ao_ray(ao_data, cen, dv);
1360 if (hit_something != 0) {
1365 value = 1.0f - (shadow / ao_data->number_of_rays);
1367 if (ibuf->rect_float) {
1368 float *rrgbf = ibuf->rect_float + pixel * 4;
1369 rrgbf[0] = rrgbf[1] = rrgbf[2] = value;
1373 uchar *rrgb = (
uchar *)ibuf->rect + pixel * 4;
1385 const char margin_type,
1387 const float uv_offset[2])
1393 switch (margin_type) {
1418 const float *displacement,
1420 float displacement_min,
1421 float displacement_max)
1424 const float *current_displacement = displacement;
1425 const char *current_mask =
mask;
1430 for (i = 0; i < ibuf->
x * ibuf->
y; i++) {
1432 float normalized_displacement;
1434 if (max_distance > 1e-5f) {
1435 normalized_displacement = (*current_displacement + max_distance) / (max_distance * 2);
1438 normalized_displacement = 0.5f;
1444 fp[0] = fp[1] = fp[2] = normalized_displacement;
1455 current_displacement++;
1470 ima->
id.
tag &= ~ID_TAG_DOIT;
1489 ima->
id.
tag &= ~ID_TAG_DOIT;
1498 result->height_max = -
FLT_MAX;
1510 if (ibuf->
x > 0 && ibuf->
y > 0) {
1511 BakeImBufuserData *userdata = MEM_cnew<BakeImBufuserData>(
"MultiresBake userdata");
1512 userdata->
mask_buffer = MEM_cnew_array<char>(ibuf->
y * ibuf->
x,
"MultiresBake imbuf mask");
1515 switch (bkr->
mode) {
1577 if (ibuf->
x <= 0 || ibuf->
y <= 0) {
1581 if (use_displacement_buffer) {
1586 result->height_max);
blender::float3 & CCG_grid_elem_no(const CCGKey &key, CCGElem *elem, int x, int y)
blender::float3 & CCG_grid_elem_co(const CCGKey &key, CCGElem *elem, int x, int y)
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
int CustomData_get_layer_index(const CustomData *data, eCustomDataType type)
ImBuf * BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
void BKE_image_mark_dirty(Image *image, ImBuf *ibuf)
void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
void BKE_image_get_tile_uv(const Image *ima, const int tile_number, float r_uv[2])
bool BKE_imbuf_alpha_test(ImBuf *ibuf)
void BKE_imageuser_default(ImageUser *iuser)
void BKE_id_free(Main *bmain, void *idv)
Mesh * BKE_mesh_new_nomain(int verts_num, int edges_num, int faces_num, int corners_num)
void * DM_get_loop_data_layer(DerivedMesh *dm, eCustomDataType type)
void BKE_mesh_calc_loop_tangent_ex(blender::Span< blender::float3 > vert_positions, blender::OffsetIndices< int > faces, const int *corner_verts, const blender::int3 *corner_tris, const int *corner_tri_faces, uint corner_tris_len, const blender::Span< bool > sharp_faces, const CustomData *loopdata, bool calc_active_tangent, const char(*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME], int tangent_names_len, blender::Span< blender::float3 > vert_normals, blender::Span< blender::float3 > face_normals, blender::Span< blender::float3 > corner_normals, blender::Span< blender::float3 > vert_orco, CustomData *loopdata_out, uint loopdata_out_len, short *tangent_mask_curr_p)
int mdisp_rot_face_to_crn(int face_size, int face_side, float u, float v, float *x, float *y)
DerivedMesh * subsurf_make_derived_from_derived(DerivedMesh *dm, SubsurfModifierData *smd, const Scene *scene, float(*vertCos)[3], SubsurfFlags flags)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
struct LinkData * BLI_genericNodeN(void *data)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3])
void resolve_tri_uv_v2(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2])
void resolve_quad_uv_v2(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2])
void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3])
void interp_bilinear_quad_v3(float data[4][3], float u, float v, float res[3])
bool invert_m3_m3(float inverse[3][3], const float mat[3][3])
void zero_m3(float m[3][3])
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void clamp_v2(float vec[2], float min, float max)
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3_length(float n[3], float unit_length)
MINLINE float normalize_v3(float n[3])
pthread_spinlock_t SpinLock
void BLI_threadpool_init(struct ListBase *threadbase, void *(*do_thread)(void *), int tot)
int BLI_system_thread_count(void)
void BLI_threadpool_end(struct ListBase *threadbase)
void BLI_spin_init(SpinLock *spin)
void BLI_spin_unlock(SpinLock *spin)
void BLI_spin_lock(SpinLock *spin)
void BLI_threadpool_insert(struct ListBase *threadbase, void *callerdata)
void BLI_spin_end(SpinLock *spin)
void DEG_id_tag_update(ID *id, unsigned int flags)
@ SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES
void IMB_rectfill_alpha(ImBuf *ibuf, float value)
void imb_freemipmapImBuf(ImBuf *ibuf)
void IMB_filter_extend(ImBuf *ibuf, char *mask, int filter)
Contains defines and structs used throughout the imbuf module.
@ IB_DISPLAY_BUFFER_INVALID
Read Guarded memory(de)allocation.
#define RE_BAKE_DISPLACEMENT
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
constexpr const T * data() const
constexpr int64_t size() const
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
ccl_global const KernelWorkTile * tile
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
#define unit_float_to_uchar_clamp(val)
ccl_device_inline float4 mask(const int4 mask, const float4 a)
static void apply_heights_callback(const blender::Span< blender::float3 > vert_positions, const blender::Span< blender::float3 > vert_normals, const blender::OffsetIndices< int > faces, const blender::Span< int > corner_verts, const blender::Span< blender::int3 > corner_tris, const blender::Span< int > tri_faces, const blender::Span< blender::float2 > uv_map, DerivedMesh *hires_dm, void *thread_data_v, void *bake_data, ImBuf *ibuf, const int tri_index, const int lvl, const float st[2], float[3][3], const int x, const int y)
static void * init_normal_data(MultiresBakeRender *bkr, ImBuf *)
static void * init_heights_data(MultiresBakeRender *bkr, ImBuf *ibuf)
static int multiresbake_test_break(MultiresBakeRender *bkr)
void(*)(void *bake_data) MFreeBakeData
static void rasterize_half(const MBakeRast *bake_rast, const float s0_s, const float t0_s, const float s1_s, const float t1_s, const float s0_l, const float t0_l, const float s1_l, const float t1_l, const int y0_in, const int y1_in, const int is_mid_right)
static void bake_ibuf_normalize_displacement(ImBuf *ibuf, const float *displacement, const char *mask, float displacement_min, float displacement_max)
static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
static void count_images(MultiresBakeRender *bkr)
static void interp_bilinear_mpoly(const blender::Span< blender::float3 > vert_positions, const blender::Span< blender::float3 > vert_normals, const blender::Span< int > corner_verts, const blender::IndexRange face, const float u, const float v, const int mode, float res[3])
static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
static void multiresbake_get_normal(const MResolvePixelData *data, const int tri_num, const int vert_index, float r_normal[3])
static void init_ccgdm_arrays(DerivedMesh *dm)
static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y)
static void get_ccgdm_data(const blender::OffsetIndices< int > lores_polys, DerivedMesh *hidm, const int *index_mp_to_orig, const int lvl, const int face_index, const float u, const float v, float co[3], float n[3])
void *(*)(MultiresBakeRender *bkr, ImBuf *ibuf) MInitBakeData
void(*)(const MResolvePixelData *data, const int x, const int y) MFlushPixel
static void * do_multires_bake_thread(void *data_v)
void(*)(blender::Span< blender::float3 > vert_positions, blender::Span< blender::float3 > vert_normals, blender::OffsetIndices< int > faces, blender::Span< int > corner_verts, blender::Span< blender::int3 > corner_tris, blender::Span< int > tri_faces, blender::Span< blender::float2 > uv_map, DerivedMesh *hires_dm, void *thread_data, void *bake_data, ImBuf *ibuf, const int face_index, const int lvl, const float st[2], float tangmat[3][3], const int x, const int y) MPassKnownData
static void free_normal_data(void *bake_data)
static void bake_rasterize(const MBakeRast *bake_rast, const float st0_in[2], const float st1_in[2], const float st2_in[2])
void RE_multires_bake_images(MultiresBakeRender *bkr)
static int multires_bake_queue_next_tri(MultiresBakeQueue *queue)
static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResolvePixelData *data, MFlushPixel flush_pixel, bool *do_update)
static void interp_barycentric_corner_tri(const blender::Span< blender::float3 > vert_positions, const blender::Span< blender::float3 > vert_normals, const blender::Span< int > corner_verts, const blender::int3 &corner_tri, const float u, const float v, const int mode, float res[3])
static void bake_ibuf_filter(ImBuf *ibuf, char *mask, const int margin, const char margin_type, DerivedMesh *dm, const float uv_offset[2])
static void free_heights_data(void *bake_data)
static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, ImageTile *tile, ImBuf *ibuf, bool require_tangent, MPassKnownData passKnownData, MInitBakeData initBakeData, MFreeBakeData freeBakeData, MultiresBakeResult *result)
static void interp_bilinear_grid(const CCGKey &key, CCGElem *grid, float crn_x, float crn_y, int mode, float res[3])
static void apply_tangmat_callback(const blender::Span< blender::float3 >, const blender::Span< blender::float3 >, const blender::OffsetIndices< int > faces, const blender::Span< int >, const blender::Span< blender::int3 > corner_tris, const blender::Span< int > tri_faces, const blender::Span< blender::float2 > uv_map, DerivedMesh *hires_dm, void *, void *bake_data, ImBuf *ibuf, const int tri_index, const int lvl, const float st[2], float tangmat[3][3], const int x, const int y)
float * displacement_buffer
int(* getGridSize)(DerivedMesh *dm)
int *(* getPolyArray)(DerivedMesh *dm)
int(* getNumVerts)(DerivedMesh *dm)
int *(* getCornerVertArray)(DerivedMesh *dm)
void *(* getPolyDataArray)(DerivedMesh *dm, eCustomDataType type)
int(* getNumPolys)(DerivedMesh *dm)
int(* getNumEdges)(DerivedMesh *dm)
void *(* getVertDataArray)(DerivedMesh *dm, eCustomDataType type)
int(* getNumGrids)(DerivedMesh *dm)
float *(* getVertArray)(DerivedMesh *dm)
int *(* getGridOffset)(DerivedMesh *dm)
void *(* getLoopDataArray)(DerivedMesh *dm, eCustomDataType type)
blender::int2 *(* getEdgeArray)(DerivedMesh *dm)
CCGElem **(* getGridData)(DerivedMesh *dm)
int *(* getCornerEdgeArray)(DerivedMesh *dm)
void(* release)(DerivedMesh *dm)
void(* getGridKey)(DerivedMesh *dm, CCGKey *key)
int(* getNumLoops)(DerivedMesh *dm)
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
ImBuf * mipmap[IMB_MIPMAP_LEVELS]
const MResolvePixelData * data
const int * orig_index_mp_to_orig
const int * orig_index_mp_to_orig
const int * material_indices
blender::Span< blender::float3 > vert_positions
blender::Span< blender::float3 > face_normals
blender::OffsetIndices< int > faces
blender::Span< blender::float2 > uv_map
blender::Span< blender::float3 > vert_normals
blender::Span< int > tri_faces
blender::Span< blender::int3 > corner_tris
blender::Span< int > corner_verts
struct MultiresBakeRender::@1362 ob_image
MultiresBakeQueue * queue
void RE_generate_texturemargin_adjacentfaces_dm(ImBuf *ibuf, char *mask, const int margin, DerivedMesh *dm, const float uv_offset[2])