Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/render/intern/source/bake_api.c')
-rw-r--r--source/blender/render/intern/source/bake_api.c115
1 files changed, 63 insertions, 52 deletions
diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c
index 508ea8c7c15..77f6ab9cfc2 100644
--- a/source/blender/render/intern/source/bake_api.c
+++ b/source/blender/render/intern/source/bake_api.c
@@ -64,6 +64,8 @@
* For a complete implementation example look at the Cycles Bake commit.
*/
+#include <limits.h>
+
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
@@ -354,23 +356,30 @@ static bool cast_ray_highpoly(
* This function populates an array of verts for the triangles of a mesh
* Tangent and Normals are also stored
*/
-static void mesh_calc_tri_tessface(
- TriTessFace *triangles, Mesh *me, bool tangent, DerivedMesh *dm)
+static TriTessFace *mesh_calc_tri_tessface(
+ Mesh *me, bool tangent, DerivedMesh *dm)
{
int i;
MVert *mvert;
TSpace *tspace;
float *precomputed_normals = NULL;
bool calculate_normal;
+
const int tottri = poly_to_tri_count(me->totpoly, me->totloop);
MLoopTri *looptri;
+ TriTessFace *triangles;
+
+ /* calculate normal for each polygon only once */
+ unsigned int mpoly_prev = UINT_MAX;
+ float no[3];
mvert = CustomData_get_layer(&me->vdata, CD_MVERT);
looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__);
+ triangles = MEM_mallocN(sizeof(TriTessFace) * tottri, __func__);
if (tangent) {
DM_ensure_normals(dm);
- DM_add_tangent_layer(dm);
+ DM_calc_loop_tangents(dm);
precomputed_normals = dm->getPolyDataArray(dm, CD_NORMAL);
calculate_normal = precomputed_normals ? false : true;
@@ -389,9 +398,9 @@ static void mesh_calc_tri_tessface(
MLoopTri *lt = &looptri[i];
MPoly *mp = &me->mpoly[lt->poly];
- triangles[i].mverts[0] = &mvert[lt->tri[0]];
- triangles[i].mverts[1] = &mvert[lt->tri[1]];
- triangles[i].mverts[2] = &mvert[lt->tri[2]];
+ triangles[i].mverts[0] = &mvert[me->mloop[lt->tri[0]].v];
+ triangles[i].mverts[1] = &mvert[me->mloop[lt->tri[1]].v];
+ triangles[i].mverts[2] = &mvert[me->mloop[lt->tri[2]].v];
triangles[i].is_smooth = (mp->flag & ME_SMOOTH) != 0;
if (tangent) {
@@ -400,10 +409,12 @@ static void mesh_calc_tri_tessface(
triangles[i].tspace[2] = &tspace[lt->tri[2]];
if (calculate_normal) {
- normal_tri_v3(triangles[i].normal,
- triangles[i].mverts[0]->co,
- triangles[i].mverts[1]->co,
- triangles[i].mverts[2]->co);
+ if (lt->poly != mpoly_prev) {
+ const MPoly *mp = &me->mpoly[lt->poly];
+ BKE_mesh_calc_poly_normal(mp, &me->mloop[mp->loopstart], me->mvert, no);
+ mpoly_prev = lt->poly;
+ }
+ copy_v3_v3(triangles[i].normal, no);
}
else {
copy_v3_v3(triangles[i].normal, &precomputed_normals[lt->poly]);
@@ -412,6 +423,8 @@ static void mesh_calc_tri_tessface(
}
MEM_freeN(looptri);
+
+ return triangles;
}
bool RE_bake_pixels_populate_from_objects(
@@ -444,28 +457,23 @@ bool RE_bake_pixels_populate_from_objects(
if (!is_cage) {
dm_low = CDDM_from_mesh(me_low);
- tris_low = MEM_mallocN(sizeof(TriTessFace) * (me_low->totface * 2), "MVerts Lowpoly Mesh");
- mesh_calc_tri_tessface(tris_low, me_low, true, dm_low);
+ tris_low = mesh_calc_tri_tessface(me_low, true, dm_low);
}
else if (is_custom_cage) {
- tris_low = MEM_mallocN(sizeof(TriTessFace) * (me_low->totface * 2), "MVerts Lowpoly Mesh");
- mesh_calc_tri_tessface(tris_low, me_low, false, NULL);
-
- tris_cage = MEM_mallocN(sizeof(TriTessFace) * (me_low->totface * 2), "MVerts Cage Mesh");
- mesh_calc_tri_tessface(tris_cage, me_cage, false, NULL);
+ tris_low = mesh_calc_tri_tessface(me_low, false, NULL);
+ tris_cage = mesh_calc_tri_tessface(me_cage, false, NULL);
}
else {
- tris_cage = MEM_mallocN(sizeof(TriTessFace) * (me_low->totface * 2), "MVerts Cage Mesh");
- mesh_calc_tri_tessface(tris_cage, me_cage, false, NULL);
+ tris_cage = mesh_calc_tri_tessface(me_cage, false, NULL);
}
invert_m4_m4(imat_low, mat_low);
for (i = 0; i < tot_highpoly; i++) {
- tris_high[i] = MEM_mallocN(sizeof(TriTessFace) * highpoly[i].me->totface, "MVerts Highpoly Mesh");
- mesh_calc_tri_tessface(tris_high[i], highpoly[i].me, false, NULL);
+ tris_high[i] = mesh_calc_tri_tessface(highpoly[i].me, false, NULL);
dm_highpoly[i] = CDDM_from_mesh(highpoly[i].me);
+ DM_ensure_tessface(dm_highpoly[i]);
if (dm_highpoly[i]->getNumTessFaces(dm_highpoly[i]) != 0) {
/* Create a bvh-tree for each highpoly object */
@@ -575,13 +583,26 @@ void RE_bake_pixels_populate(
size_t i;
int a, p_id;
- MTFace *mtface;
- MFace *mface;
+ const MLoopUV *mloopuv;
+ const int tottri = poly_to_tri_count(me->totpoly, me->totloop);
+ MLoopTri *looptri;
/* we can't bake in edit mode */
if (me->edit_btmesh)
return;
+ if ((uv_layer == NULL) || (uv_layer[0] == '\0')) {
+ mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV);
+ }
+ else {
+ int uv_id = CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, uv_layer);
+ mloopuv = CustomData_get_layer_n(&me->ldata, CD_MTFACE, uv_id);
+ }
+
+ if (mloopuv == NULL)
+ return;
+
+
bd.pixel_array = pixel_array;
bd.zspan = MEM_callocN(sizeof(ZSpan) * bake_images->size, "bake zspan");
@@ -594,54 +615,45 @@ void RE_bake_pixels_populate(
zbuf_alloc_span(&bd.zspan[i], bake_images->data[i].width, bake_images->data[i].height, R.clipcrop);
}
- if ((uv_layer == NULL) || (uv_layer[0] == '\0')) {
- mtface = CustomData_get_layer(&me->fdata, CD_MTFACE);
- }
- else {
- int uv_id = CustomData_get_named_layer(&me->fdata, CD_MTFACE, uv_layer);
- mtface = CustomData_get_layer_n(&me->fdata, CD_MTFACE, uv_id);
- }
-
- mface = CustomData_get_layer(&me->fdata, CD_MFACE);
+ looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__);
- if (mtface == NULL)
- return;
+ BKE_mesh_recalc_looptri(
+ me->mloop, me->mpoly,
+ me->mvert,
+ me->totloop, me->totpoly,
+ looptri);
p_id = -1;
- for (i = 0; i < me->totface; i++) {
- float vec[4][2];
- MTFace *mtf = &mtface[i];
- MFace *mf = &mface[i];
- int mat_nr = mf->mat_nr;
+ for (i = 0; i < tottri; i++) {
+ const MLoopTri *lt = &looptri[i];
+ const MPoly *mp = &me->mpoly[lt->poly];
+ float vec[3][2];
+ int mat_nr = mp->mat_nr;
int image_id = bake_images->lookup[mat_nr];
bd.bk_image = &bake_images->data[image_id];
bd.primitive_id = ++p_id;
- for (a = 0; a < 4; a++) {
+ for (a = 0; a < 3; a++) {
+ const float *uv = mloopuv[lt->tri[a]].uv;
+
/* Note, workaround for pixel aligned UVs which are common and can screw up our intersection tests
* where a pixel gets in between 2 faces or the middle of a quad,
* camera aligned quads also have this problem but they are less common.
* Add a small offset to the UVs, fixes bug #18685 - Campbell */
- vec[a][0] = mtf->uv[a][0] * (float)bd.bk_image->width - (0.5f + 0.001f);
- vec[a][1] = mtf->uv[a][1] * (float)bd.bk_image->height - (0.5f + 0.002f);
+ vec[a][0] = uv[0] * (float)bd.bk_image->width - (0.5f + 0.001f);
+ vec[a][1] = uv[1] * (float)bd.bk_image->height - (0.5f + 0.002f);
}
bake_differentials(&bd, vec[0], vec[1], vec[2]);
zspan_scanconvert(&bd.zspan[image_id], (void *)&bd, vec[0], vec[1], vec[2], store_bake_pixel);
-
- /* 4 vertices in the face */
- if (mf->v4 != 0) {
- bd.primitive_id = ++p_id;
-
- bake_differentials(&bd, vec[0], vec[2], vec[3]);
- zspan_scanconvert(&bd.zspan[image_id], (void *)&bd, vec[0], vec[2], vec[3], store_bake_pixel);
- }
}
for (i = 0; i < bake_images->size; i++) {
zbuf_free_span(&bd.zspan[i]);
}
+
+ MEM_freeN(looptri);
MEM_freeN(bd.zspan);
}
@@ -710,8 +722,7 @@ void RE_bake_normal_world_to_tangent(
DerivedMesh *dm = CDDM_from_mesh(me);
- triangles = MEM_mallocN(sizeof(TriTessFace) * (me->totface * 2), "MVerts Mesh");
- mesh_calc_tri_tessface(triangles, me, true, dm);
+ triangles = mesh_calc_tri_tessface(me, true, dm);
BLI_assert(num_pixels >= 3);