Files
test/source/blender/render/intern/multires_bake.cc

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1600 lines
49 KiB
C++
Raw Normal View History

/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2012 Blender Foundation */
/** \file
* \ingroup render
*/
#include <cstring>
#include "MEM_guardedalloc.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
#include "DNA_scene_types.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_threads.h"
#include "BKE_DerivedMesh.h"
#include "BKE_ccg.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_lib_id.h"
#include "BKE_material.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_tangent.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_subsurf.h"
#include "DEG_depsgraph.h"
#include "RE_multires_bake.h"
#include "RE_pipeline.h"
#include "RE_texture.h"
#include "RE_texture_margin.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
using MPassKnownData = void (*)(blender::Span<blender::float3> vert_positions,
blender::Span<blender::float3> vert_normals,
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
blender::OffsetIndices<int> polys,
blender::Span<int> corner_verts,
blender::Span<MLoopTri> looptris,
blender::Span<int> looptri_polys,
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);
using MInitBakeData = void *(*)(MultiresBakeRender *bkr, ImBuf *ibuf);
using MFreeBakeData = void (*)(void *bake_data);
struct MultiresBakeResult {
float height_min, height_max;
};
struct MResolvePixelData {
/* Data from low-resolution mesh. */
blender::Span<blender::float3> vert_positions;
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
blender::OffsetIndices<int> polys;
blender::Span<int> corner_verts;
blender::Span<MLoopTri> looptris;
blender::Span<int> looptri_polys;
blender::Span<blender::float3> vert_normals;
blender::Span<blender::float3> poly_normals;
blender::Span<blender::float2> uv_map;
/* May be null. */
const int *material_indices;
Mesh: Move face shade smooth flag to a generic attribute Currently the shade smooth status for mesh faces is stored as part of `MPoly::flag`. As described in #95967, this moves that information to a separate boolean attribute. It also flips its status, so the attribute is now called `sharp_face`, which mirrors the existing `sharp_edge` attribute. The attribute doesn't need to be allocated when all faces are smooth. Forward compatibility is kept until 4.0 like the other mesh refactors. This will reduce memory bandwidth requirements for some operations, since the array of booleans uses 12 times less memory than `MPoly`. It also allows faces to be stored more efficiently in the future, since the flag is now unused. It's also possible to use generic functions to process the values. For example, finding whether there is a sharp face is just `sharp_faces.contains(true)`. The `shade_smooth` attribute is no longer accessible with geometry nodes. Since there were dedicated accessor nodes for that data, that shouldn't be a problem. That's difficult to version automatically since the named attribute nodes could be used in arbitrary combinations. **Implementation notes:** - The attribute and array variables in the code use the `sharp_faces` term, to be consistent with the user-facing "sharp faces" wording, and to avoid requiring many renames when #101689 is implemented. - Cycles now accesses smooth face status with the generic attribute, to avoid overhead. - Changing the zero-value from "smooth" to "flat" takes some care to make sure defaults are the same. - Versioning for the edge mode extrude node is particularly complex. New nodes are added by versioning to propagate the attribute in its old inverted state. - A lot of access is still done through the `CustomData` API rather than the attribute API because of a few functions. That can be cleaned up easily in the future. - In the future we would benefit from a way to store attributes as a single value for when all faces are sharp. Pull Request: https://projects.blender.org/blender/blender/pulls/104422
2023-03-08 15:36:18 +01:00
const bool *sharp_faces;
float uv_offset[2];
float *pvtangent;
int w, h;
int tri_index;
DerivedMesh *hires_dm;
int lvl;
void *thread_data;
void *bake_data;
ImBuf *ibuf;
MPassKnownData pass_data;
/* material aligned UV array */
Image **image_array;
};
using MFlushPixel = void (*)(const MResolvePixelData *data, const int x, const int y);
struct MBakeRast {
int w, h;
char *texels;
const MResolvePixelData *data;
MFlushPixel flush_pixel;
bool *do_update;
};
struct MHeightBakeData {
float *heights;
DerivedMesh *ssdm;
const int *orig_index_mp_to_orig;
};
struct MNormalBakeData {
const int *orig_index_mp_to_orig;
};
struct BakeImBufuserData {
float *displacement_buffer;
char *mask_buffer;
};
2019-03-25 11:55:36 +11:00
static void multiresbake_get_normal(const MResolvePixelData *data,
const int tri_num,
const int vert_index,
float r_normal[3])
{
const int poly_index = data->looptri_polys[tri_num];
Mesh: Move face shade smooth flag to a generic attribute Currently the shade smooth status for mesh faces is stored as part of `MPoly::flag`. As described in #95967, this moves that information to a separate boolean attribute. It also flips its status, so the attribute is now called `sharp_face`, which mirrors the existing `sharp_edge` attribute. The attribute doesn't need to be allocated when all faces are smooth. Forward compatibility is kept until 4.0 like the other mesh refactors. This will reduce memory bandwidth requirements for some operations, since the array of booleans uses 12 times less memory than `MPoly`. It also allows faces to be stored more efficiently in the future, since the flag is now unused. It's also possible to use generic functions to process the values. For example, finding whether there is a sharp face is just `sharp_faces.contains(true)`. The `shade_smooth` attribute is no longer accessible with geometry nodes. Since there were dedicated accessor nodes for that data, that shouldn't be a problem. That's difficult to version automatically since the named attribute nodes could be used in arbitrary combinations. **Implementation notes:** - The attribute and array variables in the code use the `sharp_faces` term, to be consistent with the user-facing "sharp faces" wording, and to avoid requiring many renames when #101689 is implemented. - Cycles now accesses smooth face status with the generic attribute, to avoid overhead. - Changing the zero-value from "smooth" to "flat" takes some care to make sure defaults are the same. - Versioning for the edge mode extrude node is particularly complex. New nodes are added by versioning to propagate the attribute in its old inverted state. - A lot of access is still done through the `CustomData` API rather than the attribute API because of a few functions. That can be cleaned up easily in the future. - In the future we would benefit from a way to store attributes as a single value for when all faces are sharp. Pull Request: https://projects.blender.org/blender/blender/pulls/104422
2023-03-08 15:36:18 +01:00
const bool smoothnormal = !(data->sharp_faces && data->sharp_faces[poly_index]);
if (smoothnormal) {
const int vi = data->corner_verts[data->looptris[tri_num].tri[vert_index]];
copy_v3_v3(r_normal, data->vert_normals[vi]);
}
else {
copy_v3_v3(r_normal, data->poly_normals[poly_index]);
}
}
static void init_bake_rast(MBakeRast *bake_rast,
const ImBuf *ibuf,
const MResolvePixelData *data,
MFlushPixel flush_pixel,
bool *do_update)
{
2019-03-25 11:55:36 +11:00
BakeImBufuserData *userdata = (BakeImBufuserData *)ibuf->userdata;
memset(bake_rast, 0, sizeof(MBakeRast));
bake_rast->texels = userdata->mask_buffer;
bake_rast->w = ibuf->x;
bake_rast->h = ibuf->y;
bake_rast->data = data;
bake_rast->flush_pixel = flush_pixel;
bake_rast->do_update = do_update;
}
static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
{
const float st[2] = {(x + 0.5f) / data->w + data->uv_offset[0],
(y + 0.5f) / data->h + data->uv_offset[1]};
const float *st0, *st1, *st2;
const float *tang0, *tang1, *tang2;
float no0[3], no1[3], no2[3];
float fUV[2], from_tang[3][3], to_tang[3][3];
float u, v, w, sign;
int r;
st0 = data->uv_map[data->looptris[data->tri_index].tri[0]];
st1 = data->uv_map[data->looptris[data->tri_index].tri[1]];
st2 = data->uv_map[data->looptris[data->tri_index].tri[2]];
multiresbake_get_normal(data, data->tri_index, 0, no0); /* can optimize these 3 into one call */
multiresbake_get_normal(data, data->tri_index, 1, no1);
multiresbake_get_normal(data, data->tri_index, 2, no2);
resolve_tri_uv_v2(fUV, st, st0, st1, st2);
u = fUV[0];
v = fUV[1];
w = 1 - u - v;
if (data->pvtangent) {
tang0 = data->pvtangent + data->looptris[data->tri_index].tri[0] * 4;
tang1 = data->pvtangent + data->looptris[data->tri_index].tri[1] * 4;
tang2 = data->pvtangent + data->looptris[data->tri_index].tri[2] * 4;
/* the sign is the same at all face vertices for any non degenerate face.
* Just in case we clamp the interpolated value though. */
sign = (tang0[3] * u + tang1[3] * v + tang2[3] * w) < 0 ? (-1.0f) : 1.0f;
/* this sequence of math is designed specifically as is with great care
* to be compatible with our shader. Please don't change without good reason. */
for (r = 0; r < 3; r++) {
from_tang[0][r] = tang0[r] * u + tang1[r] * v + tang2[r] * w;
from_tang[2][r] = no0[r] * u + no1[r] * v + no2[r] * w;
}
cross_v3_v3v3(from_tang[1], from_tang[2], from_tang[0]); /* `B = sign * cross(N, T)` */
mul_v3_fl(from_tang[1], sign);
invert_m3_m3(to_tang, from_tang);
}
else {
zero_m3(to_tang);
}
data->pass_data(data->vert_positions,
data->vert_normals,
data->polys,
data->corner_verts,
data->looptris,
data->looptri_polys,
data->uv_map,
data->hires_dm,
data->thread_data,
data->bake_data,
data->ibuf,
data->tri_index,
data->lvl,
st,
to_tang,
x,
y);
}
static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y)
{
const int w = bake_rast->w;
const int h = bake_rast->h;
if (x >= 0 && x < w && y >= 0 && y < h) {
if ((bake_rast->texels[y * w + x]) == 0) {
bake_rast->texels[y * w + x] = FILTER_MASK_USED;
flush_pixel(bake_rast->data, x, y);
if (bake_rast->do_update) {
*bake_rast->do_update = true;
}
}
}
}
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)
{
const int s_stable = fabsf(t1_s - t0_s) > FLT_EPSILON ? 1 : 0;
const int l_stable = fabsf(t1_l - t0_l) > FLT_EPSILON ? 1 : 0;
const int w = bake_rast->w;
const int h = bake_rast->h;
int y, y0, y1;
2019-04-22 09:08:06 +10:00
if (y1_in <= 0 || y0_in >= h) {
return;
2019-04-22 09:08:06 +10:00
}
y0 = y0_in < 0 ? 0 : y0_in;
y1 = y1_in >= h ? h : y1_in;
for (y = y0; y < y1; y++) {
/*-b(x-x0) + a(y-y0) = 0 */
int iXl, iXr, x;
float x_l = s_stable != 0 ? (s0_s + (((s1_s - s0_s) * (y - t0_s)) / (t1_s - t0_s))) : s0_s;
float x_r = l_stable != 0 ? (s0_l + (((s1_l - s0_l) * (y - t0_l)) / (t1_l - t0_l))) : s0_l;
2019-04-22 09:08:06 +10:00
if (is_mid_right != 0) {
std::swap(x_l, x_r);
2019-04-22 09:08:06 +10:00
}
iXl = int(ceilf(x_l));
iXr = int(ceilf(x_r));
if (iXr > 0 && iXl < w) {
iXl = iXl < 0 ? 0 : iXl;
iXr = iXr >= w ? w : iXr;
2019-04-22 09:08:06 +10:00
for (x = iXl; x < iXr; x++) {
set_rast_triangle(bake_rast, x, y);
2019-04-22 09:08:06 +10:00
}
}
}
}
static void bake_rasterize(const MBakeRast *bake_rast,
const float st0_in[2],
const float st1_in[2],
const float st2_in[2])
{
const int w = bake_rast->w;
const int h = bake_rast->h;
float slo = st0_in[0] * w - 0.5f;
float tlo = st0_in[1] * h - 0.5f;
float smi = st1_in[0] * w - 0.5f;
float tmi = st1_in[1] * h - 0.5f;
float shi = st2_in[0] * w - 0.5f;
float thi = st2_in[1] * h - 0.5f;
int is_mid_right = 0, ylo, yhi, yhi_beg;
/* skip degenerates */
2019-04-22 09:08:06 +10:00
if ((slo == smi && tlo == tmi) || (slo == shi && tlo == thi) || (smi == shi && tmi == thi)) {
return;
2019-04-22 09:08:06 +10:00
}
/* sort by T */
if (tlo > tmi && tlo > thi) {
std::swap(shi, slo);
std::swap(thi, tlo);
}
else if (tmi > thi) {
std::swap(shi, smi);
std::swap(thi, tmi);
}
if (tlo > tmi) {
std::swap(slo, smi);
std::swap(tlo, tmi);
}
/* check if mid point is to the left or to the right of the lo-hi edge */
is_mid_right = (-(shi - slo) * (tmi - thi) + (thi - tlo) * (smi - shi)) > 0 ? 1 : 0;
ylo = int(ceilf(tlo));
yhi_beg = int(ceilf(tmi));
yhi = int(ceilf(thi));
// if (fTmi>ceilf(fTlo))
rasterize_half(bake_rast, slo, tlo, smi, tmi, slo, tlo, shi, thi, ylo, yhi_beg, is_mid_right);
rasterize_half(bake_rast, smi, tmi, shi, thi, slo, tlo, shi, thi, yhi_beg, yhi, is_mid_right);
}
static int multiresbake_test_break(MultiresBakeRender *bkr)
{
if (!bkr->stop) {
/* this means baker is executed outside from job system */
return 0;
}
return *bkr->stop || G.is_break;
}
/* **** Threading routines **** */
struct MultiresBakeQueue {
int cur_tri;
int tot_tri;
SpinLock spin;
};
struct MultiresBakeThread {
/* this data is actually shared between all the threads */
MultiresBakeQueue *queue;
MultiresBakeRender *bkr;
Image *image;
void *bake_data;
/* thread-specific data */
MBakeRast bake_rast;
MResolvePixelData data;
/* displacement-specific data */
float height_min, height_max;
};
static int multires_bake_queue_next_tri(MultiresBakeQueue *queue)
{
int face = -1;
/* TODO: it could worth making it so thread will handle neighbor faces
* for better memory cache utilization
*/
BLI_spin_lock(&queue->spin);
if (queue->cur_tri < queue->tot_tri) {
face = queue->cur_tri;
queue->cur_tri++;
}
BLI_spin_unlock(&queue->spin);
return face;
}
static void *do_multires_bake_thread(void *data_v)
{
2019-03-25 11:55:36 +11:00
MultiresBakeThread *handle = (MultiresBakeThread *)data_v;
MResolvePixelData *data = &handle->data;
MBakeRast *bake_rast = &handle->bake_rast;
MultiresBakeRender *bkr = handle->bkr;
int tri_index;
while ((tri_index = multires_bake_queue_next_tri(handle->queue)) >= 0) {
const MLoopTri *lt = &data->looptris[tri_index];
const int poly_i = data->looptri_polys[tri_index];
const short mat_nr = data->material_indices == nullptr ? 0 : data->material_indices[poly_i];
2019-04-22 09:08:06 +10:00
if (multiresbake_test_break(bkr)) {
break;
2019-04-22 09:08:06 +10:00
}
Image *tri_image = mat_nr < bkr->ob_image.len ? bkr->ob_image.array[mat_nr] : nullptr;
2019-04-22 09:08:06 +10:00
if (tri_image != handle->image) {
continue;
2019-04-22 09:08:06 +10:00
}
data->tri_index = tri_index;
float uv[3][2];
sub_v2_v2v2(uv[0], data->uv_map[lt->tri[0]], data->uv_offset);
sub_v2_v2v2(uv[1], data->uv_map[lt->tri[1]], data->uv_offset);
sub_v2_v2v2(uv[2], data->uv_map[lt->tri[2]], data->uv_offset);
bake_rasterize(bake_rast, uv[0], uv[1], uv[2]);
/* tag image buffer for refresh */
2019-04-22 09:08:06 +10:00
if (data->ibuf->rect_float) {
data->ibuf->userflags |= IB_RECT_INVALID;
2019-04-22 09:08:06 +10:00
}
data->ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
/* update progress */
BLI_spin_lock(&handle->queue->spin);
bkr->baked_faces++;
2019-04-22 09:08:06 +10:00
if (bkr->do_update) {
*bkr->do_update = true;
2019-04-22 09:08:06 +10:00
}
2019-04-22 09:08:06 +10:00
if (bkr->progress) {
*bkr->progress = (float(bkr->baked_objects) +
float(bkr->baked_faces) / handle->queue->tot_tri) /
bkr->tot_obj;
2019-04-22 09:08:06 +10:00
}
BLI_spin_unlock(&handle->queue->spin);
}
return nullptr;
}
/* some of arrays inside ccgdm are lazy-initialized, which will generally
* require lock around accessing such data
* this function will ensure all arrays are allocated before threading started
*/
static void init_ccgdm_arrays(DerivedMesh *dm)
{
CCGElem **grid_data;
CCGKey key;
int grid_size;
const int *grid_offset;
grid_size = dm->getGridSize(dm);
grid_data = dm->getGridData(dm);
grid_offset = dm->getGridOffset(dm);
dm->getGridKey(dm, &key);
2019-03-25 11:55:36 +11:00
(void)grid_size;
(void)grid_data;
(void)grid_offset;
}
static void do_multires_bake(MultiresBakeRender *bkr,
Image *ima,
ImageTile *tile,
ImBuf *ibuf,
bool require_tangent,
MPassKnownData passKnownData,
MInitBakeData initBakeData,
MFreeBakeData freeBakeData,
MultiresBakeResult *result)
{
DerivedMesh *dm = bkr->lores_dm;
const int lvl = bkr->lvl;
if (dm->getNumPolys(dm) == 0) {
2022-05-09 23:59:19 +02:00
return;
}
2022-05-09 23:59:19 +02:00
MultiresBakeQueue queue;
const blender::Span<blender::float2> uv_map(
reinterpret_cast<const blender::float2 *>(dm->getLoopDataArray(dm, CD_PROP_FLOAT2)),
dm->getNumLoops(dm));
float *pvtangent = nullptr;
2022-05-09 23:59:19 +02:00
ListBase threads;
int i, tot_thread = bkr->threads > 0 ? bkr->threads : BLI_system_thread_count();
void *bake_data = nullptr;
2022-05-09 23:59:19 +02:00
Mesh *temp_mesh = BKE_mesh_new_nomain(
dm->getNumVerts(dm), dm->getNumEdges(dm), dm->getNumPolys(dm), dm->getNumLoops(dm));
temp_mesh->vert_positions_for_write().copy_from(
{reinterpret_cast<const blender::float3 *>(dm->getVertArray(dm)), temp_mesh->totvert});
Mesh: Move edges to a generic attribute Implements #95966, as the final step of #95965. This commit changes the storage of mesh edge vertex indices from the `MEdge` type to the generic `int2` attribute type. This follows the general design for geometry and the attribute system, where the data storage type and the usage semantics are separated. The main benefit of the change is reduced memory usage-- the requirements of storing mesh edges is reduced by 1/3. For example, this saves 8MB on a 1 million vertex grid. This also gives performance benefits to any memory-bound mesh processing algorithm that uses edges. Another benefit is that all of the edge's vertex indices are contiguous. In a few cases, it's helpful to process all of them as `Span<int>` rather than `Span<int2>`. Similarly, the type is more likely to match a generic format used by a library, or code that shouldn't know about specific Blender `Mesh` types. Various Notes: - The `.edge_verts` name is used to reflect a mapping between domains, similar to `.corner_verts`, etc. The period means that it the data shouldn't change arbitrarily by the user or procedural operations. - `edge[0]` is now used instead of `edge.v1` - Signed integers are used instead of unsigned to reduce the mixing of signed-ness, which can be error prone. - All of the previously used core mesh data types (`MVert`, `MEdge`, `MLoop`, `MPoly` are now deprecated. Only generic types are used). - The `vec2i` DNA type is used in the few C files where necessary. Pull Request: https://projects.blender.org/blender/blender/pulls/106638
2023-04-17 13:47:41 +02:00
temp_mesh->edges_for_write().copy_from(
{reinterpret_cast<const blender::int2 *>(dm->getEdgeArray(dm)), temp_mesh->totedge});
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
temp_mesh->poly_offsets_for_write().copy_from({dm->getPolyArray(dm), temp_mesh->totpoly + 1});
Mesh: Replace MLoop struct with generic attributes Implements #102359. Split the `MLoop` struct into two separate integer arrays called `corner_verts` and `corner_edges`, referring to the vertex each corner is attached to and the next edge around the face at each corner. These arrays can be sliced to give access to the edges or vertices in a face. Then they are often referred to as "poly_verts" or "poly_edges". The main benefits are halving the necessary memory bandwidth when only one array is used and simplifications from using regular integer indices instead of a special-purpose struct. The commit also starts a renaming from "loop" to "corner" in mesh code. Like the other mesh struct of array refactors, forward compatibility is kept by writing files with the older format. This will be done until 4.0 to ease the transition process. Looking at a small portion of the patch should give a good impression for the rest of the changes. I tried to make the changes as small as possible so it's easy to tell the correctness from the diff. Though I found Blender developers have been very inventive over the last decade when finding different ways to loop over the corners in a face. For performance, nearly every piece of code that deals with `Mesh` is slightly impacted. Any algorithm that is memory bottle-necked should see an improvement. For example, here is a comparison of interpolating a vertex float attribute to face corners (Ryzen 3700x): **Before** (Average: 3.7 ms, Min: 3.4 ms) ``` threading::parallel_for(loops.index_range(), 4096, [&](IndexRange range) { for (const int64_t i : range) { dst[i] = src[loops[i].v]; } }); ``` **After** (Average: 2.9 ms, Min: 2.6 ms) ``` array_utils::gather(src, corner_verts, dst); ``` That's an improvement of 28% to the average timings, and it's also a simplification, since an index-based routine can be used instead. For more examples using the new arrays, see the design task. Pull Request: https://projects.blender.org/blender/blender/pulls/104424
2023-03-20 15:55:13 +01:00
temp_mesh->corner_verts_for_write().copy_from({dm->getCornerVertArray(dm), temp_mesh->totloop});
temp_mesh->corner_edges_for_write().copy_from({dm->getCornerEdgeArray(dm), temp_mesh->totloop});
const blender::Span<blender::float3> positions = temp_mesh->vert_positions();
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
const blender::OffsetIndices polys = temp_mesh->polys();
const blender::Span<int> corner_verts = temp_mesh->corner_verts();
const blender::Span<blender::float3> vert_normals = temp_mesh->vert_normals();
const blender::Span<blender::float3> poly_normals = temp_mesh->poly_normals();
const blender::Span<MLoopTri> looptris = temp_mesh->looptris();
const blender::Span<int> looptri_polys = temp_mesh->looptri_polys();
2022-05-09 23:59:19 +02:00
if (require_tangent) {
if (CustomData_get_layer_index(&dm->loopData, CD_TANGENT) == -1) {
BKE_mesh_calc_loop_tangent_ex(
reinterpret_cast<const float(*)[3]>(positions.data()),
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
polys,
Mesh: Replace MLoop struct with generic attributes Implements #102359. Split the `MLoop` struct into two separate integer arrays called `corner_verts` and `corner_edges`, referring to the vertex each corner is attached to and the next edge around the face at each corner. These arrays can be sliced to give access to the edges or vertices in a face. Then they are often referred to as "poly_verts" or "poly_edges". The main benefits are halving the necessary memory bandwidth when only one array is used and simplifications from using regular integer indices instead of a special-purpose struct. The commit also starts a renaming from "loop" to "corner" in mesh code. Like the other mesh struct of array refactors, forward compatibility is kept by writing files with the older format. This will be done until 4.0 to ease the transition process. Looking at a small portion of the patch should give a good impression for the rest of the changes. I tried to make the changes as small as possible so it's easy to tell the correctness from the diff. Though I found Blender developers have been very inventive over the last decade when finding different ways to loop over the corners in a face. For performance, nearly every piece of code that deals with `Mesh` is slightly impacted. Any algorithm that is memory bottle-necked should see an improvement. For example, here is a comparison of interpolating a vertex float attribute to face corners (Ryzen 3700x): **Before** (Average: 3.7 ms, Min: 3.4 ms) ``` threading::parallel_for(loops.index_range(), 4096, [&](IndexRange range) { for (const int64_t i : range) { dst[i] = src[loops[i].v]; } }); ``` **After** (Average: 2.9 ms, Min: 2.6 ms) ``` array_utils::gather(src, corner_verts, dst); ``` That's an improvement of 28% to the average timings, and it's also a simplification, since an index-based routine can be used instead. For more examples using the new arrays, see the design task. Pull Request: https://projects.blender.org/blender/blender/pulls/104424
2023-03-20 15:55:13 +01:00
dm->getCornerVertArray(dm),
looptris.data(),
looptri_polys.data(),
looptris.size(),
Mesh: Move face shade smooth flag to a generic attribute Currently the shade smooth status for mesh faces is stored as part of `MPoly::flag`. As described in #95967, this moves that information to a separate boolean attribute. It also flips its status, so the attribute is now called `sharp_face`, which mirrors the existing `sharp_edge` attribute. The attribute doesn't need to be allocated when all faces are smooth. Forward compatibility is kept until 4.0 like the other mesh refactors. This will reduce memory bandwidth requirements for some operations, since the array of booleans uses 12 times less memory than `MPoly`. It also allows faces to be stored more efficiently in the future, since the flag is now unused. It's also possible to use generic functions to process the values. For example, finding whether there is a sharp face is just `sharp_faces.contains(true)`. The `shade_smooth` attribute is no longer accessible with geometry nodes. Since there were dedicated accessor nodes for that data, that shouldn't be a problem. That's difficult to version automatically since the named attribute nodes could be used in arbitrary combinations. **Implementation notes:** - The attribute and array variables in the code use the `sharp_faces` term, to be consistent with the user-facing "sharp faces" wording, and to avoid requiring many renames when #101689 is implemented. - Cycles now accesses smooth face status with the generic attribute, to avoid overhead. - Changing the zero-value from "smooth" to "flat" takes some care to make sure defaults are the same. - Versioning for the edge mode extrude node is particularly complex. New nodes are added by versioning to propagate the attribute in its old inverted state. - A lot of access is still done through the `CustomData` API rather than the attribute API because of a few functions. That can be cleaned up easily in the future. - In the future we would benefit from a way to store attributes as a single value for when all faces are sharp. Pull Request: https://projects.blender.org/blender/blender/pulls/104422
2023-03-08 15:36:18 +01:00
static_cast<const bool *>(
CustomData_get_layer_named(&dm->polyData, CD_PROP_BOOL, "sharp_face")),
2022-05-09 23:59:19 +02:00
&dm->loopData,
true,
nullptr,
2022-05-09 23:59:19 +02:00
0,
reinterpret_cast<const float(*)[3]>(vert_normals.data()),
reinterpret_cast<const float(*)[3]>(poly_normals.data()),
2022-05-09 23:59:19 +02:00
(const float(*)[3])dm->getLoopDataArray(dm, CD_NORMAL),
2022-12-05 12:58:18 +11:00
(const float(*)[3])dm->getVertDataArray(dm, CD_ORCO), /* May be nullptr. */
2022-05-09 23:59:19 +02:00
/* result */
&dm->loopData,
dm->getNumLoops(dm),
&dm->tangent_mask);
}
pvtangent = static_cast<float *>(DM_get_loop_data_layer(dm, CD_TANGENT));
2022-05-09 23:59:19 +02:00
}
2022-05-09 23:59:19 +02:00
/* all threads shares the same custom bake data */
if (initBakeData) {
bake_data = initBakeData(bkr, ibuf);
}
2022-05-09 23:59:19 +02:00
if (tot_thread > 1) {
BLI_threadpool_init(&threads, do_multires_bake_thread, tot_thread);
}
blender::Array<MultiresBakeThread> handles(tot_thread);
2022-05-09 23:59:19 +02:00
init_ccgdm_arrays(bkr->hires_dm);
/* faces queue */
queue.cur_tri = 0;
queue.tot_tri = looptris.size();
2022-05-09 23:59:19 +02:00
BLI_spin_init(&queue.spin);
/* fill in threads handles */
for (i = 0; i < tot_thread; i++) {
MultiresBakeThread *handle = &handles[i];
handle->bkr = bkr;
handle->image = ima;
handle->queue = &queue;
handle->data.vert_positions = positions;
handle->data.polys = polys;
handle->data.corner_verts = corner_verts;
handle->data.looptris = looptris;
handle->data.looptri_polys = looptri_polys;
handle->data.vert_normals = vert_normals;
handle->data.poly_normals = poly_normals;
handle->data.material_indices = static_cast<const int *>(
CustomData_get_layer_named(&dm->polyData, CD_PROP_INT32, "material_index"));
Mesh: Move face shade smooth flag to a generic attribute Currently the shade smooth status for mesh faces is stored as part of `MPoly::flag`. As described in #95967, this moves that information to a separate boolean attribute. It also flips its status, so the attribute is now called `sharp_face`, which mirrors the existing `sharp_edge` attribute. The attribute doesn't need to be allocated when all faces are smooth. Forward compatibility is kept until 4.0 like the other mesh refactors. This will reduce memory bandwidth requirements for some operations, since the array of booleans uses 12 times less memory than `MPoly`. It also allows faces to be stored more efficiently in the future, since the flag is now unused. It's also possible to use generic functions to process the values. For example, finding whether there is a sharp face is just `sharp_faces.contains(true)`. The `shade_smooth` attribute is no longer accessible with geometry nodes. Since there were dedicated accessor nodes for that data, that shouldn't be a problem. That's difficult to version automatically since the named attribute nodes could be used in arbitrary combinations. **Implementation notes:** - The attribute and array variables in the code use the `sharp_faces` term, to be consistent with the user-facing "sharp faces" wording, and to avoid requiring many renames when #101689 is implemented. - Cycles now accesses smooth face status with the generic attribute, to avoid overhead. - Changing the zero-value from "smooth" to "flat" takes some care to make sure defaults are the same. - Versioning for the edge mode extrude node is particularly complex. New nodes are added by versioning to propagate the attribute in its old inverted state. - A lot of access is still done through the `CustomData` API rather than the attribute API because of a few functions. That can be cleaned up easily in the future. - In the future we would benefit from a way to store attributes as a single value for when all faces are sharp. Pull Request: https://projects.blender.org/blender/blender/pulls/104422
2023-03-08 15:36:18 +01:00
handle->data.sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&dm->polyData, CD_PROP_BOOL, "sharp_face"));
handle->data.uv_map = uv_map;
2022-05-09 23:59:19 +02:00
BKE_image_get_tile_uv(ima, tile->tile_number, handle->data.uv_offset);
handle->data.pvtangent = pvtangent;
handle->data.w = ibuf->x;
handle->data.h = ibuf->y;
handle->data.hires_dm = bkr->hires_dm;
handle->data.lvl = lvl;
handle->data.pass_data = passKnownData;
handle->data.thread_data = handle;
handle->data.bake_data = bake_data;
handle->data.ibuf = ibuf;
handle->height_min = FLT_MAX;
handle->height_max = -FLT_MAX;
init_bake_rast(&handle->bake_rast, ibuf, &handle->data, flush_pixel, bkr->do_update);
2019-04-22 09:08:06 +10:00
if (tot_thread > 1) {
2022-05-09 23:59:19 +02:00
BLI_threadpool_insert(&threads, handle);
2019-04-22 09:08:06 +10:00
}
2022-05-09 23:59:19 +02:00
}
2022-05-09 23:59:19 +02:00
/* run threads */
if (tot_thread > 1) {
BLI_threadpool_end(&threads);
}
else {
do_multires_bake_thread(&handles[0]);
}
2022-05-09 23:59:19 +02:00
/* construct bake result */
result->height_min = handles[0].height_min;
result->height_max = handles[0].height_max;
2022-05-09 23:59:19 +02:00
for (i = 1; i < tot_thread; i++) {
result->height_min = min_ff(result->height_min, handles[i].height_min);
result->height_max = max_ff(result->height_max, handles[i].height_max);
}
2022-05-09 23:59:19 +02:00
BLI_spin_end(&queue.spin);
2022-05-09 23:59:19 +02:00
/* finalize baking */
if (freeBakeData) {
freeBakeData(bake_data);
}
2022-05-09 23:59:19 +02:00
BKE_id_free(nullptr, temp_mesh);
}
/* mode = 0: interpolate normals,
* mode = 1: interpolate coord */
static void interp_bilinear_grid(
CCGKey *key, CCGElem *grid, float crn_x, float crn_y, int mode, float res[3])
{
int x0, x1, y0, y1;
float u, v;
float data[4][3];
x0 = int(crn_x);
x1 = x0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (x0 + 1);
y0 = int(crn_y);
y1 = y0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (y0 + 1);
u = crn_x - x0;
v = crn_y - y0;
if (mode == 0) {
copy_v3_v3(data[0], CCG_grid_elem_no(key, grid, x0, y0));
copy_v3_v3(data[1], CCG_grid_elem_no(key, grid, x1, y0));
copy_v3_v3(data[2], CCG_grid_elem_no(key, grid, x1, y1));
copy_v3_v3(data[3], CCG_grid_elem_no(key, grid, x0, y1));
}
else {
copy_v3_v3(data[0], CCG_grid_elem_co(key, grid, x0, y0));
copy_v3_v3(data[1], CCG_grid_elem_co(key, grid, x1, y0));
copy_v3_v3(data[2], CCG_grid_elem_co(key, grid, x1, y1));
copy_v3_v3(data[3], CCG_grid_elem_co(key, grid, x0, y1));
}
interp_bilinear_quad_v3(data, u, v, res);
}
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
static void get_ccgdm_data(const blender::OffsetIndices<int> lores_polys,
DerivedMesh *hidm,
const int *index_mp_to_orig,
const int lvl,
const int poly_index,
const float u,
const float v,
float co[3],
float n[3])
{
CCGElem **grid_data;
CCGKey key;
float crn_x, crn_y;
int grid_size, S, face_side;
int *grid_offset, g_index;
grid_size = hidm->getGridSize(hidm);
grid_data = hidm->getGridData(hidm);
grid_offset = hidm->getGridOffset(hidm);
hidm->getGridKey(hidm, &key);
if (lvl == 0) {
face_side = (grid_size << 1) - 1;
g_index = grid_offset[poly_index];
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
S = mdisp_rot_face_to_crn(lores_polys[poly_index].size(),
face_side,
u * (face_side - 1),
v * (face_side - 1),
&crn_x,
&crn_y);
}
else {
/* number of faces per grid side */
int polys_per_grid_side = (1 << (lvl - 1));
/* get the original cage face index */
int cage_face_index = index_mp_to_orig ? index_mp_to_orig[poly_index] : poly_index;
/* local offset in total cage face grids
* `(1 << (2 * lvl))` is number of all polys for one cage face */
int loc_cage_poly_ofs = poly_index % (1 << (2 * lvl));
/* local offset in the vertex grid itself */
int cell_index = loc_cage_poly_ofs % (polys_per_grid_side * polys_per_grid_side);
int cell_side = (grid_size - 1) / polys_per_grid_side;
/* row and column based on grid side */
int row = cell_index / polys_per_grid_side;
int col = cell_index % polys_per_grid_side;
/* S is the vertex whose grid we are examining */
S = poly_index / (1 << (2 * (lvl - 1))) - grid_offset[cage_face_index];
/* get offset of grid data for original cage face */
g_index = grid_offset[cage_face_index];
crn_y = (row * cell_side) + u * cell_side;
crn_x = (col * cell_side) + v * cell_side;
}
CLAMP(crn_x, 0.0f, grid_size);
CLAMP(crn_y, 0.0f, grid_size);
if (n != nullptr) {
interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 0, n);
2019-04-22 09:08:06 +10:00
}
if (co != nullptr) {
interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 1, co);
2019-04-22 09:08:06 +10:00
}
}
/* mode = 0: interpolate normals,
* mode = 1: interpolate coord */
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,
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
const blender::IndexRange poly,
const float u,
const float v,
const int mode,
float res[3])
{
float data[4][3];
if (mode == 0) {
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
copy_v3_v3(data[0], vert_normals[corner_verts[poly[0]]]);
copy_v3_v3(data[1], vert_normals[corner_verts[poly[1]]]);
copy_v3_v3(data[2], vert_normals[corner_verts[poly[2]]]);
copy_v3_v3(data[3], vert_normals[corner_verts[poly[3]]]);
}
else {
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
copy_v3_v3(data[0], vert_positions[corner_verts[poly[0]]]);
copy_v3_v3(data[1], vert_positions[corner_verts[poly[1]]]);
copy_v3_v3(data[2], vert_positions[corner_verts[poly[2]]]);
copy_v3_v3(data[3], vert_positions[corner_verts[poly[3]]]);
}
interp_bilinear_quad_v3(data, u, v, res);
}
static void interp_barycentric_mlooptri(const blender::Span<blender::float3> vert_positions,
const blender::Span<blender::float3> vert_normals,
const blender::Span<int> corner_verts,
const MLoopTri *lt,
const float u,
const float v,
const int mode,
float res[3])
{
float data[3][3];
if (mode == 0) {
copy_v3_v3(data[0], vert_normals[corner_verts[lt->tri[0]]]);
copy_v3_v3(data[1], vert_normals[corner_verts[lt->tri[1]]]);
copy_v3_v3(data[2], vert_normals[corner_verts[lt->tri[2]]]);
}
else {
copy_v3_v3(data[0], vert_positions[corner_verts[lt->tri[0]]]);
copy_v3_v3(data[1], vert_positions[corner_verts[lt->tri[1]]]);
copy_v3_v3(data[2], vert_positions[corner_verts[lt->tri[2]]]);
}
interp_barycentric_tri_v3(data, u, v, res);
}
/* **************** Displacement Baker **************** */
static void *init_heights_data(MultiresBakeRender *bkr, ImBuf *ibuf)
{
MHeightBakeData *height_data;
DerivedMesh *lodm = bkr->lores_dm;
BakeImBufuserData *userdata = static_cast<BakeImBufuserData *>(ibuf->userdata);
if (userdata->displacement_buffer == nullptr) {
userdata->displacement_buffer = MEM_cnew_array<float>(ibuf->x * ibuf->y,
"MultiresBake heights");
2019-04-22 09:08:06 +10:00
}
height_data = MEM_cnew<MHeightBakeData>("MultiresBake heightData");
height_data->heights = userdata->displacement_buffer;
if (!bkr->use_lores_mesh) {
SubsurfModifierData smd = {{nullptr}};
int ss_lvl = bkr->tot_lvl - bkr->lvl;
CLAMP(ss_lvl, 0, 6);
if (ss_lvl > 0) {
smd.levels = smd.renderLevels = ss_lvl;
smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES;
smd.quality = 3;
height_data->ssdm = subsurf_make_derived_from_derived(
bkr->lores_dm, &smd, bkr->scene, nullptr, SubsurfFlags(0));
init_ccgdm_arrays(height_data->ssdm);
}
}
height_data->orig_index_mp_to_orig = static_cast<const int *>(
lodm->getPolyDataArray(lodm, CD_ORIGINDEX));
return (void *)height_data;
}
static void free_heights_data(void *bake_data)
{
MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
2019-04-22 09:08:06 +10:00
if (height_data->ssdm) {
height_data->ssdm->release(height_data->ssdm);
2019-04-22 09:08:06 +10:00
}
MEM_freeN(height_data);
}
/* MultiresBake callback for heights baking
* general idea:
* - find coord of point with specified UV in hi-res mesh (let's call it p1)
* - find coord of point and normal with specified UV in lo-res mesh (or subdivided lo-res
* mesh to make texture smoother) let's call this point p0 and n.
* - height wound be dot(n, p1-p0) */
static void apply_heights_callback(const blender::Span<blender::float3> vert_positions,
const blender::Span<blender::float3> vert_normals,
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
const blender::OffsetIndices<int> polys,
const blender::Span<int> corner_verts,
const blender::Span<MLoopTri> looptris,
const blender::Span<int> looptri_polys,
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 /*tangmat*/[3][3],
const int x,
const int y)
{
const MLoopTri *lt = &looptris[tri_index];
const int poly_i = looptri_polys[tri_index];
const blender::IndexRange poly = polys[poly_i];
MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
2019-03-25 11:55:36 +11:00
MultiresBakeThread *thread_data = (MultiresBakeThread *)thread_data_v;
float uv[2];
const float *st0, *st1, *st2, *st3;
int pixel = ibuf->x * y + x;
float vec[3], p0[3], p1[3], n[3], len;
/* ideally we would work on triangles only, however, we rely on quads to get orthogonal
* coordinates for use in grid space (triangle barycentric is not orthogonal) */
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
if (poly.size() == 4) {
st0 = uv_map[poly[0]];
st1 = uv_map[poly[1]];
st2 = uv_map[poly[2]];
st3 = uv_map[poly[3]];
resolve_quad_uv_v2(uv, st, st0, st1, st2, st3);
}
else {
st0 = uv_map[lt->tri[0]];
st1 = uv_map[lt->tri[1]];
st2 = uv_map[lt->tri[2]];
resolve_tri_uv_v2(uv, st, st0, st1, st2);
}
clamp_v2(uv, 0.0f, 1.0f);
get_ccgdm_data(
polys, hires_dm, height_data->orig_index_mp_to_orig, lvl, poly_i, uv[0], uv[1], p1, nullptr);
if (height_data->ssdm) {
get_ccgdm_data(polys,
height_data->ssdm,
height_data->orig_index_mp_to_orig,
0,
poly_i,
uv[0],
uv[1],
p0,
n);
}
else {
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
if (poly.size() == 4) {
interp_bilinear_mpoly(vert_positions, vert_normals, corner_verts, poly, uv[0], uv[1], 1, p0);
interp_bilinear_mpoly(vert_positions, vert_normals, corner_verts, poly, uv[0], uv[1], 0, n);
}
else {
interp_barycentric_mlooptri(
vert_positions, vert_normals, corner_verts, lt, uv[0], uv[1], 1, p0);
interp_barycentric_mlooptri(
vert_positions, vert_normals, corner_verts, lt, uv[0], uv[1], 0, n);
}
}
sub_v3_v3v3(vec, p1, p0);
len = dot_v3v3(n, vec);
height_data->heights[pixel] = len;
thread_data->height_min = min_ff(thread_data->height_min, len);
thread_data->height_max = max_ff(thread_data->height_max, len);
if (ibuf->rect_float) {
float *rrgbf = ibuf->rect_float + pixel * 4;
rrgbf[0] = rrgbf[1] = rrgbf[2] = len;
rrgbf[3] = 1.0f;
}
else {
char *rrgb = (char *)ibuf->rect + pixel * 4;
rrgb[0] = rrgb[1] = rrgb[2] = unit_float_to_uchar_clamp(len);
rrgb[3] = 255;
}
}
/* **************** Normal Maps Baker **************** */
static void *init_normal_data(MultiresBakeRender *bkr, ImBuf * /*ibuf*/)
{
MNormalBakeData *normal_data;
DerivedMesh *lodm = bkr->lores_dm;
normal_data = MEM_cnew<MNormalBakeData>("MultiresBake normalData");
normal_data->orig_index_mp_to_orig = static_cast<const int *>(
lodm->getPolyDataArray(lodm, CD_ORIGINDEX));
return (void *)normal_data;
}
static void free_normal_data(void *bake_data)
{
MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
MEM_freeN(normal_data);
}
/**
* MultiresBake callback for normals' baking.
*
* General idea:
* - Find coord and normal of point with specified UV in hi-res mesh.
* - Multiply it by tangmat.
* - Vector in color space would be `norm(vec) / 2 + (0.5, 0.5, 0.5)`.
*/
static void apply_tangmat_callback(const blender::Span<blender::float3> /*vert_positions*/,
const blender::Span<blender::float3> /*vert_normals*/,
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
const blender::OffsetIndices<int> polys,
const blender::Span<int> /*corner_verts*/,
const blender::Span<MLoopTri> looptris,
const blender::Span<int> looptri_polys,
const blender::Span<blender::float2> uv_map,
DerivedMesh *hires_dm,
void * /*thread_data*/,
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)
{
const MLoopTri *lt = &looptris[tri_index];
const int poly_i = looptri_polys[tri_index];
const blender::IndexRange poly = polys[poly_i];
MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
float uv[2];
const float *st0, *st1, *st2, *st3;
int pixel = ibuf->x * y + x;
float n[3], vec[3], tmp[3] = {0.5, 0.5, 0.5};
/* ideally we would work on triangles only, however, we rely on quads to get orthogonal
* coordinates for use in grid space (triangle barycentric is not orthogonal) */
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
if (poly.size() == 4) {
st0 = uv_map[poly[0]];
st1 = uv_map[poly[1]];
st2 = uv_map[poly[2]];
st3 = uv_map[poly[3]];
resolve_quad_uv_v2(uv, st, st0, st1, st2, st3);
}
else {
st0 = uv_map[lt->tri[0]];
st1 = uv_map[lt->tri[1]];
st2 = uv_map[lt->tri[2]];
resolve_tri_uv_v2(uv, st, st0, st1, st2);
}
clamp_v2(uv, 0.0f, 1.0f);
get_ccgdm_data(
polys, hires_dm, normal_data->orig_index_mp_to_orig, lvl, poly_i, uv[0], uv[1], nullptr, n);
mul_v3_m3v3(vec, tangmat, n);
2016-07-08 10:14:49 +10:00
normalize_v3_length(vec, 0.5);
add_v3_v3(vec, tmp);
if (ibuf->rect_float) {
float *rrgbf = ibuf->rect_float + pixel * 4;
rrgbf[0] = vec[0];
rrgbf[1] = vec[1];
rrgbf[2] = vec[2];
rrgbf[3] = 1.0f;
}
else {
uchar *rrgb = (uchar *)ibuf->rect + pixel * 4;
rgb_float_to_uchar(rrgb, vec);
rrgb[3] = 255;
}
}
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
/* TODO: restore ambient occlusion baking support, using BLI BVH? */
#if 0
/* **************** Ambient Occlusion Baker **************** */
/* Must be a power of two. */
# define MAX_NUMBER_OF_AO_RAYS 1024
static ushort ao_random_table_1[MAX_NUMBER_OF_AO_RAYS];
static ushort ao_random_table_2[MAX_NUMBER_OF_AO_RAYS];
static void init_ao_random(void)
{
int i;
for (i = 0; i < MAX_NUMBER_OF_AO_RAYS; i++) {
ao_random_table_1[i] = rand() & 0xffff;
ao_random_table_2[i] = rand() & 0xffff;
}
}
static ushort get_ao_random1(const int i)
{
return ao_random_table_1[i & (MAX_NUMBER_OF_AO_RAYS - 1)];
}
static ushort get_ao_random2(const int i)
{
return ao_random_table_2[i & (MAX_NUMBER_OF_AO_RAYS - 1)];
}
static void build_permutation_table(ushort permutation[],
ushort temp_permutation[],
const int number_of_rays,
const int is_first_perm_table)
{
int i, k;
for (i = 0; i < number_of_rays; i++) {
temp_permutation[i] = i;
}
for (i = 0; i < number_of_rays; i++) {
const uint nr_entries_left = number_of_rays - i;
ushort rnd = is_first_perm_table != false ? get_ao_random1(i) : get_ao_random2(i);
const ushort entry = rnd % nr_entries_left;
/* pull entry */
permutation[i] = temp_permutation[entry];
/* delete entry */
2013-02-11 00:49:00 +00:00
for (k = entry; k < nr_entries_left - 1; k++) {
temp_permutation[k] = temp_permutation[k + 1];
2013-02-11 00:49:00 +00:00
}
}
/* verify permutation table
* every entry must appear exactly once
*/
# if 0
2013-02-11 00:49:00 +00:00
for (i = 0; i < number_of_rays; i++) temp_permutation[i] = 0;
for (i = 0; i < number_of_rays; i++) ++temp_permutation[permutation[i]];
for (i = 0; i < number_of_rays; i++) BLI_assert(temp_permutation[i] == 1);
# endif
}
static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data)
{
DerivedMesh *hidm = bkr->hires_dm;
RayObject *raytree;
RayFace *face;
CCGElem **grid_data;
CCGKey key;
int grids_num, grid_size /*, face_side */, faces_num;
int i;
grids_num = hidm->getNumGrids(hidm);
grid_size = hidm->getGridSize(hidm);
grid_data = hidm->getGridData(hidm);
hidm->getGridKey(hidm, &key);
/* face_side = (grid_size << 1) - 1; */ /* UNUSED */
faces_num = grids_num * (grid_size - 1) * (grid_size - 1);
raytree = ao_data->raytree = RE_rayobject_create(
bkr->raytrace_structure, faces_num, bkr->octree_resolution);
face = ao_data->rayfaces = (RayFace *)MEM_callocN(faces_num * sizeof(RayFace),
"ObjectRen faces");
for (i = 0; i < grids_num; i++) {
int x, y;
for (x = 0; x < grid_size - 1; x++) {
for (y = 0; y < grid_size - 1; y++) {
float co[4][3];
copy_v3_v3(co[0], CCG_grid_elem_co(&key, grid_data[i], x, y));
copy_v3_v3(co[1], CCG_grid_elem_co(&key, grid_data[i], x, y + 1));
copy_v3_v3(co[2], CCG_grid_elem_co(&key, grid_data[i], x + 1, y + 1));
copy_v3_v3(co[3], CCG_grid_elem_co(&key, grid_data[i], x + 1, y));
RE_rayface_from_coords(face, ao_data, face, co[0], co[1], co[2], co[3]);
RE_rayobject_add(raytree, RE_rayobject_unalignRayFace(face));
face++;
}
}
}
RE_rayobject_done(raytree);
}
static void *init_ao_data(MultiresBakeRender *bkr, ImBuf */*ibuf*/)
{
MAOBakeData *ao_data;
DerivedMesh *lodm = bkr->lores_dm;
ushort *temp_permutation_table;
size_t permutation_size;
init_ao_random();
ao_data = MEM_callocN(sizeof(MAOBakeData), "MultiresBake aoData");
ao_data->number_of_rays = bkr->number_of_rays;
ao_data->bias = bkr->bias;
ao_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX);
create_ao_raytree(bkr, ao_data);
/* initialize permutation tables */
permutation_size = sizeof(ushort) * bkr->number_of_rays;
ao_data->permutation_table_1 = MEM_callocN(permutation_size, "multires AO baker perm1");
ao_data->permutation_table_2 = MEM_callocN(permutation_size, "multires AO baker perm2");
temp_permutation_table = MEM_callocN(permutation_size, "multires AO baker temp perm");
build_permutation_table(
ao_data->permutation_table_1, temp_permutation_table, bkr->number_of_rays, 1);
build_permutation_table(
ao_data->permutation_table_2, temp_permutation_table, bkr->number_of_rays, 0);
MEM_freeN(temp_permutation_table);
return (void *)ao_data;
}
static void free_ao_data(void *bake_data)
{
2019-03-25 11:55:36 +11:00
MAOBakeData *ao_data = (MAOBakeData *)bake_data;
RE_rayobject_free(ao_data->raytree);
MEM_freeN(ao_data->rayfaces);
MEM_freeN(ao_data->permutation_table_1);
MEM_freeN(ao_data->permutation_table_2);
MEM_freeN(ao_data);
}
/* builds an X and a Y axis from the given Z axis */
static void build_coordinate_frame(float axisX[3], float axisY[3], const float axisZ[3])
{
const float faX = fabsf(axisZ[0]);
const float faY = fabsf(axisZ[1]);
const float faZ = fabsf(axisZ[2]);
if (faX <= faY && faX <= faZ) {
const float len = sqrtf(axisZ[1] * axisZ[1] + axisZ[2] * axisZ[2]);
axisY[0] = 0;
axisY[1] = axisZ[2] / len;
axisY[2] = -axisZ[1] / len;
cross_v3_v3v3(axisX, axisY, axisZ);
}
else if (faY <= faZ) {
const float len = sqrtf(axisZ[0] * axisZ[0] + axisZ[2] * axisZ[2]);
axisX[0] = axisZ[2] / len;
axisX[1] = 0;
axisX[2] = -axisZ[0] / len;
cross_v3_v3v3(axisY, axisZ, axisX);
}
else {
const float len = sqrtf(axisZ[0] * axisZ[0] + axisZ[1] * axisZ[1]);
axisX[0] = axisZ[1] / len;
axisX[1] = -axisZ[0] / len;
axisX[2] = 0;
cross_v3_v3v3(axisY, axisZ, axisX);
}
}
/* return false if nothing was hit and true otherwise */
static int trace_ao_ray(MAOBakeData *ao_data, float ray_start[3], float ray_direction[3])
{
Isect isect = {{0}};
isect.dist = RE_RAYTRACE_MAXDIST;
copy_v3_v3(isect.start, ray_start);
copy_v3_v3(isect.dir, ray_direction);
isect.lay = -1;
normalize_v3(isect.dir);
return RE_rayobject_raycast(ao_data->raytree, &isect);
}
static void apply_ao_callback(DerivedMesh *lores_dm,
DerivedMesh *hires_dm,
void */*thread_data*/,
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)
{
const MLoopTri *lt = lores_dm->getLoopTriArray(lores_dm) + tri_index;
Mesh: Move UV layers to generic attributes Currently the `MLoopUV` struct stores UV coordinates and flags related to editing UV maps in the UV editor. This patch changes the coordinates to use the generic 2D vector type, and moves the flags into three separate boolean attributes. This follows the design in T95965, with the ultimate intention of simplifying code and improving performance. Importantly, the change allows exporters and renderers to use UVs "touched" by geometry nodes, which only creates generic attributes. It also allows geometry nodes to create "proper" UV maps from scratch, though only with the Store Named Attribute node for now. The new design considers any 2D vector attribute on the corner domain to be a UV map. In the future, they might be distinguished from regular 2D vectors with attribute metadata, which may be helpful because they are often interpolated differently. Most of the code changes deal with passing around UV BMesh custom data offsets and tracking the boolean "sublayers". The boolean layers are use the following prefixes for attribute names: vert selection: `.vs.`, edge selection: `.es.`, pinning: `.pn.`. Currently these are short to avoid using up the maximum length of attribute names. To accommodate for these 4 extra characters, the name length limit is enlarged to 68 bytes, while the maximum user settable name length is still 64 bytes. Unfortunately Python/RNA API access to the UV flag data becomes slower. Accessing the boolean layers directly is be better for performance in general. Like the other mesh SoA refactors, backward and forward compatibility aren't affected, and won't be changed until 4.0. We pay for that by making mesh reading and writing more expensive with conversions. Resolves T85962 Differential Revision: https://developer.blender.org/D14365
2023-01-10 00:47:04 -05:00
float (*mloopuv)[2] = lores_dm->getLoopDataArray(lores_dm, CD_PROP_FLOAT2);
2019-03-25 11:55:36 +11:00
MAOBakeData *ao_data = (MAOBakeData *)bake_data;
int i, k, perm_ofs;
float pos[3], nrm[3];
float cen[3];
float axisX[3], axisY[3], axisZ[3];
float shadow = 0;
float value;
int pixel = ibuf->x * y + x;
float uv[2], *st0, *st1, *st2, *st3;
/* ideally we would work on triangles only, however, we rely on quads to get orthogonal
* coordinates for use in grid space (triangle barycentric is not orthogonal) */
Mesh: Replace MPoly struct with offset indices Implements #95967. Currently the `MPoly` struct is 12 bytes, and stores the index of a face's first corner and the number of corners/verts/edges. Polygons and corners are always created in order by Blender, meaning each face's corners will be after the previous face's corners. We can take advantage of this fact and eliminate the redundancy in mesh face storage by only storing a single integer corner offset for each face. The size of the face is then encoded by the offset of the next face. The size of a single integer is 4 bytes, so this reduces memory usage by 3 times. The same method is used for `CurvesGeometry`, so Blender already has an abstraction to simplify using these offsets called `OffsetIndices`. This class is used to easily retrieve a range of corner indices for each face. This also gives the opportunity for sharing some logic with curves. Another benefit of the change is that the offsets and sizes stored in `MPoly` can no longer disagree with each other. Storing faces in the order of their corners can simplify some code too. Face/polygon variables now use the `IndexRange` type, which comes with quite a few utilities that can simplify code. Some: - The offset integer array has to be one longer than the face count to avoid a branch for every face, which means the data is no longer part of the mesh's `CustomData`. - We lose the ability to "reference" an original mesh's offset array until more reusable CoW from #104478 is committed. That will be added in a separate commit. - Since they aren't part of `CustomData`, poly offsets often have to be copied manually. - To simplify using `OffsetIndices` in many places, some functions and structs in headers were moved to only compile in C++. - All meshes created by Blender use the same order for faces and face corners, but just in case, meshes with mismatched order are fixed by versioning code. - `MeshPolygon.totloop` is no longer editable in RNA. This API break is necessary here unfortunately. It should be worth it in 3.6, since that's the best way to allow loading meshes from 4.0, which is important for an LTS version. Pull Request: https://projects.blender.org/blender/blender/pulls/105938
2023-04-04 20:39:28 +02:00
if (poly.size() == 4) {
st0 = mloopuv[poly[0]];
st1 = mloopuv[poly[1]];
st2 = mloopuv[poly[2]];
st3 = mloopuv[poly[3]];
resolve_quad_uv_v2(uv, st, st0, st1, st2, st3);
}
else {
Mesh: Move UV layers to generic attributes Currently the `MLoopUV` struct stores UV coordinates and flags related to editing UV maps in the UV editor. This patch changes the coordinates to use the generic 2D vector type, and moves the flags into three separate boolean attributes. This follows the design in T95965, with the ultimate intention of simplifying code and improving performance. Importantly, the change allows exporters and renderers to use UVs "touched" by geometry nodes, which only creates generic attributes. It also allows geometry nodes to create "proper" UV maps from scratch, though only with the Store Named Attribute node for now. The new design considers any 2D vector attribute on the corner domain to be a UV map. In the future, they might be distinguished from regular 2D vectors with attribute metadata, which may be helpful because they are often interpolated differently. Most of the code changes deal with passing around UV BMesh custom data offsets and tracking the boolean "sublayers". The boolean layers are use the following prefixes for attribute names: vert selection: `.vs.`, edge selection: `.es.`, pinning: `.pn.`. Currently these are short to avoid using up the maximum length of attribute names. To accommodate for these 4 extra characters, the name length limit is enlarged to 68 bytes, while the maximum user settable name length is still 64 bytes. Unfortunately Python/RNA API access to the UV flag data becomes slower. Accessing the boolean layers directly is be better for performance in general. Like the other mesh SoA refactors, backward and forward compatibility aren't affected, and won't be changed until 4.0. We pay for that by making mesh reading and writing more expensive with conversions. Resolves T85962 Differential Revision: https://developer.blender.org/D14365
2023-01-10 00:47:04 -05:00
st0 = mloopuv[lt->tri[0]];
st1 = mloopuv[lt->tri[1]];
st2 = mloopuv[lt->tri[2]];
resolve_tri_uv_v2(uv, st, st0, st1, st2);
}
clamp_v2(uv, 0.0f, 1.0f);
get_ccgdm_data(
lores_dm, hires_dm, ao_data->orig_index_mp_to_orig, lvl, lt, uv[0], uv[1], pos, nrm);
/* offset ray origin by user bias along normal */
for (i = 0; i < 3; i++) {
cen[i] = pos[i] + ao_data->bias * nrm[i];
}
/* build tangent frame */
for (i = 0; i < 3; i++) {
axisZ[i] = nrm[i];
}
build_coordinate_frame(axisX, axisY, axisZ);
/* static noise */
perm_ofs = (get_ao_random2(get_ao_random1(x) + y)) & (MAX_NUMBER_OF_AO_RAYS - 1);
/* importance sample shadow rays (cosine weighted) */
for (i = 0; i < ao_data->number_of_rays; i++) {
int hit_something;
/* use N-Rooks to distribute our N ray samples across
* a multi-dimensional domain (2D)
*/
const ushort I =
ao_data->permutation_table_1[(i + perm_ofs) % ao_data->number_of_rays];
const ushort J = ao_data->permutation_table_2[i];
const float JitPh = (get_ao_random2(I + perm_ofs) & (MAX_NUMBER_OF_AO_RAYS - 1)) /
2023-01-11 13:03:53 +11:00
float(MAX_NUMBER_OF_AO_RAYS);
const float JitTh = (get_ao_random1(J + perm_ofs) & (MAX_NUMBER_OF_AO_RAYS - 1)) /
2023-01-11 13:03:53 +11:00
float(MAX_NUMBER_OF_AO_RAYS);
const float SiSqPhi = (I + JitPh) / ao_data->number_of_rays;
2023-01-11 13:03:53 +11:00
const float Theta = float(2 * M_PI) * ((J + JitTh) / ao_data->number_of_rays);
/* this gives results identical to the so-called cosine
* weighted distribution relative to the north pole.
*/
float SiPhi = sqrtf(SiSqPhi);
2012-12-20 05:03:00 +00:00
float CoPhi = SiSqPhi < 1.0f ? sqrtf(1.0f - SiSqPhi) : 0;
float CoThe = cosf(Theta);
float SiThe = sinf(Theta);
const float dx = CoThe * CoPhi;
const float dy = SiThe * CoPhi;
const float dz = SiPhi;
/* transform ray direction out of tangent frame */
float dv[3];
for (k = 0; k < 3; k++) {
dv[k] = axisX[k] * dx + axisY[k] * dy + axisZ[k] * dz;
}
hit_something = trace_ao_ray(ao_data, cen, dv);
if (hit_something != 0) {
shadow += 1;
}
}
value = 1.0f - (shadow / ao_data->number_of_rays);
if (ibuf->rect_float) {
float *rrgbf = ibuf->rect_float + pixel * 4;
rrgbf[0] = rrgbf[1] = rrgbf[2] = value;
rrgbf[3] = 1.0f;
}
else {
uchar *rrgb = (uchar *)ibuf->rect + pixel * 4;
rrgb[0] = rrgb[1] = rrgb[2] = unit_float_to_uchar_clamp(value);
rrgb[3] = 255;
}
}
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
#endif
/* ******$***************** Post processing ************************* */
static void bake_ibuf_filter(ImBuf *ibuf,
char *mask,
const int margin,
const char margin_type,
DerivedMesh *dm,
const float uv_offset[2])
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
{
/* must check before filtering */
const bool is_new_alpha = (ibuf->planes != R_IMF_PLANES_RGBA) && BKE_imbuf_alpha_test(ibuf);
if (margin) {
switch (margin_type) {
case R_BAKE_ADJACENT_FACES:
RE_generate_texturemargin_adjacentfaces_dm(ibuf, mask, margin, dm, uv_offset);
break;
default:
/* fall through */
case R_BAKE_EXTEND:
IMB_filter_extend(ibuf, mask, margin);
break;
}
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
}
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
/* if the bake results in new alpha then change the image setting */
if (is_new_alpha) {
ibuf->planes = R_IMF_PLANES_RGBA;
}
else {
if (margin && ibuf->planes != R_IMF_PLANES_RGBA) {
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
/* clear alpha added by filtering */
IMB_rectfill_alpha(ibuf, 1.0f);
}
}
}
static void bake_ibuf_normalize_displacement(ImBuf *ibuf,
const float *displacement,
const char *mask,
float displacement_min,
float displacement_max)
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
{
int i;
const float *current_displacement = displacement;
const char *current_mask = mask;
float max_distance;
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
max_distance = max_ff(fabsf(displacement_min), fabsf(displacement_max));
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
for (i = 0; i < ibuf->x * ibuf->y; i++) {
if (*current_mask == FILTER_MASK_USED) {
float normalized_displacement;
2019-04-22 09:08:06 +10:00
if (max_distance > 1e-5f) {
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
normalized_displacement = (*current_displacement + max_distance) / (max_distance * 2);
2019-04-22 09:08:06 +10:00
}
else {
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
normalized_displacement = 0.5f;
2019-04-22 09:08:06 +10:00
}
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
if (ibuf->rect_float) {
/* currently baking happens to RGBA only */
float *fp = ibuf->rect_float + i * 4;
fp[0] = fp[1] = fp[2] = normalized_displacement;
fp[3] = 1.0f;
}
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
if (ibuf->rect) {
uchar *cp = (uchar *)(ibuf->rect + i);
2018-05-07 18:02:48 +02:00
cp[0] = cp[1] = cp[2] = unit_float_to_uchar_clamp(normalized_displacement);
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
cp[3] = 255;
}
}
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
current_displacement++;
current_mask++;
}
}
/* **************** Common functions public API relates on **************** */
static void count_images(MultiresBakeRender *bkr)
{
BLI_listbase_clear(&bkr->image);
bkr->tot_image = 0;
for (int i = 0; i < bkr->ob_image.len; i++) {
Image *ima = bkr->ob_image.array[i];
if (ima) {
ima->id.tag &= ~LIB_TAG_DOIT;
}
}
for (int i = 0; i < bkr->ob_image.len; i++) {
Image *ima = bkr->ob_image.array[i];
if (ima) {
if ((ima->id.tag & LIB_TAG_DOIT) == 0) {
LinkData *data = BLI_genericNodeN(ima);
BLI_addtail(&bkr->image, data);
bkr->tot_image++;
ima->id.tag |= LIB_TAG_DOIT;
}
}
}
for (int i = 0; i < bkr->ob_image.len; i++) {
Image *ima = bkr->ob_image.array[i];
if (ima) {
ima->id.tag &= ~LIB_TAG_DOIT;
}
}
}
static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
{
LinkData *link;
for (link = static_cast<LinkData *>(bkr->image.first); link; link = link->next) {
Image *ima = (Image *)link->data;
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
ImageUser iuser;
BKE_imageuser_default(&iuser);
iuser.tile = tile->tile_number;
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, nullptr);
if (ibuf->x > 0 && ibuf->y > 0) {
BakeImBufuserData *userdata = MEM_cnew<BakeImBufuserData>("MultiresBake userdata");
userdata->mask_buffer = MEM_cnew_array<char>(ibuf->y * ibuf->x, "MultiresBake imbuf mask");
ibuf->userdata = userdata;
switch (bkr->mode) {
case RE_BAKE_NORMALS:
do_multires_bake(bkr,
ima,
tile,
ibuf,
true,
apply_tangmat_callback,
init_normal_data,
free_normal_data,
result);
break;
case RE_BAKE_DISPLACEMENT:
do_multires_bake(bkr,
ima,
tile,
ibuf,
false,
apply_heights_callback,
init_heights_data,
free_heights_data,
result);
break;
/* TODO: restore ambient occlusion baking support. */
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
#if 0
case RE_BAKE_AO:
do_multires_bake(bkr, ima, tile, ibuf, false, apply_ao_callback, init_ao_data, free_ao_data, result);
break;
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
#endif
}
}
BKE_image_release_ibuf(ima, ibuf, nullptr);
}
ima->id.tag |= LIB_TAG_DOIT;
}
}
static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
{
LinkData *link;
Remove Blender Internal and legacy viewport from Blender 2.8. Brecht authored this commit, but he gave me the honours to actually do it. Here it goes; Blender Internal. Bye bye, you did great! * Point density, voxel data, ocean, environment map textures were removed, as these only worked within BI rendering. Note that the ocean modifier and the Cycles point density shader node continue to work. * Dynamic paint using material shading was removed, as this only worked with BI. If we ever wanted to support this again probably it should go through the baking API. * GPU shader export through the Python API was removed. This only worked for the old BI GLSL shaders, which no longer exists. Doing something similar for Eevee would be significantly more complicated because it uses a lot of multiplass rendering and logic outside the shader, it's probably impractical. * Collada material import / export code is mostly gone, as it only worked for BI materials. We need to add Cycles / Eevee material support at some point. * The mesh noise operator was removed since it only worked with BI material texture slots. A displacement modifier can be used instead. * The delete texture paint slot operator was removed since it only worked for BI material texture slots. Could be added back with node support. * Not all legacy viewport features are supported in the new viewport, but their code was removed. If we need to bring anything back we can look at older git revisions. * There is some legacy viewport code that I could not remove yet, and some that I probably missed. * Shader node execution code was left mostly intact, even though it is not used anywhere now. We may eventually use this to replace the texture nodes with Cycles / Eevee shader nodes. * The Cycles Bake panel now includes settings for baking multires normal and displacement maps. The underlying code needs to be merged properly, and we plan to add back support for multires AO baking and add support to Cycles baking for features like vertex color, displacement, and other missing baking features. * This commit removes DNA and the Python API for BI material, lamp, world and scene settings. This breaks a lot of addons. * There is more DNA that can be removed or renamed, where Cycles or Eevee are reusing some old BI properties but the names are not really correct anymore. * Texture slots for materials, lamps and world were removed. They remain for brushes, particles and freestyle linestyles. * 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and other renderers use this to find all panels to show, minus a few panels that they have their own replacement for.
2018-04-19 17:34:44 +02:00
bool use_displacement_buffer = bkr->mode == RE_BAKE_DISPLACEMENT;
for (link = static_cast<LinkData *>(bkr->image.first); link; link = link->next) {
Image *ima = (Image *)link->data;
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
ImageUser iuser;
BKE_imageuser_default(&iuser);
iuser.tile = tile->tile_number;
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, nullptr);
BakeImBufuserData *userdata = (BakeImBufuserData *)ibuf->userdata;
if (ibuf->x <= 0 || ibuf->y <= 0) {
continue;
}
if (use_displacement_buffer) {
bake_ibuf_normalize_displacement(ibuf,
userdata->displacement_buffer,
userdata->mask_buffer,
result->height_min,
result->height_max);
}
float uv_offset[2];
BKE_image_get_tile_uv(ima, tile->tile_number, uv_offset);
bake_ibuf_filter(ibuf,
userdata->mask_buffer,
bkr->bake_margin,
bkr->bake_margin_type,
bkr->lores_dm,
uv_offset);
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
BKE_image_mark_dirty(ima, ibuf);
if (ibuf->rect_float) {
ibuf->userflags |= IB_RECT_INVALID;
2019-04-22 09:08:06 +10:00
}
if (ibuf->mipmap[0]) {
ibuf->userflags |= IB_MIPMAP_INVALID;
imb_freemipmapImBuf(ibuf);
}
if (ibuf->userdata) {
if (userdata->displacement_buffer) {
MEM_freeN(userdata->displacement_buffer);
}
MEM_freeN(userdata->mask_buffer);
MEM_freeN(userdata);
ibuf->userdata = nullptr;
}
BKE_image_release_ibuf(ima, ibuf, nullptr);
DEG_id_tag_update(&ima->id, 0);
}
}
}
void RE_multires_bake_images(MultiresBakeRender *bkr)
{
MultiresBakeResult result;
count_images(bkr);
bake_images(bkr, &result);
finish_images(bkr, &result);
}