2023-08-16 00:20:26 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2012 Blender Authors
|
2023-05-31 16:19:06 +02:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup render
|
2012-12-18 17:46:26 +00:00
|
|
|
*/
|
|
|
|
|
|
2022-12-29 12:01:32 -05:00
|
|
|
#include <cstring>
|
2012-12-18 17:46:26 +00:00
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.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"
|
2012-12-18 17:46:26 +00:00
|
|
|
|
|
|
|
|
#include "BLI_listbase.h"
|
Cleanup: reduce amount of math-related includes
Using ClangBuildAnalyzer on the whole Blender build, it was pointing
out that BLI_math.h is the heaviest "header hub" (i.e. non tiny file
that is included a lot).
However, there's very little (actually zero) source files in Blender
that need "all the math" (base, colors, vectors, matrices,
quaternions, intersection, interpolation, statistics, solvers and
time). A common use case is source files needing just vectors, or
just vectors & matrices, or just colors etc. Actually, 181 files
were including the whole math thing without needing it at all.
This change removes BLI_math.h completely, and instead in all the
places that need it, includes BLI_math_vector.h or BLI_math_color.h
and so on.
Change from that:
- BLI_math_color.h was included 1399 times -> now 408 (took 114.0sec
to parse -> now 36.3sec)
- BLI_simd.h 1403 -> 418 (109.7sec -> 34.9sec).
Full rebuild of Blender (Apple M1, Xcode, RelWithDebInfo) is not
affected much (342sec -> 334sec). Most of benefit would be when
someone's changing BLI_simd.h or BLI_math_color.h or similar files,
that now there's 3x fewer files result in a recompile.
Pull Request #110944
2023-08-09 11:39:20 +03:00
|
|
|
#include "BLI_math_color.h"
|
|
|
|
|
#include "BLI_math_geom.h"
|
|
|
|
|
#include "BLI_math_matrix.h"
|
2012-12-19 08:13:41 +00:00
|
|
|
#include "BLI_threads.h"
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2024-04-29 21:07:25 +02:00
|
|
|
#include "BKE_attribute.hh"
|
2024-05-30 09:43:56 -04:00
|
|
|
#include "BKE_ccg.hh"
|
2023-12-26 23:21:19 -05:00
|
|
|
#include "BKE_customdata.hh"
|
2024-02-10 18:25:14 +01:00
|
|
|
#include "BKE_global.hh"
|
2012-12-18 17:46:26 +00:00
|
|
|
#include "BKE_image.h"
|
2024-01-15 12:44:04 -05:00
|
|
|
#include "BKE_lib_id.hh"
|
2023-03-12 22:29:15 +01:00
|
|
|
#include "BKE_mesh.hh"
|
2024-05-20 12:53:28 -04:00
|
|
|
#include "BKE_mesh_legacy_derived_mesh.hh"
|
2023-08-02 22:14:18 +02:00
|
|
|
#include "BKE_mesh_tangent.hh"
|
2023-11-14 09:30:40 +01:00
|
|
|
#include "BKE_modifier.hh"
|
2023-08-02 22:14:18 +02:00
|
|
|
#include "BKE_multires.hh"
|
|
|
|
|
#include "BKE_subsurf.hh"
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2023-09-22 03:18:17 +02:00
|
|
|
#include "DEG_depsgraph.hh"
|
2017-04-06 16:38:43 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
#include "RE_multires_bake.h"
|
|
|
|
|
#include "RE_pipeline.h"
|
2022-01-17 18:00:35 +01:00
|
|
|
#include "RE_texture_margin.h"
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2024-01-18 22:50:23 +02:00
|
|
|
#include "IMB_imbuf.hh"
|
|
|
|
|
#include "IMB_imbuf_types.hh"
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2023-04-04 11:26:14 -04:00
|
|
|
using MPassKnownData = void (*)(blender::Span<blender::float3> vert_positions,
|
|
|
|
|
blender::Span<blender::float3> vert_normals,
|
2023-07-24 22:06:55 +02:00
|
|
|
blender::OffsetIndices<int> faces,
|
2023-04-04 11:26:14 -04:00
|
|
|
blender::Span<int> corner_verts,
|
2023-12-19 14:57:49 +01:00
|
|
|
blender::Span<blender::int3> corner_tris,
|
|
|
|
|
blender::Span<int> tri_faces,
|
2023-04-04 11:26:14 -04:00
|
|
|
blender::Span<blender::float2> uv_map,
|
2022-12-29 12:01:32 -05:00
|
|
|
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 {
|
2013-01-21 18:34:27 +00:00
|
|
|
float height_min, height_max;
|
2022-12-29 12:01:32 -05:00
|
|
|
};
|
2013-01-21 18:34:27 +00:00
|
|
|
|
2022-12-29 12:01:32 -05:00
|
|
|
struct MResolvePixelData {
|
2023-04-04 11:26:14 -04:00
|
|
|
/* Data from low-resolution mesh. */
|
|
|
|
|
blender::Span<blender::float3> vert_positions;
|
2023-07-24 22:06:55 +02:00
|
|
|
blender::OffsetIndices<int> faces;
|
2023-04-04 11:26:14 -04:00
|
|
|
blender::Span<int> corner_verts;
|
2023-12-19 14:57:49 +01:00
|
|
|
blender::Span<blender::int3> corner_tris;
|
|
|
|
|
blender::Span<int> tri_faces;
|
2023-04-04 11:26:14 -04:00
|
|
|
blender::Span<blender::float3> vert_normals;
|
2023-07-24 22:06:55 +02:00
|
|
|
blender::Span<blender::float3> face_normals;
|
2023-04-04 11:26:14 -04:00
|
|
|
|
|
|
|
|
blender::Span<blender::float2> uv_map;
|
|
|
|
|
|
|
|
|
|
/* May be null. */
|
2022-08-31 09:09:01 -05:00
|
|
|
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;
|
2023-04-04 11:26:14 -04:00
|
|
|
|
2022-04-22 20:44:49 +02:00
|
|
|
float uv_offset[2];
|
2012-12-18 17:46:26 +00:00
|
|
|
float *pvtangent;
|
|
|
|
|
int w, h;
|
2015-07-30 14:43:58 +02:00
|
|
|
int tri_index;
|
2023-04-04 11:26:14 -04:00
|
|
|
|
|
|
|
|
DerivedMesh *hires_dm;
|
|
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
int lvl;
|
2013-01-21 18:34:27 +00:00
|
|
|
void *thread_data;
|
2012-12-18 17:46:26 +00:00
|
|
|
void *bake_data;
|
|
|
|
|
ImBuf *ibuf;
|
|
|
|
|
MPassKnownData pass_data;
|
2017-05-24 23:14:32 +10:00
|
|
|
/* material aligned UV array */
|
|
|
|
|
Image **image_array;
|
2022-12-29 12:01:32 -05:00
|
|
|
};
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2022-12-29 12:01:32 -05:00
|
|
|
using MFlushPixel = void (*)(const MResolvePixelData *data, const int x, const int y);
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2022-12-29 12:01:32 -05:00
|
|
|
struct MBakeRast {
|
2012-12-18 17:46:26 +00:00
|
|
|
int w, h;
|
|
|
|
|
char *texels;
|
|
|
|
|
const MResolvePixelData *data;
|
|
|
|
|
MFlushPixel flush_pixel;
|
2022-11-04 18:37:25 +11:00
|
|
|
bool *do_update;
|
2022-12-29 12:01:32 -05:00
|
|
|
};
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2022-12-29 12:01:32 -05:00
|
|
|
struct MHeightBakeData {
|
2012-12-18 17:46:26 +00:00
|
|
|
float *heights;
|
|
|
|
|
DerivedMesh *ssdm;
|
|
|
|
|
const int *orig_index_mp_to_orig;
|
2022-12-29 12:01:32 -05:00
|
|
|
};
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2022-12-29 12:01:32 -05:00
|
|
|
struct MNormalBakeData {
|
2012-12-18 17:46:26 +00:00
|
|
|
const int *orig_index_mp_to_orig;
|
2022-12-29 12:01:32 -05:00
|
|
|
};
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2022-12-29 12:01:32 -05:00
|
|
|
struct BakeImBufuserData {
|
2020-11-09 15:42:38 +01:00
|
|
|
float *displacement_buffer;
|
|
|
|
|
char *mask_buffer;
|
2022-12-29 12:01:32 -05:00
|
|
|
};
|
2020-11-09 15:42:38 +01:00
|
|
|
|
2019-03-25 11:55:36 +11:00
|
|
|
static void multiresbake_get_normal(const MResolvePixelData *data,
|
|
|
|
|
const int tri_num,
|
2022-03-21 17:11:39 -05:00
|
|
|
const int vert_index,
|
|
|
|
|
float r_normal[3])
|
2012-12-18 17:46:26 +00:00
|
|
|
{
|
2023-12-19 14:57:49 +01:00
|
|
|
const int face_index = data->tri_faces[tri_num];
|
2023-07-24 22:06:55 +02:00
|
|
|
const bool smoothnormal = !(data->sharp_faces && data->sharp_faces[face_index]);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-21 17:11:39 -05:00
|
|
|
if (smoothnormal) {
|
2023-12-19 14:57:49 +01:00
|
|
|
const int vi = data->corner_verts[data->corner_tris[tri_num][vert_index]];
|
2022-03-21 17:11:39 -05:00
|
|
|
copy_v3_v3(r_normal, data->vert_normals[vi]);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2023-07-24 22:06:55 +02:00
|
|
|
copy_v3_v3(r_normal, data->face_normals[face_index]);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-17 18:29:01 +00:00
|
|
|
static void init_bake_rast(MBakeRast *bake_rast,
|
|
|
|
|
const ImBuf *ibuf,
|
|
|
|
|
const MResolvePixelData *data,
|
|
|
|
|
MFlushPixel flush_pixel,
|
2022-11-04 18:37:25 +11:00
|
|
|
bool *do_update)
|
2012-12-18 17:46:26 +00:00
|
|
|
{
|
2019-03-25 11:55:36 +11:00
|
|
|
BakeImBufuserData *userdata = (BakeImBufuserData *)ibuf->userdata;
|
2013-01-21 18:34:27 +00:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
memset(bake_rast, 0, sizeof(MBakeRast));
|
|
|
|
|
|
2013-01-21 18:34:27 +00:00
|
|
|
bake_rast->texels = userdata->mask_buffer;
|
2012-12-18 17:46:26 +00:00
|
|
|
bake_rast->w = ibuf->x;
|
|
|
|
|
bake_rast->h = ibuf->y;
|
|
|
|
|
bake_rast->data = data;
|
|
|
|
|
bake_rast->flush_pixel = flush_pixel;
|
2013-10-17 18:29:01 +00:00
|
|
|
bake_rast->do_update = do_update;
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
|
|
|
|
|
{
|
2022-04-22 20:44:49 +02:00
|
|
|
const float st[2] = {(x + 0.5f) / data->w + data->uv_offset[0],
|
|
|
|
|
(y + 0.5f) / data->h + data->uv_offset[1]};
|
2014-04-27 00:22:07 +10:00
|
|
|
const float *st0, *st1, *st2;
|
|
|
|
|
const float *tang0, *tang1, *tang2;
|
2012-12-18 17:46:26 +00:00
|
|
|
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;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-12-19 14:57:49 +01:00
|
|
|
st0 = data->uv_map[data->corner_tris[data->tri_index][0]];
|
|
|
|
|
st1 = data->uv_map[data->corner_tris[data->tri_index][1]];
|
|
|
|
|
st2 = data->uv_map[data->corner_tris[data->tri_index][2]];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-21 17:11:39 -05:00
|
|
|
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);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-03-26 11:15:21 +11:00
|
|
|
resolve_tri_uv_v2(fUV, st, st0, st1, st2);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
u = fUV[0];
|
|
|
|
|
v = fUV[1];
|
|
|
|
|
w = 1 - u - v;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
if (data->pvtangent) {
|
2023-12-19 14:57:49 +01:00
|
|
|
tang0 = data->pvtangent + data->corner_tris[data->tri_index][0] * 4;
|
|
|
|
|
tang1 = data->pvtangent + data->corner_tris[data->tri_index][1] * 4;
|
|
|
|
|
tang2 = data->pvtangent + data->corner_tris[data->tri_index][2] * 4;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
/* 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;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
/* 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;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-24 15:56:58 +10:00
|
|
|
cross_v3_v3v3(from_tang[1], from_tang[2], from_tang[0]); /* `B = sign * cross(N, T)` */
|
2012-12-18 17:46:42 +00:00
|
|
|
mul_v3_fl(from_tang[1], sign);
|
|
|
|
|
invert_m3_m3(to_tang, from_tang);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
zero_m3(to_tang);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-04-04 11:26:14 -04:00
|
|
|
data->pass_data(data->vert_positions,
|
|
|
|
|
data->vert_normals,
|
2023-07-24 22:06:55 +02:00
|
|
|
data->faces,
|
2023-04-04 11:26:14 -04:00
|
|
|
data->corner_verts,
|
2023-12-19 14:57:49 +01:00
|
|
|
data->corner_tris,
|
|
|
|
|
data->tri_faces,
|
2023-04-04 11:26:14 -04:00
|
|
|
data->uv_map,
|
2013-01-21 18:34:27 +00:00
|
|
|
data->hires_dm,
|
|
|
|
|
data->thread_data,
|
|
|
|
|
data->bake_data,
|
2015-07-30 14:43:58 +02:00
|
|
|
data->ibuf,
|
|
|
|
|
data->tri_index,
|
|
|
|
|
data->lvl,
|
|
|
|
|
st,
|
|
|
|
|
to_tang,
|
|
|
|
|
x,
|
|
|
|
|
y);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
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;
|
2012-12-23 18:58:10 +00:00
|
|
|
flush_pixel(bake_rast->data, x, y);
|
2013-10-17 18:29:01 +00:00
|
|
|
if (bake_rast->do_update) {
|
|
|
|
|
*bake_rast->do_update = true;
|
|
|
|
|
}
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:08:06 +10:00
|
|
|
if (y1_in <= 0 || y0_in >= h) {
|
2012-12-18 17:46:26 +00:00
|
|
|
return;
|
2019-04-22 09:08:06 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
y0 = y0_in < 0 ? 0 : y0_in;
|
|
|
|
|
y1 = y1_in >= h ? h : y1_in;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
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-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:08:06 +10:00
|
|
|
if (is_mid_right != 0) {
|
2023-01-09 23:26:32 -05:00
|
|
|
std::swap(x_l, x_r);
|
2019-04-22 09:08:06 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-01-03 11:04:16 +11:00
|
|
|
iXl = int(ceilf(x_l));
|
|
|
|
|
iXr = int(ceilf(x_r));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
if (iXr > 0 && iXl < w) {
|
|
|
|
|
iXl = iXl < 0 ? 0 : iXl;
|
|
|
|
|
iXr = iXr >= w ? w : iXr;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:08:06 +10:00
|
|
|
for (x = iXl; x < iXr; x++) {
|
2012-12-18 17:46:26 +00:00
|
|
|
set_rast_triangle(bake_rast, x, y);
|
2019-04-22 09:08:06 +10:00
|
|
|
}
|
2012-12-18 17:46:26 +00: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;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
/* skip degenerates */
|
2019-04-22 09:08:06 +10:00
|
|
|
if ((slo == smi && tlo == tmi) || (slo == shi && tlo == thi) || (smi == shi && tmi == thi)) {
|
2012-12-18 17:46:26 +00:00
|
|
|
return;
|
2019-04-22 09:08:06 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
/* sort by T */
|
|
|
|
|
if (tlo > tmi && tlo > thi) {
|
2023-01-09 23:26:32 -05:00
|
|
|
std::swap(shi, slo);
|
|
|
|
|
std::swap(thi, tlo);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
else if (tmi > thi) {
|
2023-01-09 23:26:32 -05:00
|
|
|
std::swap(shi, smi);
|
|
|
|
|
std::swap(thi, tmi);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
if (tlo > tmi) {
|
2023-01-09 23:26:32 -05:00
|
|
|
std::swap(slo, smi);
|
|
|
|
|
std::swap(tlo, tmi);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
/* 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;
|
2023-01-03 11:04:16 +11:00
|
|
|
ylo = int(ceilf(tlo));
|
|
|
|
|
yhi_beg = int(ceilf(tmi));
|
|
|
|
|
yhi = int(ceilf(thi));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-06-26 21:35:18 +10:00
|
|
|
// if (fTmi>ceilf(fTlo))
|
2012-12-18 17:46:26 +00:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-19 08:13:41 +00:00
|
|
|
return *bkr->stop || G.is_break;
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
|
2012-12-19 08:13:41 +00:00
|
|
|
/* **** Threading routines **** */
|
|
|
|
|
|
2022-12-29 12:01:32 -05:00
|
|
|
struct MultiresBakeQueue {
|
2015-07-30 14:43:58 +02:00
|
|
|
int cur_tri;
|
|
|
|
|
int tot_tri;
|
2012-12-19 08:13:41 +00:00
|
|
|
SpinLock spin;
|
2022-12-29 12:01:32 -05:00
|
|
|
};
|
2012-12-19 08:13:41 +00:00
|
|
|
|
2022-12-29 12:01:32 -05:00
|
|
|
struct MultiresBakeThread {
|
2012-12-19 08:13:41 +00:00
|
|
|
/* this data is actually shared between all the threads */
|
|
|
|
|
MultiresBakeQueue *queue;
|
|
|
|
|
MultiresBakeRender *bkr;
|
|
|
|
|
Image *image;
|
|
|
|
|
void *bake_data;
|
2023-06-16 18:40:18 +02:00
|
|
|
int num_total_faces;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-19 08:13:41 +00:00
|
|
|
/* thread-specific data */
|
|
|
|
|
MBakeRast bake_rast;
|
|
|
|
|
MResolvePixelData data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-01-21 18:34:27 +00:00
|
|
|
/* displacement-specific data */
|
|
|
|
|
float height_min, height_max;
|
2022-12-29 12:01:32 -05:00
|
|
|
};
|
2012-12-19 08:13:41 +00:00
|
|
|
|
2015-07-30 14:43:58 +02:00
|
|
|
static int multires_bake_queue_next_tri(MultiresBakeQueue *queue)
|
2012-12-18 17:46:26 +00:00
|
|
|
{
|
2012-12-19 08:13:41 +00:00
|
|
|
int face = -1;
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2012-12-19 08:13:41 +00:00
|
|
|
/* TODO: it could worth making it so thread will handle neighbor faces
|
|
|
|
|
* for better memory cache utilization
|
|
|
|
|
*/
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2012-12-19 08:13:41 +00:00
|
|
|
BLI_spin_lock(&queue->spin);
|
2015-07-30 14:43:58 +02:00
|
|
|
if (queue->cur_tri < queue->tot_tri) {
|
|
|
|
|
face = queue->cur_tri;
|
|
|
|
|
queue->cur_tri++;
|
2012-12-18 17:46:42 +00:00
|
|
|
}
|
2012-12-19 08:13:41 +00:00
|
|
|
BLI_spin_unlock(&queue->spin);
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2012-12-19 08:13:41 +00:00
|
|
|
return face;
|
|
|
|
|
}
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2012-12-19 08:13:41 +00:00
|
|
|
static void *do_multires_bake_thread(void *data_v)
|
|
|
|
|
{
|
2019-03-25 11:55:36 +11:00
|
|
|
MultiresBakeThread *handle = (MultiresBakeThread *)data_v;
|
2012-12-19 08:13:41 +00:00
|
|
|
MResolvePixelData *data = &handle->data;
|
|
|
|
|
MBakeRast *bake_rast = &handle->bake_rast;
|
|
|
|
|
MultiresBakeRender *bkr = handle->bkr;
|
2015-07-30 14:43:58 +02:00
|
|
|
int tri_index;
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2015-07-30 14:43:58 +02:00
|
|
|
while ((tri_index = multires_bake_queue_next_tri(handle->queue)) >= 0) {
|
2023-12-19 14:57:49 +01:00
|
|
|
const blender::int3 &tri = data->corner_tris[tri_index];
|
|
|
|
|
const int face_i = data->tri_faces[tri_index];
|
2023-07-24 22:06:55 +02:00
|
|
|
const short mat_nr = data->material_indices == nullptr ? 0 : data->material_indices[face_i];
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2019-04-22 09:08:06 +10:00
|
|
|
if (multiresbake_test_break(bkr)) {
|
2012-12-19 08:13:41 +00:00
|
|
|
break;
|
2019-04-22 09:08:06 +10:00
|
|
|
}
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2022-12-02 12:34:26 +01: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) {
|
2012-12-19 08:13:41 +00:00
|
|
|
continue;
|
2019-04-22 09:08:06 +10:00
|
|
|
}
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2015-07-30 14:43:58 +02:00
|
|
|
data->tri_index = tri_index;
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2022-04-22 20:44:49 +02:00
|
|
|
float uv[3][2];
|
2023-12-19 14:57:49 +01:00
|
|
|
sub_v2_v2v2(uv[0], data->uv_map[tri[0]], data->uv_offset);
|
|
|
|
|
sub_v2_v2v2(uv[1], data->uv_map[tri[1]], data->uv_offset);
|
|
|
|
|
sub_v2_v2v2(uv[2], data->uv_map[tri[2]], data->uv_offset);
|
2022-04-22 20:44:49 +02:00
|
|
|
|
|
|
|
|
bake_rasterize(bake_rast, uv[0], uv[1], uv[2]);
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2015-07-30 14:43:58 +02:00
|
|
|
/* tag image buffer for refresh */
|
2023-05-18 10:19:01 +02:00
|
|
|
if (data->ibuf->float_buffer.data) {
|
2015-07-30 14:43:58 +02:00
|
|
|
data->ibuf->userflags |= IB_RECT_INVALID;
|
2019-04-22 09:08:06 +10:00
|
|
|
}
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2015-07-30 14:43:58 +02:00
|
|
|
data->ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
|
2012-12-18 17:46:48 +00:00
|
|
|
|
2012-12-19 08:13:41 +00:00
|
|
|
/* update progress */
|
|
|
|
|
BLI_spin_lock(&handle->queue->spin);
|
|
|
|
|
bkr->baked_faces++;
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2019-04-22 09:08:06 +10:00
|
|
|
if (bkr->do_update) {
|
2014-04-01 11:34:00 +11:00
|
|
|
*bkr->do_update = true;
|
2019-04-22 09:08:06 +10:00
|
|
|
}
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2019-04-22 09:08:06 +10:00
|
|
|
if (bkr->progress) {
|
2022-12-08 13:04:50 +11:00
|
|
|
*bkr->progress = (float(bkr->baked_objects) +
|
2023-06-16 18:40:18 +02:00
|
|
|
float(bkr->baked_faces) / handle->num_total_faces) /
|
2015-07-30 14:43:58 +02:00
|
|
|
bkr->tot_obj;
|
2019-04-22 09:08:06 +10:00
|
|
|
}
|
2012-12-19 08:13:41 +00:00
|
|
|
BLI_spin_unlock(&handle->queue->spin);
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-02 12:34:26 +01:00
|
|
|
return nullptr;
|
2012-12-19 08:13:41 +00:00
|
|
|
}
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2013-01-21 18:34:14 +00:00
|
|
|
/* 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;
|
2014-04-27 00:22:07 +10:00
|
|
|
const int *grid_offset;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-01-21 18:34:14 +00:00
|
|
|
grid_size = dm->getGridSize(dm);
|
|
|
|
|
grid_data = dm->getGridData(dm);
|
|
|
|
|
grid_offset = dm->getGridOffset(dm);
|
|
|
|
|
dm->getGridKey(dm, &key);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-25 11:55:36 +11:00
|
|
|
(void)grid_size;
|
|
|
|
|
(void)grid_data;
|
|
|
|
|
(void)grid_offset;
|
2013-01-21 18:34:14 +00:00
|
|
|
}
|
|
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
static void do_multires_bake(MultiresBakeRender *bkr,
|
|
|
|
|
Image *ima,
|
2022-04-22 20:44:49 +02:00
|
|
|
ImageTile *tile,
|
|
|
|
|
ImBuf *ibuf,
|
2014-04-01 11:34:00 +11:00
|
|
|
bool require_tangent,
|
|
|
|
|
MPassKnownData passKnownData,
|
2013-01-21 18:34:27 +00:00
|
|
|
MInitBakeData initBakeData,
|
|
|
|
|
MFreeBakeData freeBakeData,
|
|
|
|
|
MultiresBakeResult *result)
|
2012-12-19 08:13:41 +00:00
|
|
|
{
|
2024-05-10 18:23:13 -04:00
|
|
|
using namespace blender;
|
2012-12-19 08:13:41 +00:00
|
|
|
DerivedMesh *dm = bkr->lores_dm;
|
|
|
|
|
const int lvl = bkr->lvl;
|
2023-04-04 11:26:14 -04:00
|
|
|
if (dm->getNumPolys(dm) == 0) {
|
2022-05-09 23:59:19 +02:00
|
|
|
return;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-09 23:59:19 +02:00
|
|
|
MultiresBakeQueue queue;
|
|
|
|
|
|
2024-05-10 18:23:13 -04:00
|
|
|
const Span<float2> uv_map(
|
|
|
|
|
reinterpret_cast<const float2 *>(dm->getLoopDataArray(dm, CD_PROP_FLOAT2)),
|
2023-04-04 11:26:14 -04:00
|
|
|
dm->getNumLoops(dm));
|
|
|
|
|
|
2023-03-21 19:46:13 +11:00
|
|
|
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();
|
|
|
|
|
|
2022-12-02 12:34:26 +01:00
|
|
|
void *bake_data = nullptr;
|
2022-05-09 23:59:19 +02:00
|
|
|
|
|
|
|
|
Mesh *temp_mesh = BKE_mesh_new_nomain(
|
2023-04-19 15:28:53 -04:00
|
|
|
dm->getNumVerts(dm), dm->getNumEdges(dm), dm->getNumPolys(dm), dm->getNumLoops(dm));
|
2023-04-04 11:26:14 -04:00
|
|
|
temp_mesh->vert_positions_for_write().copy_from(
|
2024-05-10 18:23:13 -04:00
|
|
|
{reinterpret_cast<const float3 *>(dm->getVertArray(dm)), temp_mesh->verts_num});
|
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(
|
2024-05-10 18:23:13 -04:00
|
|
|
{reinterpret_cast<const int2 *>(dm->getEdgeArray(dm)), temp_mesh->edges_num});
|
2023-07-24 22:06:55 +02:00
|
|
|
temp_mesh->face_offsets_for_write().copy_from({dm->getPolyArray(dm), temp_mesh->faces_num + 1});
|
2023-12-20 02:21:48 +01:00
|
|
|
temp_mesh->corner_verts_for_write().copy_from(
|
|
|
|
|
{dm->getCornerVertArray(dm), temp_mesh->corners_num});
|
|
|
|
|
temp_mesh->corner_edges_for_write().copy_from(
|
|
|
|
|
{dm->getCornerEdgeArray(dm), temp_mesh->corners_num});
|
2023-04-04 11:26:14 -04:00
|
|
|
|
2024-05-10 18:23:13 -04:00
|
|
|
const Span<float3> positions = temp_mesh->vert_positions();
|
|
|
|
|
const OffsetIndices faces = temp_mesh->faces();
|
|
|
|
|
const Span<int> corner_verts = temp_mesh->corner_verts();
|
|
|
|
|
const Span<float3> vert_normals = temp_mesh->vert_normals();
|
|
|
|
|
const Span<float3> face_normals = temp_mesh->face_normals();
|
|
|
|
|
const Span<int3> corner_tris = temp_mesh->corner_tris();
|
|
|
|
|
const Span<int> tri_faces = temp_mesh->corner_tri_faces();
|
2022-05-09 23:59:19 +02:00
|
|
|
|
|
|
|
|
if (require_tangent) {
|
|
|
|
|
if (CustomData_get_layer_index(&dm->loopData, CD_TANGENT) == -1) {
|
2024-04-29 21:07:25 +02:00
|
|
|
const bool *sharp_edges = static_cast<const bool *>(
|
|
|
|
|
CustomData_get_layer_named(&dm->edgeData, CD_PROP_BOOL, "sharp_edge"));
|
2023-12-12 17:49:51 -05:00
|
|
|
const bool *sharp_faces = static_cast<const bool *>(
|
|
|
|
|
CustomData_get_layer_named(&dm->polyData, CD_PROP_BOOL, "sharp_face"));
|
2024-04-29 21:07:25 +02:00
|
|
|
|
|
|
|
|
/* Copy sharp faces and edges, for corner normals domain and tangents
|
|
|
|
|
* to be computed correctly. */
|
|
|
|
|
if (sharp_edges) {
|
2024-05-10 18:23:13 -04:00
|
|
|
bke::MutableAttributeAccessor attributes = temp_mesh->attributes_for_write();
|
2024-04-29 21:07:25 +02:00
|
|
|
attributes.add<bool>("sharp_edge",
|
2024-05-10 18:23:13 -04:00
|
|
|
bke::AttrDomain::Edge,
|
|
|
|
|
bke::AttributeInitVArray(VArray<bool>::ForSpan(
|
|
|
|
|
Span<bool>(sharp_edges, temp_mesh->edges_num))));
|
2024-04-29 21:07:25 +02:00
|
|
|
}
|
|
|
|
|
if (sharp_faces) {
|
2024-05-10 18:23:13 -04:00
|
|
|
bke::MutableAttributeAccessor attributes = temp_mesh->attributes_for_write();
|
2024-04-29 21:07:25 +02:00
|
|
|
attributes.add<bool>("sharp_face",
|
2024-05-10 18:23:13 -04:00
|
|
|
bke::AttrDomain::Face,
|
|
|
|
|
bke::AttributeInitVArray(VArray<bool>::ForSpan(
|
|
|
|
|
Span<bool>(sharp_faces, temp_mesh->faces_num))));
|
2024-04-29 21:07:25 +02:00
|
|
|
}
|
|
|
|
|
|
2024-05-10 18:23:13 -04:00
|
|
|
const float3 *orco = static_cast<const float3 *>(dm->getVertDataArray(dm, CD_ORCO));
|
|
|
|
|
|
|
|
|
|
const Span<float3> corner_normals = temp_mesh->corner_normals();
|
|
|
|
|
BKE_mesh_calc_loop_tangent_ex(positions,
|
|
|
|
|
faces,
|
|
|
|
|
dm->getCornerVertArray(dm),
|
|
|
|
|
corner_tris.data(),
|
|
|
|
|
tri_faces.data(),
|
|
|
|
|
corner_tris.size(),
|
|
|
|
|
sharp_faces ? Span(sharp_faces, faces.size()) : Span<bool>(),
|
|
|
|
|
&dm->loopData,
|
|
|
|
|
true,
|
|
|
|
|
nullptr,
|
|
|
|
|
0,
|
|
|
|
|
vert_normals,
|
|
|
|
|
face_normals,
|
|
|
|
|
corner_normals,
|
|
|
|
|
orco ? Span(orco, positions.size()) : Span<float3>(),
|
|
|
|
|
/* result */
|
|
|
|
|
&dm->loopData,
|
|
|
|
|
dm->getNumLoops(dm),
|
|
|
|
|
&dm->tangent_mask);
|
2012-12-19 08:13:41 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-12-02 12:34:26 +01:00
|
|
|
pvtangent = static_cast<float *>(DM_get_loop_data_layer(dm, CD_TANGENT));
|
2022-05-09 23:59:19 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +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);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-09 23:59:19 +02:00
|
|
|
if (tot_thread > 1) {
|
|
|
|
|
BLI_threadpool_init(&threads, do_multires_bake_thread, tot_thread);
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-10 18:23:13 -04:00
|
|
|
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;
|
2023-12-19 14:57:49 +01:00
|
|
|
queue.tot_tri = corner_tris.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;
|
2023-06-16 18:40:18 +02:00
|
|
|
handle->num_total_faces = queue.tot_tri * BLI_listbase_count(&ima->tiles);
|
2022-05-09 23:59:19 +02:00
|
|
|
handle->queue = &queue;
|
|
|
|
|
|
2023-04-04 11:26:14 -04:00
|
|
|
handle->data.vert_positions = positions;
|
2023-07-24 22:06:55 +02:00
|
|
|
handle->data.faces = faces;
|
2023-04-04 11:26:14 -04:00
|
|
|
handle->data.corner_verts = corner_verts;
|
2023-12-19 14:57:49 +01:00
|
|
|
handle->data.corner_tris = corner_tris;
|
|
|
|
|
handle->data.tri_faces = tri_faces;
|
2023-04-04 11:26:14 -04:00
|
|
|
handle->data.vert_normals = vert_normals;
|
2023-07-24 22:06:55 +02:00
|
|
|
handle->data.face_normals = face_normals;
|
2022-12-02 12:34:26 +01:00
|
|
|
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"));
|
2023-04-04 11:26:14 -04:00
|
|
|
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-17 06:17:24 +02:00
|
|
|
|
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
|
|
|
}
|
2019-04-17 06:17:24 +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]);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-06-28 14:58:52 +02:00
|
|
|
for (i = 0; i < tot_thread; i++) {
|
2022-05-09 23:59:19 +02:00
|
|
|
result->height_min = min_ff(result->height_min, handles[i].height_min);
|
|
|
|
|
result->height_max = max_ff(result->height_max, handles[i].height_max);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-09 23:59:19 +02:00
|
|
|
BLI_spin_end(&queue.spin);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-09 23:59:19 +02:00
|
|
|
/* finalize baking */
|
|
|
|
|
if (freeBakeData) {
|
|
|
|
|
freeBakeData(bake_data);
|
2012-12-19 08:13:41 +00:00
|
|
|
}
|
2022-05-09 23:59:19 +02:00
|
|
|
|
2022-12-02 12:34:26 +01:00
|
|
|
BKE_id_free(nullptr, temp_mesh);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* mode = 0: interpolate normals,
|
|
|
|
|
* mode = 1: interpolate coord */
|
|
|
|
|
static void interp_bilinear_grid(
|
2024-05-30 10:04:07 -04:00
|
|
|
const CCGKey &key, CCGElem *grid, float crn_x, float crn_y, int mode, float res[3])
|
2012-12-18 17:46:26 +00:00
|
|
|
{
|
|
|
|
|
int x0, x1, y0, y1;
|
|
|
|
|
float u, v;
|
|
|
|
|
float data[4][3];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-12-08 13:04:50 +11:00
|
|
|
x0 = int(crn_x);
|
2024-05-30 10:04:07 -04:00
|
|
|
x1 = x0 >= (key.grid_size - 1) ? (key.grid_size - 1) : (x0 + 1);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-12-08 13:04:50 +11:00
|
|
|
y0 = int(crn_y);
|
2024-05-30 10:04:07 -04:00
|
|
|
y1 = y0 >= (key.grid_size - 1) ? (key.grid_size - 1) : (y0 + 1);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
u = crn_x - x0;
|
|
|
|
|
v = crn_y - y0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
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));
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
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,
|
2012-12-18 17:46:26 +00:00
|
|
|
DerivedMesh *hidm,
|
2015-07-30 14:43:58 +02:00
|
|
|
const int *index_mp_to_orig,
|
|
|
|
|
const int lvl,
|
2023-07-24 22:06:55 +02:00
|
|
|
const int face_index,
|
2015-07-30 14:43:58 +02:00
|
|
|
const float u,
|
|
|
|
|
const float v,
|
|
|
|
|
float co[3],
|
|
|
|
|
float n[3])
|
2012-12-18 17:46:26 +00:00
|
|
|
{
|
|
|
|
|
CCGElem **grid_data;
|
|
|
|
|
CCGKey key;
|
|
|
|
|
float crn_x, crn_y;
|
|
|
|
|
int grid_size, S, face_side;
|
|
|
|
|
int *grid_offset, g_index;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
grid_size = hidm->getGridSize(hidm);
|
|
|
|
|
grid_data = hidm->getGridData(hidm);
|
|
|
|
|
grid_offset = hidm->getGridOffset(hidm);
|
|
|
|
|
hidm->getGridKey(hidm, &key);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-11-18 13:05:57 +06:00
|
|
|
if (lvl == 0) {
|
2015-07-30 14:43:58 +02:00
|
|
|
face_side = (grid_size << 1) - 1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-24 22:06:55 +02:00
|
|
|
g_index = grid_offset[face_index];
|
|
|
|
|
S = mdisp_rot_face_to_crn(lores_polys[face_index].size(),
|
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
|
|
|
face_side,
|
|
|
|
|
u * (face_side - 1),
|
|
|
|
|
v * (face_side - 1),
|
|
|
|
|
&crn_x,
|
|
|
|
|
&crn_y);
|
2013-11-18 13:05:57 +06:00
|
|
|
}
|
|
|
|
|
else {
|
2015-07-30 14:43:58 +02:00
|
|
|
/* number of faces per grid side */
|
|
|
|
|
int polys_per_grid_side = (1 << (lvl - 1));
|
|
|
|
|
/* get the original cage face index */
|
2023-07-24 22:06:55 +02:00
|
|
|
int cage_face_index = index_mp_to_orig ? index_mp_to_orig[face_index] : face_index;
|
2015-07-30 14:43:58 +02:00
|
|
|
/* local offset in total cage face grids
|
2023-07-24 22:06:55 +02:00
|
|
|
* `(1 << (2 * lvl))` is number of all faces for one cage face */
|
|
|
|
|
int loc_cage_poly_ofs = face_index % (1 << (2 * lvl));
|
2015-07-30 14:43:58 +02:00
|
|
|
/* local offset in the vertex grid itself */
|
2021-03-08 14:48:45 +11:00
|
|
|
int cell_index = loc_cage_poly_ofs % (polys_per_grid_side * polys_per_grid_side);
|
2015-07-30 14:43:58 +02:00
|
|
|
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;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-30 14:43:58 +02:00
|
|
|
/* S is the vertex whose grid we are examining */
|
2023-07-24 22:06:55 +02:00
|
|
|
S = face_index / (1 << (2 * (lvl - 1))) - grid_offset[cage_face_index];
|
2015-07-30 14:43:58 +02:00
|
|
|
/* get offset of grid data for original cage face */
|
|
|
|
|
g_index = grid_offset[cage_face_index];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-11-18 13:05:57 +06:00
|
|
|
crn_y = (row * cell_side) + u * cell_side;
|
|
|
|
|
crn_x = (col * cell_side) + v * cell_side;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
CLAMP(crn_x, 0.0f, grid_size);
|
|
|
|
|
CLAMP(crn_y, 0.0f, grid_size);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-12-02 12:34:26 +01:00
|
|
|
if (n != nullptr) {
|
2024-05-30 10:04:07 -04:00
|
|
|
interp_bilinear_grid(key, grid_data[g_index + S], crn_x, crn_y, 0, n);
|
2019-04-22 09:08:06 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-12-02 12:34:26 +01:00
|
|
|
if (co != nullptr) {
|
2024-05-30 10:04:07 -04:00
|
|
|
interp_bilinear_grid(key, grid_data[g_index + S], crn_x, crn_y, 1, co);
|
2019-04-22 09:08:06 +10:00
|
|
|
}
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* mode = 0: interpolate normals,
|
|
|
|
|
* mode = 1: interpolate coord */
|
2015-07-30 14:43:58 +02:00
|
|
|
|
2023-04-04 11:26:14 -04:00
|
|
|
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,
|
2023-07-24 22:06:55 +02:00
|
|
|
const blender::IndexRange face,
|
2015-07-30 14:43:58 +02:00
|
|
|
const float u,
|
|
|
|
|
const float v,
|
|
|
|
|
const int mode,
|
|
|
|
|
float res[3])
|
2012-12-18 17:46:26 +00:00
|
|
|
{
|
|
|
|
|
float data[4][3];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
if (mode == 0) {
|
2023-07-24 22:06:55 +02:00
|
|
|
copy_v3_v3(data[0], vert_normals[corner_verts[face[0]]]);
|
|
|
|
|
copy_v3_v3(data[1], vert_normals[corner_verts[face[1]]]);
|
|
|
|
|
copy_v3_v3(data[2], vert_normals[corner_verts[face[2]]]);
|
|
|
|
|
copy_v3_v3(data[3], vert_normals[corner_verts[face[3]]]);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2023-07-24 22:06:55 +02:00
|
|
|
copy_v3_v3(data[0], vert_positions[corner_verts[face[0]]]);
|
|
|
|
|
copy_v3_v3(data[1], vert_positions[corner_verts[face[1]]]);
|
|
|
|
|
copy_v3_v3(data[2], vert_positions[corner_verts[face[2]]]);
|
|
|
|
|
copy_v3_v3(data[3], vert_positions[corner_verts[face[3]]]);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
interp_bilinear_quad_v3(data, u, v, res);
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-19 14:57:49 +01:00
|
|
|
static void interp_barycentric_corner_tri(const blender::Span<blender::float3> vert_positions,
|
|
|
|
|
const blender::Span<blender::float3> vert_normals,
|
|
|
|
|
const blender::Span<int> corner_verts,
|
|
|
|
|
const blender::int3 &corner_tri,
|
|
|
|
|
const float u,
|
|
|
|
|
const float v,
|
|
|
|
|
const int mode,
|
|
|
|
|
float res[3])
|
2012-12-18 17:46:26 +00:00
|
|
|
{
|
|
|
|
|
float data[3][3];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
if (mode == 0) {
|
2023-12-19 14:57:49 +01:00
|
|
|
copy_v3_v3(data[0], vert_normals[corner_verts[corner_tri[0]]]);
|
|
|
|
|
copy_v3_v3(data[1], vert_normals[corner_verts[corner_tri[1]]]);
|
|
|
|
|
copy_v3_v3(data[2], vert_normals[corner_verts[corner_tri[2]]]);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2023-12-19 14:57:49 +01:00
|
|
|
copy_v3_v3(data[0], vert_positions[corner_verts[corner_tri[0]]]);
|
|
|
|
|
copy_v3_v3(data[1], vert_positions[corner_verts[corner_tri[1]]]);
|
|
|
|
|
copy_v3_v3(data[2], vert_positions[corner_verts[corner_tri[2]]]);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
interp_barycentric_tri_v3(data, u, v, res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* **************** Displacement Baker **************** */
|
|
|
|
|
|
2022-04-22 20:44:49 +02:00
|
|
|
static void *init_heights_data(MultiresBakeRender *bkr, ImBuf *ibuf)
|
2012-12-18 17:46:26 +00:00
|
|
|
{
|
|
|
|
|
MHeightBakeData *height_data;
|
|
|
|
|
DerivedMesh *lodm = bkr->lores_dm;
|
2022-12-02 12:34:26 +01:00
|
|
|
BakeImBufuserData *userdata = static_cast<BakeImBufuserData *>(ibuf->userdata);
|
2013-01-21 18:34:27 +00:00
|
|
|
|
2022-12-02 12:34:26 +01:00
|
|
|
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
|
|
|
}
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2022-12-02 12:34:26 +01:00
|
|
|
height_data = MEM_cnew<MHeightBakeData>("MultiresBake heightData");
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2013-01-21 18:34:27 +00:00
|
|
|
height_data->heights = userdata->displacement_buffer;
|
2012-12-18 17:46:26 +00:00
|
|
|
|
|
|
|
|
if (!bkr->use_lores_mesh) {
|
2022-12-02 12:34:26 +01:00
|
|
|
SubsurfModifierData smd = {{nullptr}};
|
2012-12-18 17:46:26 +00:00
|
|
|
int ss_lvl = bkr->tot_lvl - bkr->lvl;
|
|
|
|
|
|
|
|
|
|
CLAMP(ss_lvl, 0, 6);
|
|
|
|
|
|
|
|
|
|
if (ss_lvl > 0) {
|
|
|
|
|
smd.levels = smd.renderLevels = ss_lvl;
|
2021-01-13 16:58:36 +01:00
|
|
|
smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES;
|
2018-08-13 15:39:01 +02:00
|
|
|
smd.quality = 3;
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2018-06-18 11:51:02 +02:00
|
|
|
height_data->ssdm = subsurf_make_derived_from_derived(
|
2022-12-02 12:34:26 +01:00
|
|
|
bkr->lores_dm, &smd, bkr->scene, nullptr, SubsurfFlags(0));
|
2013-01-21 18:34:14 +00:00
|
|
|
init_ccgdm_arrays(height_data->ssdm);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-02 12:34:26 +01:00
|
|
|
height_data->orig_index_mp_to_orig = static_cast<const int *>(
|
|
|
|
|
lodm->getPolyDataArray(lodm, CD_ORIGINDEX));
|
2012-12-18 17:46:26 +00:00
|
|
|
|
|
|
|
|
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) {
|
2012-12-18 17:46:26 +00:00
|
|
|
height_data->ssdm->release(height_data->ssdm);
|
2019-04-22 09:08:06 +10:00
|
|
|
}
|
2012-12-18 17:46:26 +00: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) */
|
2023-04-04 11:26:14 -04:00
|
|
|
static void apply_heights_callback(const blender::Span<blender::float3> vert_positions,
|
|
|
|
|
const blender::Span<blender::float3> vert_normals,
|
2023-07-24 22:06:55 +02:00
|
|
|
const blender::OffsetIndices<int> faces,
|
2023-04-04 11:26:14 -04:00
|
|
|
const blender::Span<int> corner_verts,
|
2023-12-19 14:57:49 +01:00
|
|
|
const blender::Span<blender::int3> corner_tris,
|
|
|
|
|
const blender::Span<int> tri_faces,
|
2023-04-04 11:26:14 -04:00
|
|
|
const blender::Span<blender::float2> uv_map,
|
2013-01-21 18:34:27 +00:00
|
|
|
DerivedMesh *hires_dm,
|
|
|
|
|
void *thread_data_v,
|
|
|
|
|
void *bake_data,
|
2015-07-30 14:43:58 +02:00
|
|
|
ImBuf *ibuf,
|
|
|
|
|
const int tri_index,
|
|
|
|
|
const int lvl,
|
|
|
|
|
const float st[2],
|
2022-12-20 15:51:47 -03:00
|
|
|
float /*tangmat*/[3][3],
|
2012-12-18 17:46:26 +00:00
|
|
|
const int x,
|
|
|
|
|
const int y)
|
|
|
|
|
{
|
2023-12-19 14:57:49 +01:00
|
|
|
const blender::int3 &tri = corner_tris[tri_index];
|
|
|
|
|
const int face_i = tri_faces[tri_index];
|
2023-07-24 22:06:55 +02:00
|
|
|
const blender::IndexRange face = faces[face_i];
|
2012-12-18 17:46:26 +00:00
|
|
|
MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
|
2019-03-25 11:55:36 +11:00
|
|
|
MultiresBakeThread *thread_data = (MultiresBakeThread *)thread_data_v;
|
2023-04-04 11:26:14 -04:00
|
|
|
float uv[2];
|
|
|
|
|
const float *st0, *st1, *st2, *st3;
|
2012-12-18 17:46:26 +00:00
|
|
|
int pixel = ibuf->x * y + x;
|
|
|
|
|
float vec[3], p0[3], p1[3], n[3], len;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-30 14:43:58 +02:00
|
|
|
/* 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) */
|
2023-07-24 22:06:55 +02:00
|
|
|
if (face.size() == 4) {
|
|
|
|
|
st0 = uv_map[face[0]];
|
|
|
|
|
st1 = uv_map[face[1]];
|
|
|
|
|
st2 = uv_map[face[2]];
|
|
|
|
|
st3 = uv_map[face[3]];
|
2014-03-26 11:15:21 +11:00
|
|
|
resolve_quad_uv_v2(uv, st, st0, st1, st2, st3);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
2015-07-30 14:43:58 +02:00
|
|
|
else {
|
2023-12-19 14:57:49 +01:00
|
|
|
st0 = uv_map[tri[0]];
|
|
|
|
|
st1 = uv_map[tri[1]];
|
|
|
|
|
st2 = uv_map[tri[2]];
|
2014-03-26 11:15:21 +11:00
|
|
|
resolve_tri_uv_v2(uv, st, st0, st1, st2);
|
2015-07-30 14:43:58 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-04 11:31:51 +11:00
|
|
|
clamp_v2(uv, 0.0f, 1.0f);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
get_ccgdm_data(
|
2023-07-24 22:06:55 +02:00
|
|
|
faces, hires_dm, height_data->orig_index_mp_to_orig, lvl, face_i, uv[0], uv[1], p1, nullptr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
if (height_data->ssdm) {
|
2023-07-24 22:06:55 +02:00
|
|
|
get_ccgdm_data(faces,
|
2023-05-04 15:39:10 +02:00
|
|
|
height_data->ssdm,
|
|
|
|
|
height_data->orig_index_mp_to_orig,
|
|
|
|
|
0,
|
2023-07-24 22:06:55 +02:00
|
|
|
face_i,
|
2023-05-04 15:39:10 +02:00
|
|
|
uv[0],
|
|
|
|
|
uv[1],
|
|
|
|
|
p0,
|
|
|
|
|
n);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2023-07-24 22:06:55 +02:00
|
|
|
if (face.size() == 4) {
|
|
|
|
|
interp_bilinear_mpoly(vert_positions, vert_normals, corner_verts, face, uv[0], uv[1], 1, p0);
|
|
|
|
|
interp_bilinear_mpoly(vert_positions, vert_normals, corner_verts, face, uv[0], uv[1], 0, n);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2023-12-19 14:57:49 +01:00
|
|
|
interp_barycentric_corner_tri(
|
|
|
|
|
vert_positions, vert_normals, corner_verts, tri, uv[0], uv[1], 1, p0);
|
|
|
|
|
interp_barycentric_corner_tri(
|
|
|
|
|
vert_positions, vert_normals, corner_verts, tri, uv[0], uv[1], 0, n);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
sub_v3_v3v3(vec, p1, p0);
|
|
|
|
|
len = dot_v3v3(n, vec);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
height_data->heights[pixel] = len;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-01-21 18:34:27 +00:00
|
|
|
thread_data->height_min = min_ff(thread_data->height_min, len);
|
|
|
|
|
thread_data->height_max = max_ff(thread_data->height_max, len);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-18 10:19:01 +02:00
|
|
|
if (ibuf->float_buffer.data) {
|
|
|
|
|
float *rrgbf = ibuf->float_buffer.data + pixel * 4;
|
2013-01-21 18:34:27 +00:00
|
|
|
rrgbf[0] = rrgbf[1] = rrgbf[2] = len;
|
2012-12-18 17:46:26 +00:00
|
|
|
rrgbf[3] = 1.0f;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2023-05-18 10:19:01 +02:00
|
|
|
uchar *rrgb = ibuf->byte_buffer.data + pixel * 4;
|
2018-05-07 17:31:28 +02:00
|
|
|
rrgb[0] = rrgb[1] = rrgb[2] = unit_float_to_uchar_clamp(len);
|
2012-12-18 17:46:26 +00:00
|
|
|
rrgb[3] = 255;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* **************** Normal Maps Baker **************** */
|
|
|
|
|
|
2022-12-20 15:51:47 -03:00
|
|
|
static void *init_normal_data(MultiresBakeRender *bkr, ImBuf * /*ibuf*/)
|
2012-12-18 17:46:26 +00:00
|
|
|
{
|
|
|
|
|
MNormalBakeData *normal_data;
|
|
|
|
|
DerivedMesh *lodm = bkr->lores_dm;
|
|
|
|
|
|
2022-12-02 12:34:26 +01:00
|
|
|
normal_data = MEM_cnew<MNormalBakeData>("MultiresBake normalData");
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2022-12-02 12:34:26 +01:00
|
|
|
normal_data->orig_index_mp_to_orig = static_cast<const int *>(
|
|
|
|
|
lodm->getPolyDataArray(lodm, CD_ORIGINDEX));
|
2012-12-18 17:46:26 +00:00
|
|
|
|
|
|
|
|
return (void *)normal_data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void free_normal_data(void *bake_data)
|
|
|
|
|
{
|
|
|
|
|
MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
|
|
|
|
|
|
|
|
|
|
MEM_freeN(normal_data);
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-14 10:48:42 +02:00
|
|
|
/**
|
|
|
|
|
* 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)`.
|
|
|
|
|
*/
|
2023-04-04 11:26:14 -04:00
|
|
|
static void apply_tangmat_callback(const blender::Span<blender::float3> /*vert_positions*/,
|
|
|
|
|
const blender::Span<blender::float3> /*vert_normals*/,
|
2023-07-24 22:06:55 +02:00
|
|
|
const blender::OffsetIndices<int> faces,
|
2023-04-04 11:26:14 -04:00
|
|
|
const blender::Span<int> /*corner_verts*/,
|
2023-12-19 14:57:49 +01:00
|
|
|
const blender::Span<blender::int3> corner_tris,
|
|
|
|
|
const blender::Span<int> tri_faces,
|
2023-04-04 11:26:14 -04:00
|
|
|
const blender::Span<blender::float2> uv_map,
|
2013-01-21 18:34:27 +00:00
|
|
|
DerivedMesh *hires_dm,
|
2022-12-20 15:51:47 -03:00
|
|
|
void * /*thread_data*/,
|
2015-07-30 14:43:58 +02:00
|
|
|
void *bake_data,
|
|
|
|
|
ImBuf *ibuf,
|
|
|
|
|
const int tri_index,
|
|
|
|
|
const int lvl,
|
2013-01-21 18:34:27 +00:00
|
|
|
const float st[2],
|
|
|
|
|
float tangmat[3][3],
|
|
|
|
|
const int x,
|
|
|
|
|
const int y)
|
2012-12-18 17:46:26 +00:00
|
|
|
{
|
2023-12-19 14:57:49 +01:00
|
|
|
const blender::int3 &tri = corner_tris[tri_index];
|
|
|
|
|
const int face_i = tri_faces[tri_index];
|
2023-07-24 22:06:55 +02:00
|
|
|
const blender::IndexRange face = faces[face_i];
|
2012-12-18 17:46:26 +00:00
|
|
|
MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
|
2023-04-04 11:26:14 -04:00
|
|
|
float uv[2];
|
|
|
|
|
const float *st0, *st1, *st2, *st3;
|
2012-12-18 17:46:26 +00:00
|
|
|
int pixel = ibuf->x * y + x;
|
|
|
|
|
float n[3], vec[3], tmp[3] = {0.5, 0.5, 0.5};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-30 14:43:58 +02:00
|
|
|
/* 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) */
|
2023-07-24 22:06:55 +02:00
|
|
|
if (face.size() == 4) {
|
|
|
|
|
st0 = uv_map[face[0]];
|
|
|
|
|
st1 = uv_map[face[1]];
|
|
|
|
|
st2 = uv_map[face[2]];
|
|
|
|
|
st3 = uv_map[face[3]];
|
2014-03-26 11:15:21 +11:00
|
|
|
resolve_quad_uv_v2(uv, st, st0, st1, st2, st3);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
2015-07-30 14:43:58 +02:00
|
|
|
else {
|
2023-12-19 14:57:49 +01:00
|
|
|
st0 = uv_map[tri[0]];
|
|
|
|
|
st1 = uv_map[tri[1]];
|
|
|
|
|
st2 = uv_map[tri[2]];
|
2014-03-26 11:15:21 +11:00
|
|
|
resolve_tri_uv_v2(uv, st, st0, st1, st2);
|
2015-07-30 14:43:58 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-04 11:31:51 +11:00
|
|
|
clamp_v2(uv, 0.0f, 1.0f);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
get_ccgdm_data(
|
2023-07-24 22:06:55 +02:00
|
|
|
faces, hires_dm, normal_data->orig_index_mp_to_orig, lvl, face_i, uv[0], uv[1], nullptr, n);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
mul_v3_m3v3(vec, tangmat, n);
|
2016-07-08 10:14:49 +10:00
|
|
|
normalize_v3_length(vec, 0.5);
|
2012-12-18 17:46:26 +00:00
|
|
|
add_v3_v3(vec, tmp);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-18 10:19:01 +02:00
|
|
|
if (ibuf->float_buffer.data) {
|
|
|
|
|
float *rrgbf = ibuf->float_buffer.data + pixel * 4;
|
2012-12-18 17:46:26 +00:00
|
|
|
rrgbf[0] = vec[0];
|
|
|
|
|
rrgbf[1] = vec[1];
|
|
|
|
|
rrgbf[2] = vec[2];
|
|
|
|
|
rrgbf[3] = 1.0f;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2023-05-18 10:19:01 +02:00
|
|
|
uchar *rrgb = ibuf->byte_buffer.data + pixel * 4;
|
2012-12-18 17:46:26 +00:00
|
|
|
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
|
2012-12-18 17:46:42 +00:00
|
|
|
/* **************** Ambient Occlusion Baker **************** */
|
|
|
|
|
|
2021-08-31 13:36:28 +10:00
|
|
|
/* Must be a power of two. */
|
2012-12-18 17:46:42 +00:00
|
|
|
# define MAX_NUMBER_OF_AO_RAYS 1024
|
|
|
|
|
|
2022-09-26 10:56:05 +10:00
|
|
|
static ushort ao_random_table_1[MAX_NUMBER_OF_AO_RAYS];
|
|
|
|
|
static ushort ao_random_table_2[MAX_NUMBER_OF_AO_RAYS];
|
2012-12-18 17:46:42 +00:00
|
|
|
|
2023-07-02 19:37:22 +10:00
|
|
|
static void init_ao_random()
|
2012-12-18 17:46:42 +00:00
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-26 10:56:05 +10:00
|
|
|
static ushort get_ao_random1(const int i)
|
2012-12-18 17:46:42 +00:00
|
|
|
{
|
|
|
|
|
return ao_random_table_1[i & (MAX_NUMBER_OF_AO_RAYS - 1)];
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-26 10:56:05 +10:00
|
|
|
static ushort get_ao_random2(const int i)
|
2012-12-18 17:46:42 +00:00
|
|
|
{
|
|
|
|
|
return ao_random_table_2[i & (MAX_NUMBER_OF_AO_RAYS - 1)];
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-26 10:56:05 +10:00
|
|
|
static void build_permutation_table(ushort permutation[],
|
|
|
|
|
ushort temp_permutation[],
|
2019-04-17 08:24:14 +02:00
|
|
|
const int number_of_rays,
|
|
|
|
|
const int is_first_perm_table)
|
2012-12-18 17:46:42 +00:00
|
|
|
{
|
|
|
|
|
int i, k;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-31 23:21:16 +10:00
|
|
|
for (i = 0; i < number_of_rays; i++) {
|
2012-12-18 17:46:42 +00:00
|
|
|
temp_permutation[i] = i;
|
2019-05-31 23:21:16 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
for (i = 0; i < number_of_rays; i++) {
|
2022-09-26 10:56:05 +10:00
|
|
|
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;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
/* pull entry */
|
|
|
|
|
permutation[i] = temp_permutation[entry];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
/* delete entry */
|
2013-02-11 00:49:00 +00:00
|
|
|
for (k = entry; k < nr_entries_left - 1; k++) {
|
2012-12-18 17:46:42 +00:00
|
|
|
temp_permutation[k] = temp_permutation[k + 1];
|
2013-02-11 00:49:00 +00:00
|
|
|
}
|
2012-12-18 17:46:42 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
/* verify permutation table
|
|
|
|
|
* every entry must appear exactly once
|
|
|
|
|
*/
|
|
|
|
|
# if 0
|
2023-08-09 10:47:43 +10: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);
|
2012-12-18 17:46:42 +00:00
|
|
|
# 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;
|
2022-03-28 11:12:57 +11:00
|
|
|
int grids_num, grid_size /*, face_side */, faces_num;
|
2012-12-18 17:46:42 +00:00
|
|
|
int i;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-28 11:12:57 +11:00
|
|
|
grids_num = hidm->getNumGrids(hidm);
|
2012-12-18 17:46:42 +00:00
|
|
|
grid_size = hidm->getGridSize(hidm);
|
|
|
|
|
grid_data = hidm->getGridData(hidm);
|
|
|
|
|
hidm->getGridKey(hidm, &key);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-05 13:58:04 +10:00
|
|
|
// face_side = (grid_size << 1) - 1; /* UNUSED */
|
2022-03-28 11:12:57 +11:00
|
|
|
faces_num = grids_num * (grid_size - 1) * (grid_size - 1);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:24:14 +02:00
|
|
|
raytree = ao_data->raytree = RE_rayobject_create(
|
2022-03-28 11:12:57 +11:00
|
|
|
bkr->raytrace_structure, faces_num, bkr->octree_resolution);
|
|
|
|
|
face = ao_data->rayfaces = (RayFace *)MEM_callocN(faces_num * sizeof(RayFace),
|
2019-04-17 08:24:14 +02:00
|
|
|
"ObjectRen faces");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-28 11:12:57 +11:00
|
|
|
for (i = 0; i < grids_num; i++) {
|
2012-12-18 17:46:42 +00:00
|
|
|
int x, y;
|
|
|
|
|
for (x = 0; x < grid_size - 1; x++) {
|
|
|
|
|
for (y = 0; y < grid_size - 1; y++) {
|
|
|
|
|
float co[4][3];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
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));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
RE_rayface_from_coords(face, ao_data, face, co[0], co[1], co[2], co[3]);
|
|
|
|
|
RE_rayobject_add(raytree, RE_rayobject_unalignRayFace(face));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
face++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
RE_rayobject_done(raytree);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-12 14:18:59 +02:00
|
|
|
static void *init_ao_data(MultiresBakeRender *bkr, ImBuf * /*ibuf*/)
|
2012-12-18 17:46:42 +00:00
|
|
|
{
|
|
|
|
|
MAOBakeData *ao_data;
|
|
|
|
|
DerivedMesh *lodm = bkr->lores_dm;
|
2022-09-26 10:56:05 +10:00
|
|
|
ushort *temp_permutation_table;
|
2012-12-18 17:46:42 +00:00
|
|
|
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 */
|
2022-09-26 10:56:05 +10:00
|
|
|
permutation_size = sizeof(ushort) * bkr->number_of_rays;
|
2012-12-18 17:46:42 +00:00
|
|
|
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");
|
|
|
|
|
|
2019-04-17 08:24:14 +02:00
|
|
|
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);
|
2012-12-18 17:46:42 +00:00
|
|
|
|
|
|
|
|
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;
|
2012-12-18 17:46:42 +00:00
|
|
|
|
|
|
|
|
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]);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
if (faX <= faY && faX <= faZ) {
|
|
|
|
|
const float len = sqrtf(axisZ[1] * axisZ[1] + axisZ[2] * axisZ[2]);
|
2019-04-17 08:24:14 +02:00
|
|
|
axisY[0] = 0;
|
|
|
|
|
axisY[1] = axisZ[2] / len;
|
|
|
|
|
axisY[2] = -axisZ[1] / len;
|
2012-12-18 17:46:42 +00:00
|
|
|
cross_v3_v3v3(axisX, axisY, axisZ);
|
|
|
|
|
}
|
|
|
|
|
else if (faY <= faZ) {
|
|
|
|
|
const float len = sqrtf(axisZ[0] * axisZ[0] + axisZ[2] * axisZ[2]);
|
2019-04-17 08:24:14 +02:00
|
|
|
axisX[0] = axisZ[2] / len;
|
|
|
|
|
axisX[1] = 0;
|
|
|
|
|
axisX[2] = -axisZ[0] / len;
|
2012-12-18 17:46:42 +00:00
|
|
|
cross_v3_v3v3(axisY, axisZ, axisX);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
const float len = sqrtf(axisZ[0] * axisZ[0] + axisZ[1] * axisZ[1]);
|
2019-04-17 08:24:14 +02:00
|
|
|
axisX[0] = axisZ[1] / len;
|
|
|
|
|
axisX[1] = -axisZ[0] / len;
|
|
|
|
|
axisX[2] = 0;
|
2012-12-18 17:46:42 +00:00
|
|
|
cross_v3_v3v3(axisY, axisZ, axisX);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
/* return false if nothing was hit and true otherwise */
|
2012-12-18 17:46:42 +00:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-17 08:24:14 +02:00
|
|
|
static void apply_ao_callback(DerivedMesh *lores_dm,
|
|
|
|
|
DerivedMesh *hires_dm,
|
2023-07-12 14:18:59 +02:00
|
|
|
void * /*thread_data*/,
|
2019-04-17 08:24:14 +02:00
|
|
|
void *bake_data,
|
|
|
|
|
ImBuf *ibuf,
|
|
|
|
|
const int tri_index,
|
|
|
|
|
const int lvl,
|
|
|
|
|
const float st[2],
|
2022-12-20 15:51:47 -03:00
|
|
|
float /*tangmat[3][3]*/,
|
2019-04-17 08:24:14 +02:00
|
|
|
const int x,
|
|
|
|
|
const int y)
|
2012-12-18 17:46:42 +00:00
|
|
|
{
|
2023-12-19 14:57:49 +01:00
|
|
|
const blender::int3 &tri = lores_dm->getcorner_triArray(lores_dm) + tri_index;
|
2023-07-12 14:18:59 +02: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;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-03-08 14:48:45 +11:00
|
|
|
int i, k, perm_ofs;
|
2012-12-18 17:46:42 +00:00
|
|
|
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;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-30 14:43:58 +02:00
|
|
|
/* 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) */
|
2023-07-24 22:06:55 +02:00
|
|
|
if (face.size() == 4) {
|
|
|
|
|
st0 = mloopuv[face[0]];
|
|
|
|
|
st1 = mloopuv[face[1]];
|
|
|
|
|
st2 = mloopuv[face[2]];
|
|
|
|
|
st3 = mloopuv[face[3]];
|
2014-03-26 11:15:21 +11:00
|
|
|
resolve_quad_uv_v2(uv, st, st0, st1, st2, st3);
|
2012-12-18 17:46:42 +00:00
|
|
|
}
|
2015-07-30 14:43:58 +02:00
|
|
|
else {
|
2023-12-19 14:57:49 +01:00
|
|
|
st0 = mloopuv[tri[0]];
|
|
|
|
|
st1 = mloopuv[tri[1]];
|
|
|
|
|
st2 = mloopuv[tri[2]];
|
2014-03-26 11:15:21 +11:00
|
|
|
resolve_tri_uv_v2(uv, st, st0, st1, st2);
|
2015-07-30 14:43:58 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-04 11:31:51 +11:00
|
|
|
clamp_v2(uv, 0.0f, 1.0f);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:24:14 +02:00
|
|
|
get_ccgdm_data(
|
2023-12-19 14:57:49 +01:00
|
|
|
lores_dm, hires_dm, ao_data->orig_index_mp_to_orig, lvl, tri, uv[0], uv[1], pos, nrm);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
/* offset ray origin by user bias along normal */
|
2019-05-31 23:21:16 +10:00
|
|
|
for (i = 0; i < 3; i++) {
|
2012-12-18 17:46:42 +00:00
|
|
|
cen[i] = pos[i] + ao_data->bias * nrm[i];
|
2019-05-31 23:21:16 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
/* build tangent frame */
|
2019-05-31 23:21:16 +10:00
|
|
|
for (i = 0; i < 3; i++) {
|
2012-12-18 17:46:42 +00:00
|
|
|
axisZ[i] = nrm[i];
|
2019-05-31 23:21:16 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
build_coordinate_frame(axisX, axisY, axisZ);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
/* static noise */
|
2021-03-08 14:48:45 +11:00
|
|
|
perm_ofs = (get_ao_random2(get_ao_random1(x) + y)) & (MAX_NUMBER_OF_AO_RAYS - 1);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
/* importance sample shadow rays (cosine weighted) */
|
|
|
|
|
for (i = 0; i < ao_data->number_of_rays; i++) {
|
|
|
|
|
int hit_something;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
/* use N-Rooks to distribute our N ray samples across
|
|
|
|
|
* a multi-dimensional domain (2D)
|
|
|
|
|
*/
|
2023-07-12 14:18:59 +02:00
|
|
|
const ushort I = ao_data->permutation_table_1[(i + perm_ofs) % ao_data->number_of_rays];
|
2022-09-26 10:56:05 +10:00
|
|
|
const ushort J = ao_data->permutation_table_2[i];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-03-08 14:48:45 +11:00
|
|
|
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);
|
2021-03-08 14:48:45 +11:00
|
|
|
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);
|
2012-12-18 17:46:42 +00:00
|
|
|
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);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
/* this gives results identical to the so-called cosine
|
|
|
|
|
* weighted distribution relative to the north pole.
|
|
|
|
|
*/
|
2014-09-17 14:11:37 +10:00
|
|
|
float SiPhi = sqrtf(SiSqPhi);
|
2012-12-20 05:03:00 +00:00
|
|
|
float CoPhi = SiSqPhi < 1.0f ? sqrtf(1.0f - SiSqPhi) : 0;
|
2014-09-17 14:11:37 +10:00
|
|
|
float CoThe = cosf(Theta);
|
|
|
|
|
float SiThe = sinf(Theta);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
const float dx = CoThe * CoPhi;
|
|
|
|
|
const float dy = SiThe * CoPhi;
|
|
|
|
|
const float dz = SiPhi;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
/* transform ray direction out of tangent frame */
|
|
|
|
|
float dv[3];
|
2019-05-31 23:21:16 +10:00
|
|
|
for (k = 0; k < 3; k++) {
|
2012-12-18 17:46:42 +00:00
|
|
|
dv[k] = axisX[k] * dx + axisY[k] * dy + axisZ[k] * dz;
|
2019-05-31 23:21:16 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
hit_something = trace_ao_ray(ao_data, cen, dv);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-05-31 23:21:16 +10:00
|
|
|
if (hit_something != 0) {
|
2012-12-18 17:46:42 +00:00
|
|
|
shadow += 1;
|
2019-05-31 23:21:16 +10:00
|
|
|
}
|
2012-12-18 17:46:42 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
value = 1.0f - (shadow / ao_data->number_of_rays);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-12-18 17:46:42 +00:00
|
|
|
if (ibuf->rect_float) {
|
|
|
|
|
float *rrgbf = ibuf->rect_float + pixel * 4;
|
|
|
|
|
rrgbf[0] = rrgbf[1] = rrgbf[2] = value;
|
|
|
|
|
rrgbf[3] = 1.0f;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2022-09-26 10:56:05 +10:00
|
|
|
uchar *rrgb = (uchar *)ibuf->rect + pixel * 4;
|
2018-05-07 17:31:28 +02:00
|
|
|
rrgb[0] = rrgb[1] = rrgb[2] = unit_float_to_uchar_clamp(value);
|
2012-12-18 17:46:42 +00:00
|
|
|
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 ************************* */
|
|
|
|
|
|
2022-04-22 20:44:49 +02:00
|
|
|
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);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-01-17 18:00:35 +01:00
|
|
|
if (margin) {
|
|
|
|
|
switch (margin_type) {
|
|
|
|
|
case R_BAKE_ADJACENT_FACES:
|
2022-04-22 20:44:49 +02:00
|
|
|
RE_generate_texturemargin_adjacentfaces_dm(ibuf, mask, margin, dm, uv_offset);
|
2022-01-17 18:00:35 +01:00
|
|
|
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
|
|
|
}
|
2019-04-17 06:17:24 +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 {
|
2022-01-17 18:00:35 +01:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-13 11:27:09 +02:00
|
|
|
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;
|
2019-04-17 06:17:24 +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
|
|
|
max_distance = max_ff(fabsf(displacement_min), fabsf(displacement_max));
|
2019-04-17 06:17:24 +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
|
|
|
for (i = 0; i < ibuf->x * ibuf->y; i++) {
|
|
|
|
|
if (*current_mask == FILTER_MASK_USED) {
|
|
|
|
|
float normalized_displacement;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
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
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-18 10:19:01 +02:00
|
|
|
if (ibuf->float_buffer.data) {
|
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
|
|
|
/* currently baking happens to RGBA only */
|
2023-05-18 10:19:01 +02:00
|
|
|
float *fp = ibuf->float_buffer.data + i * 4;
|
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
|
|
|
fp[0] = fp[1] = fp[2] = normalized_displacement;
|
|
|
|
|
fp[3] = 1.0f;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-18 10:19:01 +02:00
|
|
|
if (ibuf->byte_buffer.data) {
|
|
|
|
|
uchar *cp = ibuf->byte_buffer.data + 4 * 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +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
|
|
|
current_displacement++;
|
|
|
|
|
current_mask++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-12-18 17:46:42 +00:00
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
/* **************** Common functions public API relates on **************** */
|
|
|
|
|
|
|
|
|
|
static void count_images(MultiresBakeRender *bkr)
|
|
|
|
|
{
|
2014-02-08 06:07:10 +11:00
|
|
|
BLI_listbase_clear(&bkr->image);
|
2012-12-18 17:46:26 +00:00
|
|
|
bkr->tot_image = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-24 23:14:32 +10:00
|
|
|
for (int i = 0; i < bkr->ob_image.len; i++) {
|
|
|
|
|
Image *ima = bkr->ob_image.array[i];
|
|
|
|
|
if (ima) {
|
2024-08-07 12:12:17 +02:00
|
|
|
ima->id.tag &= ~ID_TAG_DOIT;
|
2017-05-24 23:14:32 +10:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-24 23:14:32 +10:00
|
|
|
for (int i = 0; i < bkr->ob_image.len; i++) {
|
|
|
|
|
Image *ima = bkr->ob_image.array[i];
|
|
|
|
|
if (ima) {
|
2024-08-07 12:12:17 +02:00
|
|
|
if ((ima->id.tag & ID_TAG_DOIT) == 0) {
|
2017-05-24 23:14:32 +10:00
|
|
|
LinkData *data = BLI_genericNodeN(ima);
|
|
|
|
|
BLI_addtail(&bkr->image, data);
|
|
|
|
|
bkr->tot_image++;
|
2024-08-07 12:12:17 +02:00
|
|
|
ima->id.tag |= ID_TAG_DOIT;
|
2017-05-24 23:14:32 +10:00
|
|
|
}
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-24 23:14:32 +10:00
|
|
|
for (int i = 0; i < bkr->ob_image.len; i++) {
|
|
|
|
|
Image *ima = bkr->ob_image.array[i];
|
|
|
|
|
if (ima) {
|
2024-08-07 12:12:17 +02:00
|
|
|
ima->id.tag &= ~ID_TAG_DOIT;
|
2017-05-24 23:14:32 +10:00
|
|
|
}
|
|
|
|
|
}
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
|
2013-01-21 18:34:27 +00:00
|
|
|
static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
|
2012-12-18 17:46:26 +00:00
|
|
|
{
|
2023-06-28 14:58:52 +02:00
|
|
|
/* construct bake result */
|
|
|
|
|
result->height_min = FLT_MAX;
|
|
|
|
|
result->height_max = -FLT_MAX;
|
|
|
|
|
|
2023-08-04 08:51:13 +10:00
|
|
|
LISTBASE_FOREACH (LinkData *, link, &bkr->image) {
|
2012-12-18 17:46:26 +00:00
|
|
|
Image *ima = (Image *)link->data;
|
2022-04-22 20:44:49 +02:00
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
|
|
|
|
|
ImageUser iuser;
|
|
|
|
|
BKE_imageuser_default(&iuser);
|
|
|
|
|
iuser.tile = tile->tile_number;
|
|
|
|
|
|
2022-12-02 12:34:26 +01:00
|
|
|
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, nullptr);
|
2022-04-22 20:44:49 +02:00
|
|
|
|
|
|
|
|
if (ibuf->x > 0 && ibuf->y > 0) {
|
2022-12-02 12:34:26 +01:00
|
|
|
BakeImBufuserData *userdata = MEM_cnew<BakeImBufuserData>("MultiresBake userdata");
|
|
|
|
|
userdata->mask_buffer = MEM_cnew_array<char>(ibuf->y * ibuf->x, "MultiresBake imbuf mask");
|
2022-04-22 20:44:49 +02:00
|
|
|
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
|
2022-04-22 20:44:49 +02:00
|
|
|
case RE_BAKE_AO:
|
2023-07-12 14:18:59 +02:00
|
|
|
do_multires_bake(bkr,
|
|
|
|
|
ima,
|
|
|
|
|
tile,
|
|
|
|
|
ibuf,
|
|
|
|
|
false,
|
|
|
|
|
apply_ao_callback,
|
|
|
|
|
init_ao_data,
|
|
|
|
|
free_ao_data,
|
|
|
|
|
result);
|
2022-04-22 20:44:49 +02:00
|
|
|
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
|
2022-04-22 20:44:49 +02:00
|
|
|
}
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
|
2022-12-02 12:34:26 +01:00
|
|
|
BKE_image_release_ibuf(ima, ibuf, nullptr);
|
2022-04-22 20:44:49 +02:00
|
|
|
}
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2024-08-07 12:12:17 +02:00
|
|
|
ima->id.tag |= ID_TAG_DOIT;
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-21 18:34:27 +00:00
|
|
|
static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
|
2012-12-18 17:46:26 +00: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
|
|
|
bool use_displacement_buffer = bkr->mode == RE_BAKE_DISPLACEMENT;
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2023-08-04 08:51:13 +10:00
|
|
|
LISTBASE_FOREACH (LinkData *, link, &bkr->image) {
|
2012-12-18 17:46:26 +00:00
|
|
|
Image *ima = (Image *)link->data;
|
|
|
|
|
|
2022-04-22 20:44:49 +02:00
|
|
|
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
|
|
|
|
|
ImageUser iuser;
|
|
|
|
|
BKE_imageuser_default(&iuser);
|
|
|
|
|
iuser.tile = tile->tile_number;
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2022-12-02 12:34:26 +01:00
|
|
|
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, nullptr);
|
2022-04-22 20:44:49 +02:00
|
|
|
BakeImBufuserData *userdata = (BakeImBufuserData *)ibuf->userdata;
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2022-04-22 20:44:49 +02:00
|
|
|
if (ibuf->x <= 0 || ibuf->y <= 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2013-02-22 09:57:10 +00:00
|
|
|
|
2022-04-22 20:44:49 +02:00
|
|
|
if (use_displacement_buffer) {
|
|
|
|
|
bake_ibuf_normalize_displacement(ibuf,
|
|
|
|
|
userdata->displacement_buffer,
|
|
|
|
|
userdata->mask_buffer,
|
|
|
|
|
result->height_min,
|
|
|
|
|
result->height_max);
|
|
|
|
|
}
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2022-04-22 20:44:49 +02:00
|
|
|
float uv_offset[2];
|
|
|
|
|
BKE_image_get_tile_uv(ima, tile->tile_number, uv_offset);
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2022-04-22 20:44:49 +02:00
|
|
|
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);
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2023-05-18 10:19:01 +02:00
|
|
|
if (ibuf->float_buffer.data) {
|
2022-04-22 20:44:49 +02:00
|
|
|
ibuf->userflags |= IB_RECT_INVALID;
|
2019-04-22 09:08:06 +10:00
|
|
|
}
|
2013-01-21 18:34:27 +00:00
|
|
|
|
2022-04-22 20:44:49 +02: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);
|
|
|
|
|
}
|
2012-12-18 17:46:26 +00:00
|
|
|
|
2022-04-22 20:44:49 +02:00
|
|
|
MEM_freeN(userdata->mask_buffer);
|
|
|
|
|
MEM_freeN(userdata);
|
2022-12-02 12:34:26 +01:00
|
|
|
ibuf->userdata = nullptr;
|
2022-04-22 20:44:49 +02:00
|
|
|
}
|
|
|
|
|
|
2022-12-02 12:34:26 +01:00
|
|
|
BKE_image_release_ibuf(ima, ibuf, nullptr);
|
2022-04-22 20:44:49 +02:00
|
|
|
DEG_id_tag_update(&ima->id, 0);
|
|
|
|
|
}
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RE_multires_bake_images(MultiresBakeRender *bkr)
|
|
|
|
|
{
|
2013-01-21 18:34:27 +00:00
|
|
|
MultiresBakeResult result;
|
|
|
|
|
|
2012-12-18 17:46:26 +00:00
|
|
|
count_images(bkr);
|
2013-01-21 18:34:27 +00:00
|
|
|
bake_images(bkr, &result);
|
|
|
|
|
finish_images(bkr, &result);
|
2012-12-18 17:46:26 +00:00
|
|
|
}
|