115 const int i = offset +
y * width +
x;
141 for (
i = 0;
i < pixels_num;
i++) {
142 if (pixel_array[
i].primitive_id != -1) {
151 const char margin_type,
153 char const *uv_layer,
154 const float uv_offset[2])
157 switch (margin_type) {
183 const float mat_low[4][4],
184 const float mat_cage[4][4],
198 triangle[0] = &triangles_low[primitive_id];
199 triangle[1] = &triangles_cage[primitive_id];
201 for (
i = 0;
i < 2;
i++) {
225 const float mat[4][4],
226 const float imat[4][4],
230 float cage_extrusion,
242 is_smooth = triangle->
is_smooth || is_cage;
283 const float facenor[3],
284 const bool differentials,
297 float t00 = v3[axis1] - v1[axis1];
298 float t01 = v3[axis2] - v1[axis2];
299 float t10 = v3[axis1] -
v2[axis1];
300 float t11 = v3[axis2] -
v2[axis2];
302 float detsh = (t00 * t11 - t10 * t01);
303 detsh = (detsh != 0.0f) ? 1.0f / detsh : 0.0f;
309 *u = (v3[axis1] - co[axis1]) * t11 - (v3[axis2] - co[axis2]) * t10;
310 *
v = (v3[axis2] - co[axis2]) * t00 - (v3[axis1] - co[axis1]) * t01;
312 *dx_u = dxco[axis1] * t11 - dxco[axis2] * t10;
313 *dx_v = dxco[axis2] * t00 - dxco[axis1] * t01;
314 *dy_u = dyco[axis1] * t11 - dyco[axis2] * t10;
315 *dy_v = dyco[axis2] * t00 - dyco[axis1] * t01;
327 const float mat_low[4][4],
329 const int highpoly_num,
334 const float max_ray_distance)
337 float hit_distance_squared = max_ray_distance * max_ray_distance;
338 if (hit_distance_squared == 0.0f) {
340 hit_distance_squared =
FLT_MAX;
343 for (
int i = 0;
i < highpoly_num;
i++) {
344 float co_high[3], dir_high[3];
358 if (treeData[
i].
tree) {
368 if (hits[
i].index != -1) {
374 if (distance_squared < hit_distance_squared) {
376 hit_distance_squared = distance_squared;
381 if (hit_mesh != -1) {
382 int primitive_id_high = hits[hit_mesh].index;
383 TriTessFace *triangle_high = &triangles[hit_mesh][primitive_id_high];
384 BakePixel *pixel_low = &pixel_array_low[pixel_id];
385 BakePixel *pixel_high = &pixel_array[pixel_id];
389 pixel_high->
seed = pixel_id;
397 float duco_low[3], dvco_low[3], dxco[3], dyco[3];
435 BLI_assert(pixel_high->
uv[0] >= -1e-3f && pixel_high->
uv[1] >= -1e-3f &&
436 pixel_high->
uv[0] + pixel_high->
uv[1] <= 1.0f + 1e-3f);
441 pixel_array[pixel_id].
seed = 0;
444 return hit_mesh != -1;
471 MEM_mallocN(
sizeof(*corner_tris) * tottri, __func__));
476 if (!calculate_normal) {
477 precomputed_normals = mesh->face_normals();
480 if (!precomputed_normals.
is_empty()) {
482 positions,
faces, corner_verts, precomputed_normals, {corner_tris, tottri});
488 const TSpace *tspace =
nullptr;
493 tspace =
static_cast<const TSpace *
>(
497 corner_normals = mesh_eval->corner_normals();
502 for (
i = 0;
i < tottri;
i++) {
503 const int3 &tri = corner_tris[
i];
504 const int face_i = tri_faces[
i];
506 triangles[
i].
positions[0] = positions[corner_verts[tri[0]]];
507 triangles[
i].
positions[1] = positions[corner_verts[tri[1]]];
508 triangles[
i].
positions[2] = positions[corner_verts[tri[2]]];
509 triangles[
i].
vert_normals[0] = vert_normals[corner_verts[tri[0]]];
510 triangles[
i].
vert_normals[1] = vert_normals[corner_verts[tri[1]]];
511 triangles[
i].
vert_normals[2] = vert_normals[corner_verts[tri[2]]];
512 triangles[
i].
is_smooth = !sharp_faces[face_i];
515 triangles[
i].
tspace[0] = &tspace[tri[0]];
516 triangles[
i].
tspace[1] = &tspace[tri[1]];
517 triangles[
i].
tspace[2] = &tspace[tri[2]];
526 if (calculate_normal) {
527 if (face_i != mpoly_prev) {
534 copy_v3_v3(triangles[
i].normal, precomputed_normals[face_i]);
547 const int highpoly_num,
548 const size_t pixels_num,
549 const bool is_custom_cage,
550 const float cage_extrusion,
551 const float max_ray_distance,
552 const float mat_low[4][4],
553 const float mat_cage[4][4],
557 float imat_low[4][4];
558 bool is_cage = me_cage !=
nullptr;
561 Mesh *me_eval_low =
nullptr;
580 else if (is_custom_cage) {
590 for (
int i = 0;
i < highpoly_num;
i++) {
593 me_highpoly[
i] = highpoly[
i].
mesh;
596 treeData[
i] = me_highpoly[
i]->bvh_corner_tris();
597 if (treeData[
i].
tree ==
nullptr) {
598 printf(
"Baking: out of memory while creating BHVTree for object \"%s\"\n",
599 highpoly[
i].ob->id.name + 2);
611 if (primitive_id == -1) {
616 const float u = pixel_array_from[
i].
uv[0];
617 const float v = pixel_array_from[
i].
uv[1];
623 if (is_custom_cage) {
625 tris_low, tris_cage, mat_low, mat_cage, primitive_id, u,
v, co, dir);
626 tri_low = &tris_cage[primitive_id];
630 tris_cage, mat_low, imat_low, primitive_id, u,
v, cage_extrusion, co, dir,
true);
631 tri_low = &tris_cage[primitive_id];
635 tris_low, mat_low, imat_low, primitive_id, u,
v, cage_extrusion, co, dir,
false);
636 tri_low = &tris_low[primitive_id];
662 for (
int i = 0;
i < highpoly_num;
i++) {
692 A = (uv2[0] - uv1[0]) * (uv3[1] - uv1[1]) - (uv3[0] - uv1[0]) * (uv2[1] - uv1[1]);
694 if (
fabsf(
A) > FLT_EPSILON) {
697 bd->
du_dx = (uv2[1] - uv3[1]) *
A;
698 bd->
dv_dx = (uv3[1] - uv1[1]) *
A;
700 bd->
du_dy = (uv3[0] - uv2[0]) *
A;
701 bd->
dv_dy = (uv1[0] - uv3[0]) *
A;
711 const size_t pixels_num,
713 const char *uv_layer)
716 const float(*mloopuv)[2];
717 if ((uv_layer ==
nullptr) || (uv_layer[0] ==
'\0')) {
718 mloopuv =
static_cast<const float(*)[2]
>(
723 mloopuv =
static_cast<const float(*)[2]
>(
727 if (mloopuv ==
nullptr) {
736 for (
int i = 0;
i < pixels_num;
i++) {
749 mesh->vert_positions(), mesh->faces(), mesh->corner_verts(), {corner_tris, tottri});
753 const VArraySpan material_indices = *attributes.
lookup<
int>(
"material_index",
758 for (
int i = 0;
i < tottri;
i++) {
759 const int3 &tri = corner_tris[
i];
760 const int face_i = tri_faces[
i];
765 const int material_index = (!material_indices.
is_empty() && materials_num) ?
766 clamp_i(material_indices[face_i], 0, materials_num - 1) :
769 for (
int image_id = 0; image_id < targets->
images_num; image_id++) {
771 if (bk_image->
image != image) {
777 for (
int a = 0; a < 3; a++) {
778 const float *uv = mloopuv[tri[a]];
784 vec[a][0] = (uv[0] - bk_image->
uv_offset[0]) *
float(bk_image->
width) - (0.5f + 0.001f);
785 vec[a][1] = (uv[1] - bk_image->
uv_offset[1]) *
float(bk_image->
height) - (0.5f + 0.002f);
810 const int swizzle_index[6] = {
818 const float swizzle_sign[6] = {
829 for (
i = 0;
i < 3;
i++) {
833 sign = swizzle_sign[normal_swizzle[
i]];
834 index = swizzle_index[normal_swizzle[
i]];
842 out[
i] =
sign *
in[index] / 2.0f + 0.5f + 1e-5f;
847 const size_t pixels_num,
852 const float mat[4][4])
864 for (
i = 0;
i < pixels_num;
i++) {
866 float tangents[3][3];
889 if (primitive_id == -1) {
899 triangle = &triangles[primitive_id];
902 for (j = 0; j < 3; j++) {
919 u = pixel_array[
i].
uv[0];
920 v = pixel_array[
i].
uv[1];
937 sign = (signs[0] * u + signs[1] *
v + signs[2] *
w) < 0 ? (-1.0f) : 1.0f;
972 const size_t pixels_num,
983 for (
i = 0;
i < pixels_num;
i++) {
987 if (pixel_array[
i].primitive_id == -1) {
1004 const size_t pixels_num,
1011 for (
i = 0;
i < pixels_num;
i++) {
1015 if (pixel_array[
i].primitive_id == -1) {
1032 const float vec_alpha[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1033 const float vec_solid[4] = {0.0f, 0.0f, 0.0f, 1.0f};
1034 const float nor_alpha[4] = {0.5f, 0.5f, 1.0f, 0.0f};
1035 const float nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f};
1058 switch (pass_type) {
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer_n(const CustomData *data, eCustomDataType type, int n)
int CustomData_get_named_layer(const CustomData *data, eCustomDataType type, blender::StringRef name)
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
ImBuf * BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
void BKE_id_free(Main *bmain, void *idv)
Mesh * BKE_mesh_copy_for_eval(const Mesh &source)
bool BKE_mesh_face_normals_are_dirty(const Mesh *mesh)
int BKE_mesh_runtime_corner_tris_len(const Mesh *mesh)
void BKE_mesh_calc_loop_tangents(Mesh *mesh_eval, bool calc_active_tangent, const char(*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME], int tangent_names_len)
#define BVH_RAYCAST_DIST_MAX
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)
MINLINE int clamp_i(int value, int min, int max)
void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3])
MINLINE int poly_to_tri_count(int poly_count, int corner_count)
MINLINE void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3])
void mul_m3_v3(const float M[3][3], float r[3])
bool invert_m3_m3(float inverse[3][3], const float mat[3][3])
void mul_m4_v3(const float M[4][4], float r[3])
void mul_transposed_mat3_m4_v3(const float M[4][4], float r[3])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void mul_v3_mat3_m4v3(float r[3], const float mat[4][4], const float vec[3])
void mul_mat3_m4_v3(const float mat[4][4], float r[3])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void copy_v2_fl2(float v[2], float x, float y)
MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w)
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_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
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 negate_v3(float r[3])
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])
@ SCE_PASS_SUBSURFACE_INDIRECT
@ SCE_PASS_SUBSURFACE_COLOR
@ SCE_PASS_DIFFUSE_DIRECT
@ SCE_PASS_GLOSSY_INDIRECT
@ SCE_PASS_TRANSM_INDIRECT
@ SCE_PASS_DIFFUSE_INDIRECT
@ SCE_PASS_SUBSURFACE_DIRECT
void IMB_rectfill_alpha(ImBuf *ibuf, float value)
void IMB_rectfill(ImBuf *drect, const float col[4])
void IMB_filter_extend(ImBuf *ibuf, char *mask, int filter)
Read Guarded memory(de)allocation.
static bool cast_ray_highpoly(blender::bke::BVHTreeFromMesh *treeData, TriTessFace *triangle_low, TriTessFace *triangles[], BakePixel *pixel_array_low, BakePixel *pixel_array, const float mat_low[4][4], BakeHighPolyData *highpoly, const int highpoly_num, blender::MutableSpan< BVHTreeRayHit > hits, const float co[3], const float dir[3], const int pixel_id, const float max_ray_distance)
void RE_bake_normal_world_to_tangent(const BakePixel pixel_array[], const size_t pixels_num, const int depth, float result[], Mesh *mesh, const eBakeNormalSwizzle normal_swizzle[3], const float mat[4][4])
int RE_pass_depth(const eScenePassType pass_type)
static void barycentric_differentials_from_position(const float co[3], const float v1[3], const float v2[3], const float v3[3], const float dxco[3], const float dyco[3], const float facenor[3], const bool differentials, float *u, float *v, float *dx_u, float *dx_v, float *dy_u, float *dy_v)
static void calc_point_from_barycentric_cage(TriTessFace *triangles_low, TriTessFace *triangles_cage, const float mat_low[4][4], const float mat_cage[4][4], int primitive_id, float u, float v, float r_co[3], float r_dir[3])
static void store_bake_pixel(void *handle, int x, int y, float u, float v)
void RE_bake_ibuf_clear(Image *image, const bool is_tangent)
static void calc_point_from_barycentric_extrusion(TriTessFace *triangles, const float mat[4][4], const float imat[4][4], int primitive_id, float u, float v, float cage_extrusion, float r_co[3], float r_dir[3], const bool is_cage)
void RE_bake_normal_world_to_world(const BakePixel pixel_array[], const size_t pixels_num, const int depth, float result[], const eBakeNormalSwizzle normal_swizzle[3])
void RE_bake_pixels_populate(Mesh *mesh, BakePixel pixel_array[], const size_t pixels_num, const BakeTargets *targets, const char *uv_layer)
static void normal_compress(float out[3], const float in[3], const eBakeNormalSwizzle normal_swizzle[3])
void RE_bake_margin(ImBuf *ibuf, char *mask, const int margin, const char margin_type, const Mesh *mesh, char const *uv_layer, const float uv_offset[2])
void RE_bake_normal_world_to_object(const BakePixel pixel_array[], const size_t pixels_num, const int depth, float result[], Object *ob, const eBakeNormalSwizzle normal_swizzle[3])
static TriTessFace * mesh_calc_tri_tessface(Mesh *mesh, bool tangent, Mesh *mesh_eval)
void RE_bake_mask_fill(const BakePixel pixel_array[], const size_t pixels_num, char *mask)
bool RE_bake_pixels_populate_from_objects(Mesh *me_low, BakePixel pixel_array_from[], BakePixel pixel_array_to[], BakeHighPolyData highpoly[], const int highpoly_num, const size_t pixels_num, const bool is_custom_cage, const float cage_extrusion, const float max_ray_distance, const float mat_low[4][4], const float mat_cage[4][4], Mesh *me_cage)
static void bake_differentials(BakeDataZSpan *bd, const float *uv1, const float *uv2, const float *uv3)
static void raycast_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *)
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
constexpr Span slice(int64_t start, int64_t size) const
constexpr bool is_empty() const
GAttributeReader lookup(const StringRef attribute_id) const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
static float normals[][3]
void * MEM_mallocN(size_t len, const char *str)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
float3 face_normal_calc(Span< float3 > vert_positions, Span< int > face_verts)
void corner_tris_calc(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, MutableSpan< int3 > corner_tris)
void corner_tris_calc_with_normals(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, Span< float3 > face_normals, MutableSpan< int3 > corner_tris)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
VecBase< int32_t, 3 > int3
VecBase< float, 3 > float3
struct Image ** material_to_image
const float * loop_normal[3]
const float * vert_normals[3]
const float * positions[3]
void RE_generate_texturemargin_adjacentfaces(ImBuf *ibuf, char *mask, const int margin, const Mesh *mesh, char const *uv_layer, const float uv_offset[2])
void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float *v3, void(*func)(void *, int, int, float, float))
void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty)
void zbuf_free_span(ZSpan *zspan)