GPU: Add Texture Usage Parameter to GPUOffscreen. #106899

Merged
Jeroen Bakker merged 5 commits from Jeroen-Bakker/blender:gpu-offscreen-texture-usage into main 2023-04-14 22:03:03 +02:00
299 changed files with 3357 additions and 1551 deletions
Showing only changes of commit afb098771c - Show all commits

View File

@ -803,6 +803,16 @@ static void attr_create_generic(Scene *scene,
num_curves, num_keys, data, element, [&](int i) { return float(src[i]); });
break;
}
case BL::Attribute::data_type_INT32_2D: {
BL::Int2Attribute b_int2_attribute{b_attribute};
const int2 *src = static_cast<const int2 *>(b_int2_attribute.data[0].ptr.data);
Attribute *attr = attributes.add(name, TypeFloat2, element);
float2 *data = attr->data_float2();
fill_generic_attribute(num_curves, num_keys, data, element, [&](int i) {
return make_float2(float(src[i][0]), float(src[i][1]));
});
break;
}
case BL::Attribute::data_type_FLOAT_VECTOR: {
BL::FloatVectorAttribute b_vector_attribute{b_attribute};
const float(*src)[3] = static_cast<const float(*)[3]>(b_vector_attribute.data[0].ptr.data);

View File

@ -528,6 +528,19 @@ static void attr_create_generic(Scene *scene,
});
break;
}
case BL::Attribute::data_type_INT32_2D: {
BL::Int2Attribute b_int2_attribute{b_attribute};
if (b_int2_attribute.data.length() == 0) {
continue;
}
const int2 *src = static_cast<const int2 *>(b_int2_attribute.data[0].ptr.data);
Attribute *attr = attributes.add(name, TypeFloat2, element);
float2 *data = attr->data_float2();
fill_generic_attribute(b_mesh, data, b_domain, subdivision, [&](int i) {
return make_float2(float(src[i][0]), float(src[i][1]));
});
break;
}
default:
/* Not supported. */
break;

View File

@ -102,6 +102,16 @@ static void copy_attributes(PointCloud *pointcloud,
}
break;
}
case BL::Attribute::data_type_INT32_2D: {
BL::Int2Attribute b_int2_attribute{b_attribute};
const int2 *src = static_cast<const int2 *>(b_int2_attribute.data[0].ptr.data);
Attribute *attr = attributes.add(name, TypeFloat2, element);
float2 *data = attr->data_float2();
for (int i = 0; i < num_points; i++) {
data[i] = make_float2(float(src[i][0]), float(src[i][1]));
}
break;
}
case BL::Attribute::data_type_FLOAT_VECTOR: {
BL::FloatVectorAttribute b_vector_attribute{b_attribute};
const float(*src)[3] = static_cast<const float(*)[3]>(b_vector_attribute.data[0].ptr.data);

View File

@ -357,8 +357,12 @@ void PathTraceWorkCPU::guiding_push_sample_data_to_global_storage(
# if PATH_GUIDING_LEVEL >= 2
const bool use_direct_light = kernel_data.integrator.use_guiding_direct_light;
const bool use_mis_weights = kernel_data.integrator.use_guiding_mis_weights;
# if OPENPGL_VERSION_MINOR >= 5
kg->opgl_path_segment_storage->PrepareSamples(use_mis_weights, use_direct_light, false);
# else
kg->opgl_path_segment_storage->PrepareSamples(
false, nullptr, use_mis_weights, use_direct_light, false);
# endif
# endif
# ifdef WITH_CYCLES_DEBUG

View File

@ -454,8 +454,13 @@ ccl_device_forceinline bool guiding_bsdf_init(KernelGlobals kg,
ccl_private float &rand)
{
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
# if OPENPGL_VERSION_MINOR >= 5
if (kg->opgl_surface_sampling_distribution->Init(
kg->opgl_guiding_field, guiding_point3f(P), rand)) {
# else
if (kg->opgl_surface_sampling_distribution->Init(
kg->opgl_guiding_field, guiding_point3f(P), rand, true)) {
# endif
kg->opgl_surface_sampling_distribution->ApplyCosineProduct(guiding_point3f(N));
return true;
}
@ -506,8 +511,13 @@ ccl_device_forceinline bool guiding_phase_init(KernelGlobals kg,
return false;
}
# if OPENPGL_VERSION_MINOR >= 5
if (kg->opgl_volume_sampling_distribution->Init(
kg->opgl_guiding_field, guiding_point3f(P), rand)) {
# else
if (kg->opgl_volume_sampling_distribution->Init(
kg->opgl_guiding_field, guiding_point3f(P), rand, true)) {
# endif
kg->opgl_volume_sampling_distribution->ApplySingleLobeHenyeyGreensteinProduct(guiding_vec3f(D),
g);
return true;

View File

@ -1390,19 +1390,128 @@ ccl_device_extern void osl_noiseparams_set_impulses(ccl_private OSLNoiseOptions
res->y = n; \
res->z = n; \
} \
ccl_device_extern void name##_vv(ccl_private float3 *res, const float3 *v) \
ccl_device_extern void name##_vv(ccl_private float3 *res, ccl_private const float3 *v) \
{ \
const float n = name##_fv(v); \
res->x = n; \
res->y = n; \
res->z = n; \
} \
ccl_device_extern void name##_vvf(ccl_private float3 *res, const float3 *v, float w) \
ccl_device_extern void name##_vvf( \
ccl_private float3 *res, ccl_private const float3 *v, float w) \
{ \
const float n = name##_fvf(v, w); \
res->x = n; \
res->y = n; \
res->z = n; \
} \
ccl_device_extern void name##_dfdf(ccl_private float *res, ccl_private const float *x) \
{ \
res[0] = name##_ff(x[0]); \
res[1] = name##_ff(x[1]); \
res[2] = name##_ff(x[2]); \
} \
ccl_device_extern void name##_dfdff( \
ccl_private float *res, ccl_private const float *x, float y) \
{ \
res[0] = name##_fff(x[0], y); \
res[1] = name##_fff(x[1], y); \
res[2] = name##_fff(x[2], y); \
} \
ccl_device_extern void name##_dffdf( \
ccl_private float *res, float x, ccl_private const float *y) \
{ \
res[0] = name##_fff(x, y[0]); \
res[1] = name##_fff(x, y[1]); \
res[2] = name##_fff(x, y[2]); \
} \
ccl_device_extern void name##_dfdfdf( \
ccl_private float *res, ccl_private const float *x, ccl_private const float *y) \
{ \
res[0] = name##_fff(x[0], y[0]); \
res[1] = name##_fff(x[1], y[1]); \
res[2] = name##_fff(x[2], y[2]); \
} \
ccl_device_extern void name##_dfdv(ccl_private float *res, ccl_private const float3 *v) \
{ \
res[0] = name##_fv(&v[0]); \
res[1] = name##_fv(&v[1]); \
res[2] = name##_fv(&v[2]); \
} \
ccl_device_extern void name##_dfdvf( \
ccl_private float *res, ccl_private const float3 *v, float w) \
{ \
res[0] = name##_fvf(&v[0], w); \
res[1] = name##_fvf(&v[1], w); \
res[2] = name##_fvf(&v[2], w); \
} \
ccl_device_extern void name##_dfvdf( \
ccl_private float *res, ccl_private const float3 *v, ccl_private const float *w) \
{ \
res[0] = name##_fvf(v, w[0]); \
res[1] = name##_fvf(v, w[1]); \
res[2] = name##_fvf(v, w[2]); \
} \
ccl_device_extern void name##_dfdvdf( \
ccl_private float *res, ccl_private const float3 *v, ccl_private const float *w) \
{ \
res[0] = name##_fvf(&v[0], w[0]); \
res[1] = name##_fvf(&v[1], w[1]); \
res[2] = name##_fvf(&v[2], w[2]); \
} \
ccl_device_extern void name##_dvdf(ccl_private float3 *res, ccl_private const float *x) \
{ \
name##_vf(&res[0], x[0]); \
name##_vf(&res[1], x[1]); \
name##_vf(&res[2], x[2]); \
} \
ccl_device_extern void name##_dvdff( \
ccl_private float3 *res, ccl_private const float *x, float y) \
{ \
name##_vff(&res[0], x[0], y); \
name##_vff(&res[1], x[1], y); \
name##_vff(&res[2], x[2], y); \
} \
ccl_device_extern void name##_dvfdf( \
ccl_private float3 *res, float x, ccl_private const float *y) \
{ \
name##_vff(&res[0], x, y[0]); \
name##_vff(&res[1], x, y[1]); \
name##_vff(&res[2], x, y[2]); \
} \
ccl_device_extern void name##_dvdfdf( \
ccl_private float3 *res, ccl_private const float *x, ccl_private const float *y) \
{ \
name##_vff(&res[0], x[0], y[0]); \
name##_vff(&res[1], x[1], y[1]); \
name##_vff(&res[2], x[2], y[2]); \
} \
ccl_device_extern void name##_dvdv(ccl_private float3 *res, ccl_private const float3 *v) \
{ \
name##_vv(&res[0], &v[0]); \
name##_vv(&res[1], &v[1]); \
name##_vv(&res[2], &v[2]); \
} \
ccl_device_extern void name##_dvdvf( \
ccl_private float3 *res, ccl_private const float3 *v, float w) \
{ \
name##_vvf(&res[0], &v[0], w); \
name##_vvf(&res[1], &v[1], w); \
name##_vvf(&res[2], &v[2], w); \
} \
ccl_device_extern void name##_dvvdf( \
ccl_private float3 *res, ccl_private const float3 *v, ccl_private const float *w) \
{ \
name##_vvf(&res[0], v, w[0]); \
name##_vvf(&res[1], v, w[1]); \
name##_vvf(&res[2], v, w[2]); \
} \
ccl_device_extern void name##_dvdvdf( \
ccl_private float3 *res, ccl_private const float3 *v, ccl_private const float *w) \
{ \
name##_vvf(&res[0], &v[0], w[0]); \
name##_vvf(&res[1], &v[1], w[1]); \
name##_vvf(&res[2], &v[2], w[2]); \
}
ccl_device_forceinline float hashnoise_1d(float p)

View File

@ -152,10 +152,12 @@ LightTreeBucket operator+(const LightTreeBucket &a, const LightTreeBucket &b);
struct LightTreeNode {
LightTreeMeasure measure;
uint bit_trail;
int num_emitters = -1; /* The number of emitters a leaf node stores. A negative number indicates
it is an inner node. */
int first_emitter_index; /* Leaf nodes contain an index to first emitter. */
unique_ptr<LightTreeNode> children[2]; /* Inner node has two children. */
/* The number of emitters a leaf node stores. A negative number indicates it is an inner node. */
int num_emitters = -1;
/* Leaf nodes contain an index to first emitter. */
int first_emitter_index;
/* Inner node has two children. */
unique_ptr<LightTreeNode> children[2];
LightTreeNode() = default;

View File

@ -703,8 +703,11 @@ string OSLCompiler::id(ShaderNode *node)
{
/* assign layer unique name based on pointer address + bump mode */
stringstream stream;
stream.imbue(std::locale("C")); /* Ensure that no grouping characters (e.g. commas with en_US
locale) are added to the pointer string */
/* Ensure that no grouping characters (e.g. commas with en_US locale)
* are added to the pointer string. */
stream.imbue(std::locale("C"));
stream << "node_" << node->type->name << "_" << node;
return stream.str();

View File

@ -214,8 +214,8 @@ void deinterlace_line_inplace(
}
/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
top field is copied as is, but the bottom field is deinterlaced
against the top field. */
* top field is copied as is, but the bottom field is deinterlaced
* against the top field. */
FFMPEG_INLINE
void deinterlace_bottom_field(
uint8_t *dst, int dst_wrap, const uint8_t *src1, int src_wrap, int width, int height)

View File

@ -911,6 +911,27 @@ extern char *GHOST_getClipboard(bool selection);
*/
extern void GHOST_putClipboard(const char *buffer, bool selection);
/**
* Returns GHOST_kSuccess if the clipboard contains an image.
*/
extern GHOST_TSuccess GHOST_hasClipboardImage(void);
/**
* Get image data from the Clipboard
* \param r_width: the returned image width in pixels.
* \param r_height: the returned image height in pixels.
* \return pointer uint array in RGBA byte order. Caller must free.
*/
extern uint *GHOST_getClipboardImage(int *r_width, int *r_height);
/**
* Put image data to the Clipboard
* \param rgba: uint array in RGBA byte order.
* \param width: the image width in pixels.
* \param height: the image height in pixels.
*/
extern GHOST_TSuccess GHOST_putClipboardImage(uint *rgba, int width, int height);
/**
* Set the Console State
* \param action: console state

View File

@ -471,6 +471,27 @@ class GHOST_ISystem {
*/
virtual void putClipboard(const char *buffer, bool selection) const = 0;
/**
* Returns GHOST_kSuccess if the clipboard contains an image.
*/
virtual GHOST_TSuccess hasClipboardImage(void) const = 0;
/**
* Get image data from the Clipboard
* \param r_width: the returned image width in pixels.
* \param r_height: the returned image height in pixels.
* \return pointer uint array in RGBA byte order. Caller must free.
*/
virtual uint *getClipboardImage(int *r_width, int *r_height) const = 0;
/**
* Put image data to the Clipboard
* \param rgba: uint array in RGBA byte order.
* \param width: the image width in pixels.
* \param height: the image height in pixels.
*/
virtual GHOST_TSuccess putClipboardImage(uint *rgba, int width, int height) const = 0;
/***************************************************************************************
* System Message Box.
***************************************************************************************/

View File

@ -883,6 +883,24 @@ void GHOST_putClipboard(const char *buffer, bool selection)
system->putClipboard(buffer, selection);
}
GHOST_TSuccess GHOST_hasClipboardImage(void)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->hasClipboardImage();
}
uint *GHOST_getClipboardImage(int *r_width, int *r_height)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->getClipboardImage(r_width, r_height);
}
GHOST_TSuccess GHOST_putClipboardImage(uint *rgba, int width, int height)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->putClipboardImage(rgba, width, height);
}
bool GHOST_setConsoleWindowState(GHOST_TConsoleWindowState action)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();

View File

@ -42,6 +42,23 @@ GHOST_System::~GHOST_System()
exit();
}
GHOST_TSuccess GHOST_System::hasClipboardImage(void) const
{
return GHOST_kFailure;
}
uint *GHOST_System::getClipboardImage(int * /*r_width*/, int * /*r_height*/) const
{
return nullptr;
}
GHOST_TSuccess GHOST_System::putClipboardImage(uint * /*rgba*/,
int /*width*/,
int /*height*/) const
{
return GHOST_kFailure;
}
uint64_t GHOST_System::getMilliSeconds() const
{
return std::chrono::duration_cast<std::chrono::milliseconds>(

View File

@ -330,6 +330,27 @@ class GHOST_System : public GHOST_ISystem {
*/
virtual void putClipboard(const char *buffer, bool selection) const = 0;
/**
* Returns GHOST_kSuccess if the clipboard contains an image.
*/
GHOST_TSuccess hasClipboardImage(void) const;
/**
* Get image data from the Clipboard
* \param r_width: the returned image width in pixels.
* \param r_height: the returned image height in pixels.
* \return pointer uint array in RGBA byte order. Caller must free.
*/
uint *getClipboardImage(int *r_width, int *r_height) const;
/**
* Put image data to the Clipboard
* \param rgba: uint array in RGBA byte order.
* \param width: the image width in pixels.
* \param height: the image height in pixels.
*/
GHOST_TSuccess putClipboardImage(uint *rgba, int width, int height) const;
/**
* Show a system message box
* \param title: The title of the message box.

View File

@ -26,6 +26,9 @@
#include "utf_winfunc.h"
#include "utfconv.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "GHOST_DisplayManagerWin32.hh"
#include "GHOST_EventButton.hh"
#include "GHOST_EventCursor.hh"
@ -2305,6 +2308,257 @@ void GHOST_SystemWin32::putClipboard(const char *buffer, bool selection) const
}
}
GHOST_TSuccess GHOST_SystemWin32::hasClipboardImage(void) const
{
if (IsClipboardFormatAvailable(CF_DIBV5) ||
IsClipboardFormatAvailable(RegisterClipboardFormat("PNG"))) {
return GHOST_kSuccess;
}
return GHOST_kFailure;
}
static uint *getClipboardImageDibV5(int *r_width, int *r_height)
{
HANDLE hGlobal = GetClipboardData(CF_DIBV5);
if (hGlobal == nullptr) {
return nullptr;
}
BITMAPV5HEADER *bitmapV5Header = (BITMAPV5HEADER *)GlobalLock(hGlobal);
if (bitmapV5Header == nullptr) {
return nullptr;
}
int offset = bitmapV5Header->bV5Size + bitmapV5Header->bV5ClrUsed * sizeof(RGBQUAD);
if (bitmapV5Header->bV5Compression == BI_BITFIELDS) {
offset += 12;
}
BYTE *buffer = (BYTE *)bitmapV5Header + offset;
int bitcount = bitmapV5Header->bV5BitCount;
int width = bitmapV5Header->bV5Width;
int height = bitmapV5Header->bV5Height;
*r_width = width;
*r_height = height;
DWORD ColorMasks[4];
ColorMasks[0] = bitmapV5Header->bV5RedMask ? bitmapV5Header->bV5RedMask : 0xff;
ColorMasks[1] = bitmapV5Header->bV5GreenMask ? bitmapV5Header->bV5GreenMask : 0xff00;
ColorMasks[2] = bitmapV5Header->bV5BlueMask ? bitmapV5Header->bV5BlueMask : 0xff0000;
ColorMasks[3] = bitmapV5Header->bV5AlphaMask ? bitmapV5Header->bV5AlphaMask : 0xff000000;
/* Bit shifts needed for the ColorMasks. */
DWORD ColorShifts[4];
for (int i = 0; i < 4; i++) {
_BitScanForward(&ColorShifts[i], ColorMasks[i]);
}
uchar *source = (uchar *)buffer;
uint *rgba = (uint *)malloc(width * height * 4);
uint8_t *target = (uint8_t *)rgba;
if (bitmapV5Header->bV5Compression == BI_BITFIELDS && bitcount == 32) {
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++, target += 4, source += 4) {
DWORD *pix = (DWORD *)source;
target[0] = uint8_t((*pix & ColorMasks[0]) >> ColorShifts[0]);
target[1] = uint8_t((*pix & ColorMasks[1]) >> ColorShifts[1]);
target[2] = uint8_t((*pix & ColorMasks[2]) >> ColorShifts[2]);
target[3] = uint8_t((*pix & ColorMasks[3]) >> ColorShifts[3]);
}
}
}
else if (bitmapV5Header->bV5Compression == BI_RGB && bitcount == 32) {
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++, target += 4, source += 4) {
RGBQUAD *quad = (RGBQUAD *)source;
target[0] = uint8_t(quad->rgbRed);
target[1] = uint8_t(quad->rgbGreen);
target[2] = uint8_t(quad->rgbBlue);
target[3] = (bitmapV5Header->bV5AlphaMask) ? uint8_t(quad->rgbReserved) : 255;
}
}
}
else if (bitmapV5Header->bV5Compression == BI_RGB && bitcount == 24) {
int bytes_per_row = ((((width * bitcount) + 31) & ~31) >> 3);
int slack = bytes_per_row - (width * 3);
for (int h = 0; h < height; h++, source += slack) {
for (int w = 0; w < width; w++, target += 4, source += 3) {
RGBTRIPLE *triple = (RGBTRIPLE *)source;
target[0] = uint8_t(triple->rgbtRed);
target[1] = uint8_t(triple->rgbtGreen);
target[2] = uint8_t(triple->rgbtBlue);
target[3] = 255;
}
}
}
GlobalUnlock(hGlobal);
return rgba;
}
/* Works with any image format that ImBuf can load. */
static uint *getClipboardImageImBuf(int *r_width, int *r_height, UINT format)
{
HANDLE hGlobal = GetClipboardData(format);
if (hGlobal == nullptr) {
return nullptr;
}
LPVOID pMem = GlobalLock(hGlobal);
if (!pMem) {
return nullptr;
}
uint *rgba = nullptr;
ImBuf *ibuf = IMB_ibImageFromMemory(
(uchar *)pMem, GlobalSize(hGlobal), IB_rect, nullptr, "<clipboard>");
if (ibuf) {
*r_width = ibuf->x;
*r_height = ibuf->y;
rgba = (uint *)malloc(4 * ibuf->x * ibuf->y);
memcpy(rgba, ibuf->rect, 4 * ibuf->x * ibuf->y);
IMB_freeImBuf(ibuf);
}
GlobalUnlock(hGlobal);
return rgba;
}
uint *GHOST_SystemWin32::getClipboardImage(int *r_width, int *r_height) const
{
if (!OpenClipboard(nullptr)) {
return nullptr;
}
/* Synthesized formats are placed after posted formats. */
UINT cfPNG = RegisterClipboardFormat("PNG");
UINT format = 0;
for (int cf = EnumClipboardFormats(0); cf; cf = EnumClipboardFormats(cf)) {
if (ELEM(cf, CF_DIBV5, cfPNG)) {
format = cf;
}
if (cf == CF_DIBV5 || (cf == CF_BITMAP && format == cfPNG)) {
break; /* Favor CF_DIBV5, but not if synthesized. */
}
}
uint *rgba = nullptr;
if (format == CF_DIBV5) {
rgba = getClipboardImageDibV5(r_width, r_height);
}
else if (format == cfPNG) {
rgba = getClipboardImageImBuf(r_width, r_height, cfPNG);
}
else {
*r_width = 0;
*r_height = 0;
}
CloseClipboard();
return rgba;
}
static bool putClipboardImageDibV5(uint *rgba, int width, int height)
{
DWORD size_pixels = width * height * 4;
/* Pixel data is 12 bytes after the header. */
HGLOBAL hMem = GlobalAlloc(GHND, sizeof(BITMAPV5HEADER) + 12 + size_pixels);
if (!hMem) {
return false;
}
BITMAPV5HEADER *hdr = (BITMAPV5HEADER *)GlobalLock(hMem);
if (!hdr) {
GlobalFree(hMem);
return false;
}
hdr->bV5Size = sizeof(BITMAPV5HEADER);
hdr->bV5Width = width;
hdr->bV5Height = height;
hdr->bV5Planes = 1;
hdr->bV5BitCount = 32;
hdr->bV5SizeImage = size_pixels;
hdr->bV5Compression = BI_BITFIELDS;
hdr->bV5RedMask = 0x000000ff;
hdr->bV5GreenMask = 0x0000ff00;
hdr->bV5BlueMask = 0x00ff0000;
hdr->bV5AlphaMask = 0xff000000;
hdr->bV5CSType = LCS_sRGB;
hdr->bV5Intent = LCS_GM_IMAGES;
hdr->bV5ClrUsed = 0;
memcpy((char *)hdr + sizeof(BITMAPV5HEADER) + 12, rgba, size_pixels);
GlobalUnlock(hMem);
if (!SetClipboardData(CF_DIBV5, hMem)) {
GlobalFree(hMem);
return false;
}
return true;
}
static bool putClipboardImagePNG(uint *rgba, int width, int height)
{
UINT cf = RegisterClipboardFormat("PNG");
/* Load buffer into ImBuf, convert to PNG. */
ImBuf *ibuf = IMB_allocFromBuffer(rgba, nullptr, width, height, 32);
ibuf->ftype = IMB_FTYPE_PNG;
ibuf->foptions.quality = 15;
if (!IMB_saveiff(ibuf, "<memory>", IB_rect | IB_mem)) {
IMB_freeImBuf(ibuf);
return false;
}
HGLOBAL hMem = GlobalAlloc(GHND, ibuf->encodedbuffersize);
if (!hMem) {
IMB_freeImBuf(ibuf);
return false;
}
LPVOID pMem = GlobalLock(hMem);
if (!pMem) {
IMB_freeImBuf(ibuf);
GlobalFree(hMem);
return false;
}
memcpy(pMem, ibuf->encodedbuffer, ibuf->encodedbuffersize);
GlobalUnlock(hMem);
IMB_freeImBuf(ibuf);
if (!SetClipboardData(cf, hMem)) {
GlobalFree(hMem);
return false;
}
return true;
}
GHOST_TSuccess GHOST_SystemWin32::putClipboardImage(uint *rgba, int width, int height) const
{
if (!OpenClipboard(nullptr) || !EmptyClipboard()) {
return GHOST_kFailure;
}
bool ok = putClipboardImageDibV5(rgba, width, height) &&
putClipboardImagePNG(rgba, width, height);
CloseClipboard();
return (ok) ? GHOST_kSuccess : GHOST_kFailure;
}
/* -------------------------------------------------------------------- */
/** \name Message Box
* \{ */

View File

@ -215,6 +215,27 @@ class GHOST_SystemWin32 : public GHOST_System {
*/
void putClipboard(const char *buffer, bool selection) const;
/**
* Returns GHOST_kSuccess if the clipboard contains an image.
*/
GHOST_TSuccess hasClipboardImage(void) const;
/**
* Get image data from the Clipboard
* \param r_width: the returned image width in pixels.
* \param r_height: the returned image height in pixels.
* \return pointer uint array in RGBA byte order. Caller must free.
*/
uint *getClipboardImage(int *r_width, int *r_height) const;
/**
* Put image data to the Clipboard
* \param rgba: uint array in RGBA byte order.
* \param width: the image width in pixels.
* \param height: the image height in pixels.
*/
GHOST_TSuccess putClipboardImage(uint *rgba, int width, int height) const;
/**
* Show a system message box
* \param title: The title of the message box.

View File

@ -93,7 +93,7 @@ def write_sysinfo(filepath):
output.write("\t%r\n" % p)
output.write("datafiles: %r\n" % (bpy.utils.user_resource('DATAFILES')))
output.write("config: %r\n" % (bpy.utils.user_resource('CONFIG')))
output.write("scripts : %r\n" % (bpy.utils.user_resource('SCRIPTS')))
output.write("scripts: %r\n" % (bpy.utils.user_resource('SCRIPTS')))
output.write("autosave: %r\n" % (bpy.utils.user_resource('AUTOSAVE')))
output.write("tempdir: %r\n" % (bpy.app.tempdir))
@ -123,7 +123,7 @@ def write_sysinfo(filepath):
output.write("OpenColorIO: ")
if ocio.supported:
if ocio.version_string == "fallback":
output.write("Blender was built with OpenColorIO, " +
output.write("Blender was built with OpenColorIO, "
"but it currently uses fallback color management.\n")
else:
output.write("%s\n" % (ocio.version_string))

View File

@ -7,8 +7,7 @@ class CONSOLE_HT_header(Header):
bl_space_type = 'CONSOLE'
def draw(self, context):
layout = self.layout.row()
layout = self.layout
layout.template_header()
CONSOLE_MT_editor_menus.draw_collapsible(context, layout)

View File

@ -184,6 +184,8 @@ class IMAGE_MT_image(Menu):
bl_label = "Image"
def draw(self, context):
import sys
layout = self.layout
sima = context.space_data
@ -207,6 +209,11 @@ class IMAGE_MT_image(Menu):
layout.separator()
if sys.platform[:3] == "win":
layout.operator("image.clipboard_copy", text="Copy")
layout.operator("image.clipboard_paste", text="Paste")
layout.separator()
if ima:
layout.operator("image.save", text="Save", icon='FILE_TICK')
layout.operator("image.save_as", text="Save As...")

View File

@ -31,21 +31,44 @@ def generate_from_enum_ex(
type,
attr,
cursor='DEFAULT',
tooldef_keywords={},
exclude_filter={},
tooldef_keywords=None,
icon_map=None,
use_separators=True,
):
if tooldef_keywords is None:
tooldef_keywords = {}
tool_defs = []
for enum in type.bl_rna.properties[attr].enum_items_static:
name = enum.name
idname = enum.identifier
if idname in exclude_filter:
continue
enum_items = getattr(
type.bl_rna.properties[attr],
"enum_items_static_ui" if use_separators else
"enum_items_static",
)
for enum in enum_items:
if use_separators:
if not (name := enum.name):
# Empty string for a UI Separator.
tool_defs.append(None)
continue
if not (idname := enum.identifier):
# This is a heading, there is no purpose in showing headings here.
continue
else:
name = enum.name
idname = enum.identifier
icon = icon_prefix + idname.lower()
if icon_map is not None:
icon = icon_map.get(icon, icon)
tool_defs.append(
ToolDef.from_dict(
dict(
idname=idname_prefix + name,
label=name,
icon=icon_prefix + idname.lower(),
icon=icon,
cursor=cursor,
data_block=idname,
**tooldef_keywords,
@ -1316,6 +1339,9 @@ class _defs_sculpt:
icon_prefix="brush.sculpt.",
type=bpy.types.Brush,
attr="sculpt_tool",
# TODO(@ideasman42): we may want to enable this,
# it causes awkward grouping with 2x column button layout.
use_separators=False,
)
@ToolDef.from_fn
@ -2326,103 +2352,18 @@ class _defs_gpencil_weight:
class _defs_curves_sculpt:
@ToolDef.from_fn
def selection_paint():
return dict(
idname="builtin_brush.selection_paint",
label="Selection Paint",
icon="ops.generic.select_paint",
data_block="SELECTION_PAINT",
)
@ToolDef.from_fn
def comb():
return dict(
idname="builtin_brush.comb",
label="Comb",
icon="ops.curves.sculpt_comb",
data_block='COMB',
)
@ToolDef.from_fn
def add():
return dict(
idname="builtin_brush.add",
label="Add",
icon="ops.curves.sculpt_add",
data_block='ADD',
)
@ToolDef.from_fn
def delete():
return dict(
idname="builtin_brush.delete",
label="Delete",
icon="ops.curves.sculpt_delete",
data_block='DELETE',
)
@ToolDef.from_fn
def snake_hook():
return dict(
idname="builtin_brush.snake_hook",
label="Snake Hook",
icon="ops.curves.sculpt_snake_hook",
data_block='SNAKE_HOOK',
)
@ToolDef.from_fn
def grow_shrink():
return dict(
idname="builtin_brush.grow_shrink",
label="Grow/Shrink",
icon="ops.curves.sculpt_grow_shrink",
data_block='GROW_SHRINK',
)
@ToolDef.from_fn
def pinch():
return dict(
idname="builtin_brush.pinch",
label="Pinch",
icon="ops.curves.sculpt_pinch",
data_block='PINCH',
)
@ToolDef.from_fn
def smooth():
return dict(
idname="builtin_brush.smooth",
label="Smooth",
icon="ops.curves.sculpt_smooth",
data_block='SMOOTH',
)
@ToolDef.from_fn
def puff():
return dict(
idname="builtin_brush.puff",
label="Puff",
icon="ops.curves.sculpt_puff",
data_block='PUFF',
)
@ToolDef.from_fn
def density():
return dict(
idname="builtin_brush.density",
label="Density",
icon="ops.curves.sculpt_density",
data_block="DENSITY",
)
@ToolDef.from_fn
def slide():
return dict(
idname="builtin_brush.slide",
label="Slide",
icon="ops.curves.sculpt_slide",
data_block="SLIDE",
@staticmethod
def generate_from_brushes(context):
return generate_from_enum_ex(
context,
idname_prefix="builtin_brush.",
icon_prefix="ops.curves.sculpt_",
type=bpy.types.Brush,
attr="curves_sculpt_tool",
icon_map={
# Use the generic icon for selection painting.
"ops.curves.sculpt_selection_paint": "ops.generic.select_paint",
},
)
@ -3193,19 +3134,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
),
],
'SCULPT_CURVES': [
_defs_curves_sculpt.selection_paint,
None,
_defs_curves_sculpt.add,
_defs_curves_sculpt.delete,
_defs_curves_sculpt.density,
None,
_defs_curves_sculpt.comb,
_defs_curves_sculpt.snake_hook,
_defs_curves_sculpt.grow_shrink,
_defs_curves_sculpt.pinch,
_defs_curves_sculpt.puff,
_defs_curves_sculpt.smooth,
_defs_curves_sculpt.slide,
_defs_curves_sculpt.generate_from_brushes,
None,
*_tools_annotate,
],

View File

@ -147,7 +147,7 @@ add_subdirectory(imbuf)
add_subdirectory(imbuf/intern/oiio)
add_subdirectory(nodes)
add_subdirectory(modifiers)
add_subdirectory(gpencil_modifiers)
add_subdirectory(gpencil_modifiers_legacy)
add_subdirectory(sequencer)
add_subdirectory(shader_fx)
add_subdirectory(io)

View File

@ -802,7 +802,6 @@ class CustomDataAttributes {
std::optional<blender::GMutableSpan> get_for_write(const AttributeIDRef &attribute_id);
bool create(const AttributeIDRef &attribute_id, eCustomDataType data_type);
bool create_by_move(const AttributeIDRef &attribute_id, eCustomDataType data_type, void *buffer);
bool remove(const AttributeIDRef &attribute_id);
bool foreach_attribute(const AttributeForeachCallback callback, eAttrDomain domain) const;

View File

@ -23,6 +23,7 @@ inline void convert_to_static_type(const CPPType &cpp_type, const Func &func)
float2,
float3,
int,
int2,
bool,
int8_t,
ColorGeometry4f,
@ -68,6 +69,11 @@ template<> inline int mix2(const float factor, const int &a, const int &b)
return int(std::round((1.0f - factor) * a + factor * b));
}
template<> inline int2 mix2(const float factor, const int2 &a, const int2 &b)
{
return math::interpolate(a, b, factor);
}
template<> inline float mix2(const float factor, const float &a, const float &b)
{
return (1.0f - factor) * a + factor * b;
@ -121,6 +127,11 @@ template<> inline int mix3(const float3 &weights, const int &v0, const int &v1,
return int(std::round(weights.x * v0 + weights.y * v1 + weights.z * v2));
}
template<> inline int2 mix3(const float3 &weights, const int2 &v0, const int2 &v1, const int2 &v2)
{
return int2(weights.x * float2(v0) + weights.y * float2(v1) + weights.z * float2(v2));
}
template<>
inline float mix3(const float3 &weights, const float &v0, const float &v1, const float &v2)
{
@ -194,6 +205,14 @@ inline int mix4(const float4 &weights, const int &v0, const int &v1, const int &
return int(std::round(weights.x * v0 + weights.y * v1 + weights.z * v2 + weights.w * v3));
}
template<>
inline int2 mix4(
const float4 &weights, const int2 &v0, const int2 &v1, const int2 &v2, const int2 &v3)
{
return int2(weights.x * float2(v0) + weights.y * float2(v1) + weights.z * float2(v2) +
weights.w * float2(v3));
}
template<>
inline float mix4(
const float4 &weights, const float &v0, const float &v1, const float &v2, const float &v3)
@ -382,7 +401,7 @@ class SimpleMixerWithAccumulationType {
private:
struct Item {
/* Store both values together, because they are accessed together. */
AccumulationT value = {0};
AccumulationT value = AccumulationT(0);
float weight = 0.0f;
};
@ -517,6 +536,15 @@ template<> struct DefaultMixerStruct<int> {
* uses double instead of float so that it is accurate for all 32 bit integers. */
using type = SimpleMixerWithAccumulationType<int, double, double_to_int>;
};
template<> struct DefaultMixerStruct<int2> {
static int2 double_to_int(const double2 &value)
{
return int2(math::round(value));
}
/* Store interpolated ints in a double temporarily, so that weights are handled correctly. It
* uses double instead of float so that it is accurate for all 32 bit integers. */
using type = SimpleMixerWithAccumulationType<int2, double2, double_to_int>;
};
template<> struct DefaultMixerStruct<bool> {
static bool float_to_bool(const float &value)
{

View File

@ -8,6 +8,7 @@
#pragma once
#include "BLI_implicit_sharing.h"
#include "BLI_sys_types.h"
#include "BLI_utildefines.h"
#ifdef __cplusplus
@ -74,14 +75,8 @@ extern const CustomData_MeshMasks CD_MASK_EVERYTHING;
/** Add/copy/merge allocation types. */
typedef enum eCDAllocType {
/** Use the data pointer. */
CD_ASSIGN = 0,
/** Allocate and set to default, which is usually just zeroed memory. */
CD_SET_DEFAULT = 2,
/** Use data pointers, set layer flag NOFREE. */
CD_REFERENCE = 3,
/** Do a full copy of all layers, only allowed if source has same number of elements. */
CD_DUPLICATE = 4,
/**
* Default construct new layer values. Does nothing for trivial types. This should be used
* if all layer values will be set by the caller after creating the layer.
@ -158,28 +153,43 @@ void CustomData_data_multiply(eCustomDataType type, void *data, float fac);
void CustomData_data_add(eCustomDataType type, void *data1, const void *data2);
/**
* Initializes a CustomData object with the same layer setup as source.
* mask is a bit-field where `(mask & (1 << (layer type)))` indicates
* if a layer should be copied or not. alloctype must be one of the above.
* Initializes a CustomData object with the same layer setup as source. `mask` is a bit-field where
* `(mask & (1 << (layer type)))` indicates if a layer should be copied or not. Data layers using
* implicit-sharing will not actually be copied but will be shared between source and destination.
*/
void CustomData_copy(const struct CustomData *source,
struct CustomData *dest,
eCustomDataMask mask,
eCDAllocType alloctype,
int totelem);
/**
* Initializes a CustomData object with the same layers as source. The data is not copied from the
* source. Instead, the new layers are initialized using the given `alloctype`.
*/
void CustomData_copy_layout(const struct CustomData *source,
struct CustomData *dest,
eCustomDataMask mask,
eCDAllocType alloctype,
int totelem);
/* BMESH_TODO, not really a public function but readfile.c needs it */
void CustomData_update_typemap(struct CustomData *data);
/**
* Same as the above, except that this will preserve existing layers, and only
* add the layers that were not there yet.
* Copies all layers from source to destination that don't exist there yet.
*/
bool CustomData_merge(const struct CustomData *source,
struct CustomData *dest,
eCustomDataMask mask,
eCDAllocType alloctype,
int totelem);
/**
* Copies all layers from source to destination that don't exist there yet. The layer data is not
* copied. Instead the newly created layers are initialized using the given `alloctype`.
*/
bool CustomData_merge_layout(const struct CustomData *source,
struct CustomData *dest,
eCustomDataMask mask,
eCDAllocType alloctype,
int totelem);
/**
* Reallocate custom data to a new element count. If the new size is larger, the new values use
@ -189,16 +199,16 @@ bool CustomData_merge(const struct CustomData *source,
void CustomData_realloc(struct CustomData *data, int old_size, int new_size);
/**
* BMesh version of CustomData_merge; merges the layouts of source and `dest`,
* BMesh version of CustomData_merge_layout; merges the layouts of source and `dest`,
* then goes through the mesh and makes sure all the custom-data blocks are
* consistent with the new layout.
*/
bool CustomData_bmesh_merge(const struct CustomData *source,
struct CustomData *dest,
eCustomDataMask mask,
eCDAllocType alloctype,
struct BMesh *bm,
char htype);
bool CustomData_bmesh_merge_layout(const struct CustomData *source,
struct CustomData *dest,
eCustomDataMask mask,
eCDAllocType alloctype,
struct BMesh *bm,
char htype);
/**
* Remove layers that aren't stored in BMesh or are stored as flags on BMesh.
@ -229,18 +239,25 @@ void CustomData_free_typemask(struct CustomData *data, int totelem, eCustomDataM
void CustomData_free_temporary(struct CustomData *data, int totelem);
/**
* Adds a data layer of the given type to the #CustomData object, optionally
* backed by an external data array. the different allocation types are
* defined above. returns the data of the layer.
* Adds a layer of the given type to the #CustomData object. The new layer is initialized based on
* the given alloctype.
* \return The layer data.
*/
void *CustomData_add_layer(struct CustomData *data,
eCustomDataType type,
eCDAllocType alloctype,
int totelem);
/**
* Adds a layer of the given type to the #CustomData object. The new layer takes ownership of the
* passed in `layer_data`. If a #ImplicitSharingInfoHandle is passed in, its user count is
* increased.
*/
const void *CustomData_add_layer_with_data(struct CustomData *data,
eCustomDataType type,
void *layer_data,
int totelem);
int totelem,
const ImplicitSharingInfoHandle *sharing_info);
/**
* Same as above but accepts a name.
@ -250,17 +267,26 @@ void *CustomData_add_layer_named(struct CustomData *data,
eCDAllocType alloctype,
int totelem,
const char *name);
const void *CustomData_add_layer_named_with_data(struct CustomData *data,
eCustomDataType type,
void *layer_data,
int totelem,
const char *name);
const char *name,
const ImplicitSharingInfoHandle *sharing_info);
void *CustomData_add_layer_anonymous(struct CustomData *data,
eCustomDataType type,
eCDAllocType alloctype,
void *layer,
int totelem,
const AnonymousAttributeIDHandle *anonymous_id);
const void *CustomData_add_layer_anonymous_with_data(
struct CustomData *data,
eCustomDataType type,
const AnonymousAttributeIDHandle *anonymous_id,
int totelem,
void *layer_data,
const ImplicitSharingInfoHandle *sharing_info);
/**
* Frees the active or first data layer with the give type.
@ -296,11 +322,6 @@ int CustomData_number_of_layers(const struct CustomData *data, eCustomDataType t
int CustomData_number_of_anonymous_layers(const struct CustomData *data, eCustomDataType type);
int CustomData_number_of_layers_typemask(const struct CustomData *data, eCustomDataMask mask);
/**
* Duplicate all the layers with flag NOFREE, and remove the flag from duplicated layers.
*/
void CustomData_duplicate_referenced_layers(CustomData *data, int totelem);
/**
* Set the #CD_FLAG_NOCOPY flag in custom data layers where the mask is
* zero for the layer type, so only layer types specified by the mask will be copied

View File

@ -54,37 +54,45 @@ enum {
* This means callback shall not *do* anything, only use this as informative data if it needs it.
*/
IDWALK_CB_EMBEDDED = (1 << 4),
/**
* That ID pointer points to an embedded ID, but does not own it.
*
* E.g the `collection` pointer of the first ViewLayerCollection of a ViewLayer should always
* point to the scene's master collection, which is an embedded ID 'owned' by
* `Scene.master_collection`.
*/
IDWALK_CB_EMBEDDED_NOT_OWNING = (1 << 5),
/**
* That ID is not really used by its owner, it's just an internal hint/helper.
* This marks the 'from' pointers issue, like Key->from.
* How to handle that kind of cases totally depends on what caller code is doing... */
IDWALK_CB_LOOPBACK = (1 << 5),
IDWALK_CB_LOOPBACK = (1 << 6),
/** That ID is used as library override's reference by its owner. */
IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE = (1 << 6),
IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE = (1 << 7),
/** That ID pointer is not overridable. */
IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE = (1 << 7),
IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE = (1 << 8),
/**
* Indicates that this is an internal runtime ID pointer, like e.g. `ID.newid` or `ID.original`.
* \note Those should be ignored in most cases, and won't be processed/generated anyway unless
* `IDWALK_DO_INTERNAL_RUNTIME_POINTERS` option is enabled.
*/
IDWALK_CB_INTERNAL = (1 << 8),
IDWALK_CB_INTERNAL = (1 << 9),
/**
* This ID usage is fully refcounted.
* Callback is responsible to deal accordingly with #ID.us if needed.
*/
IDWALK_CB_USER = (1 << 9),
IDWALK_CB_USER = (1 << 10),
/**
* This ID usage is not refcounted, but at least one user should be generated by it (to avoid
* e.g. losing the used ID on save/reload).
* Callback is responsible to deal accordingly with #ID.us if needed.
*/
IDWALK_CB_USER_ONE = (1 << 10),
IDWALK_CB_USER_ONE = (1 << 11),
};
enum {
@ -123,7 +131,9 @@ typedef int (*LibraryIDLinkCallback)(LibraryIDLinkCallbackData *cb_data);
/* Flags for the foreach function itself. */
enum {
IDWALK_NOP = 0,
/** The callback will never modify the ID pointers it processes. */
/** The callback will never modify the ID pointers it processes.
* WARNING: It is very important to pass this flag when valid, as it can lead to important
* optimizations and debug/assert code. */
IDWALK_READONLY = (1 << 0),
/** Recurse into 'descendant' IDs.
* Each ID is only processed once. Order of ID processing is not guaranteed.

View File

@ -562,8 +562,6 @@ void BKE_pbvh_update_hide_attributes_from_mesh(PBVH *pbvh);
void BKE_pbvh_face_sets_color_set(PBVH *pbvh, int seed, int color_default);
void BKE_pbvh_respect_hide_set(PBVH *pbvh, bool respect_hide);
/* Vertex Deformer. */
float (*BKE_pbvh_vert_coords_alloc(struct PBVH *pbvh))[3];
@ -591,7 +589,6 @@ typedef struct PBVHVertexIter {
int i;
int index;
PBVHVertRef vertex;
bool respect_hide;
/* grid */
struct CCGKey key;
@ -664,14 +661,9 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
} \
} \
else if (vi.vert_positions) { \
if (vi.respect_hide) { \
vi.visible = !(vi.hide_vert && vi.hide_vert[vi.vert_indices[vi.gx]]); \
if (mode == PBVH_ITER_UNIQUE && !vi.visible) { \
continue; \
} \
} \
else { \
BLI_assert(vi.visible); \
vi.visible = !(vi.hide_vert && vi.hide_vert[vi.vert_indices[vi.gx]]); \
if (mode == PBVH_ITER_UNIQUE && !vi.visible) { \
continue; \
} \
vi.co = vi.vert_positions[vi.vert_indices[vi.gx]]; \
vi.no = vi.vert_normals[vi.vert_indices[vi.gx]]; \

View File

@ -13,6 +13,10 @@
# include "BLI_bounds_types.hh"
# include "BLI_math_vector_types.hh"
# include "BLI_shared_cache.hh"
# include "DNA_pointcloud_types.h"
# include "BKE_customdata.h"
#endif
#ifdef __cplusplus
@ -45,6 +49,21 @@ struct PointCloudRuntime {
};
} // namespace blender::bke
inline blender::Span<blender::float3> PointCloud::positions() const
{
return {static_cast<const blender::float3 *>(
CustomData_get_layer_named(&this->pdata, CD_PROP_FLOAT3, "position")),
this->totpoint};
}
inline blender::MutableSpan<blender::float3> PointCloud::positions_for_write()
{
return {static_cast<blender::float3 *>(CustomData_get_layer_named_for_write(
&this->pdata, CD_PROP_FLOAT3, "position", this->totpoint)),
this->totpoint};
}
#endif
void *BKE_pointcloud_add(struct Main *bmain, const char *name);

View File

@ -12,7 +12,7 @@ set(INC
../depsgraph
../draw
../functions
../gpencil_modifiers
../gpencil_modifiers_legacy
../gpu
../ikplugin
../imbuf
@ -525,7 +525,7 @@ set(LIB
bf_depsgraph
bf_draw
bf_functions
bf_gpencil_modifiers
bf_gpencil_modifiers_legacy
bf_gpu
bf_ikplugin
bf_imbuf

View File

@ -207,11 +207,12 @@ void DM_from_template(DerivedMesh *dm,
int numPolys)
{
const CustomData_MeshMasks *mask = &CD_MASK_DERIVEDMESH;
CustomData_copy(&source->vertData, &dm->vertData, mask->vmask, CD_SET_DEFAULT, numVerts);
CustomData_copy(&source->edgeData, &dm->edgeData, mask->emask, CD_SET_DEFAULT, numEdges);
CustomData_copy(&source->faceData, &dm->faceData, mask->fmask, CD_SET_DEFAULT, numTessFaces);
CustomData_copy(&source->loopData, &dm->loopData, mask->lmask, CD_SET_DEFAULT, numLoops);
CustomData_copy(&source->polyData, &dm->polyData, mask->pmask, CD_SET_DEFAULT, numPolys);
CustomData_copy_layout(&source->vertData, &dm->vertData, mask->vmask, CD_SET_DEFAULT, numVerts);
CustomData_copy_layout(&source->edgeData, &dm->edgeData, mask->emask, CD_SET_DEFAULT, numEdges);
CustomData_copy_layout(
&source->faceData, &dm->faceData, mask->fmask, CD_SET_DEFAULT, numTessFaces);
CustomData_copy_layout(&source->loopData, &dm->loopData, mask->lmask, CD_SET_DEFAULT, numLoops);
CustomData_copy_layout(&source->polyData, &dm->polyData, mask->pmask, CD_SET_DEFAULT, numPolys);
dm->poly_offsets = static_cast<int *>(MEM_dupallocN(source->poly_offsets));
dm->type = type;

View File

@ -92,17 +92,19 @@ static int attribute_data_type_complexity(const eCustomDataType data_type)
return 2;
case CD_PROP_FLOAT:
return 3;
case CD_PROP_FLOAT2:
case CD_PROP_INT32_2D:
return 4;
case CD_PROP_FLOAT3:
case CD_PROP_FLOAT2:
return 5;
case CD_PROP_BYTE_COLOR:
case CD_PROP_FLOAT3:
return 6;
case CD_PROP_COLOR:
case CD_PROP_BYTE_COLOR:
return 7;
case CD_PROP_COLOR:
return 8;
#if 0 /* These attribute types are not supported yet. */
case CD_PROP_STRING:
return 6;
return 9;
#endif
default:
/* Only accept "generic" custom data types used by the attribute system. */
@ -201,13 +203,16 @@ static bool add_builtin_type_custom_data_layer_from_init(CustomData &custom_data
return true;
}
case AttributeInit::Type::MoveArray: {
void *source_data = static_cast<const AttributeInitMoveArray &>(initializer).data;
const void *data = CustomData_add_layer_with_data(
&custom_data, data_type, source_data, domain_num);
if (data == nullptr) {
MEM_freeN(source_data);
void *src_data = static_cast<const AttributeInitMoveArray &>(initializer).data;
const void *stored_data = CustomData_add_layer_with_data(
&custom_data, data_type, src_data, domain_num, nullptr);
if (stored_data == nullptr) {
return false;
}
if (stored_data != src_data) {
MEM_freeN(src_data);
return true;
}
return true;
}
}
@ -230,25 +235,26 @@ static void *add_generic_custom_data_layer(CustomData &custom_data,
}
const AnonymousAttributeID &anonymous_id = attribute_id.anonymous_id();
return CustomData_add_layer_anonymous(
&custom_data, data_type, alloctype, nullptr, domain_size, &anonymous_id);
&custom_data, data_type, alloctype, domain_size, &anonymous_id);
}
static const void *add_generic_custom_data_layer_with_existing_data(
CustomData &custom_data,
const eCustomDataType data_type,
void *layer_data,
const AttributeIDRef &attribute_id,
const int domain_size,
const AttributeIDRef &attribute_id)
void *layer_data,
const ImplicitSharingInfo *sharing_info)
{
if (!attribute_id.is_anonymous()) {
char attribute_name_c[MAX_CUSTOMDATA_LAYER_NAME];
attribute_id.name().copy(attribute_name_c);
return CustomData_add_layer_named_with_data(
&custom_data, data_type, layer_data, domain_size, attribute_name_c);
if (attribute_id.is_anonymous()) {
const AnonymousAttributeID &anonymous_id = attribute_id.anonymous_id();
return CustomData_add_layer_anonymous_with_data(
&custom_data, data_type, &anonymous_id, domain_size, layer_data, sharing_info);
}
const AnonymousAttributeID &anonymous_id = attribute_id.anonymous_id();
return CustomData_add_layer_anonymous(
&custom_data, data_type, CD_ASSIGN, layer_data, domain_size, &anonymous_id);
char attribute_name_c[MAX_CUSTOMDATA_LAYER_NAME];
attribute_id.name().copy(attribute_name_c);
return CustomData_add_layer_named_with_data(
&custom_data, data_type, layer_data, domain_size, attribute_name_c, sharing_info);
}
static bool add_custom_data_layer_from_attribute_init(const AttributeIDRef &attribute_id,
@ -279,9 +285,9 @@ static bool add_custom_data_layer_from_attribute_init(const AttributeIDRef &attr
break;
}
case AttributeInit::Type::MoveArray: {
void *source_data = static_cast<const AttributeInitMoveArray &>(initializer).data;
void *data = static_cast<const AttributeInitMoveArray &>(initializer).data;
add_generic_custom_data_layer_with_existing_data(
custom_data, data_type, source_data, domain_num, attribute_id);
custom_data, data_type, attribute_id, domain_num, data, nullptr);
break;
}
}
@ -571,7 +577,7 @@ CustomDataAttributes::~CustomDataAttributes()
CustomDataAttributes::CustomDataAttributes(const CustomDataAttributes &other)
{
size_ = other.size_;
CustomData_copy(&other.data, &data, CD_MASK_ALL, CD_DUPLICATE, size_);
CustomData_copy(&other.data, &data, CD_MASK_ALL, size_);
}
CustomDataAttributes::CustomDataAttributes(CustomDataAttributes &&other)
@ -655,15 +661,6 @@ bool CustomDataAttributes::create(const AttributeIDRef &attribute_id,
return result != nullptr;
}
bool CustomDataAttributes::create_by_move(const AttributeIDRef &attribute_id,
const eCustomDataType data_type,
void *buffer)
{
const void *result = add_generic_custom_data_layer_with_existing_data(
data, data_type, buffer, size_, attribute_id);
return result != nullptr;
}
bool CustomDataAttributes::remove(const AttributeIDRef &attribute_id)
{
for (const int i : IndexRange(data.totlayer)) {

View File

@ -923,8 +923,8 @@ static int foreach_libblock_link_append_callback(LibraryIDLinkCallbackData *cb_d
{
/* NOTE: It is important to also skip liboverride references here, as those should never be made
* local. */
if (cb_data->cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_INTERNAL | IDWALK_CB_LOOPBACK |
IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE)) {
if (cb_data->cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_EMBEDDED_NOT_OWNING | IDWALK_CB_INTERNAL |
IDWALK_CB_LOOPBACK | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE)) {
return IDWALK_RET_NOP;
}

View File

@ -26,6 +26,7 @@
#include "BKE_editmesh.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.h"
#include "BKE_pointcloud.h"
#include "MEM_guardedalloc.h"
@ -1425,10 +1426,7 @@ BVHTree *BKE_bvhtree_from_pointcloud_get(BVHTreeFromPointCloud *data,
return nullptr;
}
blender::bke::AttributeAccessor attributes = pointcloud->attributes();
blender::VArraySpan<blender::float3> positions = attributes.lookup_or_default<blender::float3>(
"position", ATTR_DOMAIN_POINT, blender::float3(0));
const Span<float3> positions = pointcloud->positions();
for (const int i : positions.index_range()) {
BLI_bvhtree_insert(tree, i, positions[i], 1);
}

View File

@ -147,9 +147,7 @@ static CDDerivedMesh *cdDM_create(const char *desc)
return cddm;
}
static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
eCDAllocType alloctype,
const CustomData_MeshMasks *mask)
static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh, const CustomData_MeshMasks *mask)
{
CDDerivedMesh *cddm = cdDM_create(__func__);
DerivedMesh *dm = &cddm->dm;
@ -167,15 +165,14 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
mesh->totloop,
mesh->totpoly);
CustomData_merge(&mesh->vdata, &dm->vertData, cddata_masks.vmask, alloctype, mesh->totvert);
CustomData_merge(&mesh->edata, &dm->edgeData, cddata_masks.emask, alloctype, mesh->totedge);
CustomData_merge(&mesh->vdata, &dm->vertData, cddata_masks.vmask, mesh->totvert);
CustomData_merge(&mesh->edata, &dm->edgeData, cddata_masks.emask, mesh->totedge);
CustomData_merge(&mesh->fdata,
&dm->faceData,
cddata_masks.fmask | CD_MASK_ORIGINDEX,
alloctype,
0 /* `mesh->totface` */);
CustomData_merge(&mesh->ldata, &dm->loopData, cddata_masks.lmask, alloctype, mesh->totloop);
CustomData_merge(&mesh->pdata, &dm->polyData, cddata_masks.pmask, alloctype, mesh->totpoly);
CustomData_merge(&mesh->ldata, &dm->loopData, cddata_masks.lmask, mesh->totloop);
CustomData_merge(&mesh->pdata, &dm->polyData, cddata_masks.pmask, mesh->totpoly);
cddm->vert_positions = static_cast<float(*)[3]>(CustomData_get_layer_named_for_write(
&dm->vertData, CD_PROP_FLOAT3, "position", mesh->totvert));
@ -203,5 +200,5 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
DerivedMesh *CDDM_from_mesh(Mesh *mesh)
{
return cdDM_from_mesh_ex(mesh, CD_REFERENCE, &CD_MASK_MESH);
return cdDM_from_mesh_ex(mesh, &CD_MASK_MESH);
}

View File

@ -62,45 +62,18 @@ static void curves_init_data(ID *id)
new (&curves->geometry) blender::bke::CurvesGeometry();
}
static void curves_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int flag)
static void curves_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int /*flag*/)
{
using namespace blender;
Curves *curves_dst = (Curves *)id_dst;
const Curves *curves_src = (const Curves *)id_src;
curves_dst->mat = static_cast<Material **>(MEM_dupallocN(curves_src->mat));
const bke::CurvesGeometry &src = curves_src->geometry.wrap();
bke::CurvesGeometry &dst = curves_dst->geometry.wrap();
/* We need special handling here because the generic ID management code has already done a
* shallow copy from the source to the destination, and because the copy-on-write functionality
* isn't supported more generically yet. */
dst.point_num = src.point_num;
dst.curve_num = src.curve_num;
const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
CustomData_copy(&src.point_data, &dst.point_data, CD_MASK_ALL, alloc_type, dst.point_num);
CustomData_copy(&src.curve_data, &dst.curve_data, CD_MASK_ALL, alloc_type, dst.curve_num);
dst.curve_offsets = static_cast<int *>(MEM_dupallocN(src.curve_offsets));
new (&curves_dst->geometry) blender::bke::CurvesGeometry(curves_src->geometry.wrap());
if (curves_src->surface_uv_map != nullptr) {
curves_dst->surface_uv_map = BLI_strdup(curves_src->surface_uv_map);
}
dst.runtime = MEM_new<bke::CurvesGeometryRuntime>(__func__);
dst.runtime->type_counts = src.runtime->type_counts;
dst.runtime->evaluated_offsets_cache = src.runtime->evaluated_offsets_cache;
dst.runtime->nurbs_basis_cache = src.runtime->nurbs_basis_cache;
dst.runtime->evaluated_position_cache = src.runtime->evaluated_position_cache;
dst.runtime->bounds_cache = src.runtime->bounds_cache;
dst.runtime->evaluated_length_cache = src.runtime->evaluated_length_cache;
dst.runtime->evaluated_tangent_cache = src.runtime->evaluated_tangent_cache;
dst.runtime->evaluated_normal_cache = src.runtime->evaluated_normal_cache;
curves_dst->batch_cache = nullptr;
}

View File

@ -80,8 +80,8 @@ static void copy_curves_geometry(CurvesGeometry &dst, const CurvesGeometry &src)
CustomData_free(&dst.curve_data, dst.curve_num);
dst.point_num = src.point_num;
dst.curve_num = src.curve_num;
CustomData_copy(&src.point_data, &dst.point_data, CD_MASK_ALL, CD_DUPLICATE, dst.point_num);
CustomData_copy(&src.curve_data, &dst.curve_data, CD_MASK_ALL, CD_DUPLICATE, dst.curve_num);
CustomData_copy(&src.point_data, &dst.point_data, CD_MASK_ALL, dst.point_num);
CustomData_copy(&src.curve_data, &dst.curve_data, CD_MASK_ALL, dst.curve_num);
MEM_SAFE_FREE(dst.curve_offsets);
dst.curve_offsets = (int *)MEM_malloc_arrayN(dst.point_num + 1, sizeof(int), __func__);

View File

@ -101,11 +101,8 @@ void fill_points(const OffsetIndices<int> points_by_curve,
bke::CurvesGeometry copy_only_curve_domain(const bke::CurvesGeometry &src_curves)
{
bke::CurvesGeometry dst_curves(0, src_curves.curves_num());
CustomData_copy(&src_curves.curve_data,
&dst_curves.curve_data,
CD_MASK_ALL,
CD_DUPLICATE,
src_curves.curves_num());
CustomData_copy(
&src_curves.curve_data, &dst_curves.curve_data, CD_MASK_ALL, src_curves.curves_num());
dst_curves.runtime->type_counts = src_curves.runtime->type_counts;
return dst_curves;
}

View File

@ -59,6 +59,7 @@
#include "data_transfer_intern.h"
using blender::float2;
using blender::ImplicitSharingInfo;
using blender::IndexRange;
using blender::Set;
using blender::Span;
@ -1891,8 +1892,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(float), "MFloatProperty", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
/* 45: CD_PROP_INT8 */
{sizeof(int8_t), "MInt8Property", 1, N_("Int8"), nullptr, nullptr, nullptr, nullptr, nullptr},
/* 46: CD_HAIRMAPPING */ /* UNUSED */
{-1, "", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
/* 46: CD_PROP_INT32_2D */
{sizeof(vec2i), "vec2i", 1, N_("Int 2D"), nullptr, nullptr, nullptr, nullptr, nullptr},
/* 47: CD_PROP_COLOR */
{sizeof(MPropCol),
"MPropCol",
@ -2158,12 +2159,14 @@ void customData_mask_layers__print(const CustomData_MeshMasks *mask)
static void customData_update_offsets(CustomData *data);
static CustomDataLayer *customData_add_layer__internal(CustomData *data,
eCustomDataType type,
eCDAllocType alloctype,
void *layerdata,
int totelem,
const char *name);
static CustomDataLayer *customData_add_layer__internal(
CustomData *data,
eCustomDataType type,
std::optional<eCDAllocType> alloctype,
void *layer_data_to_assign,
const ImplicitSharingInfo *sharing_info_to_assign,
int totelem,
const char *name);
void CustomData_update_typemap(CustomData *data)
{
@ -2192,93 +2195,113 @@ static bool customdata_typemap_is_valid(const CustomData *data)
}
#endif
bool CustomData_merge(const CustomData *source,
CustomData *dest,
eCustomDataMask mask,
eCDAllocType alloctype,
int totelem)
static void *copy_layer_data(const eCustomDataType type, const void *data, const int totelem)
{
const LayerTypeInfo &type_info = *layerType_getInfo(type);
if (type_info.copy) {
void *new_data = MEM_malloc_arrayN(size_t(totelem), type_info.size, __func__);
type_info.copy(data, new_data, totelem);
return new_data;
}
return MEM_dupallocN(data);
}
static void free_layer_data(const eCustomDataType type, const void *data, const int totelem)
{
const LayerTypeInfo &type_info = *layerType_getInfo(type);
if (type_info.free) {
type_info.free(const_cast<void *>(data), totelem, type_info.size);
}
MEM_freeN(const_cast<void *>(data));
}
static bool customdata_merge_internal(const CustomData *source,
CustomData *dest,
const eCustomDataMask mask,
const std::optional<eCDAllocType> alloctype,
const int totelem)
{
// const LayerTypeInfo *typeInfo;
CustomDataLayer *layer, *newlayer;
int lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0;
int number = 0, maxnumber = -1;
bool changed = false;
int last_type = -1;
int last_active = 0;
int last_render = 0;
int last_clone = 0;
int last_mask = 0;
int current_type_layer_count = 0;
int max_current_type_layer_count = -1;
for (int i = 0; i < source->totlayer; i++) {
layer = &source->layers[i];
// typeInfo = layerType_getInfo(eCustomDataType(layer->type)); /* UNUSED */
const CustomDataLayer &src_layer = source->layers[i];
const eCustomDataType type = eCustomDataType(src_layer.type);
const int src_layer_flag = src_layer.flag;
const eCustomDataType type = eCustomDataType(layer->type);
int flag = layer->flag;
if (type != lasttype) {
number = 0;
maxnumber = CustomData_layertype_layers_max(type);
lastactive = layer->active;
lastrender = layer->active_rnd;
lastclone = layer->active_clone;
lastmask = layer->active_mask;
lasttype = type;
if (type != last_type) {
current_type_layer_count = 0;
max_current_type_layer_count = CustomData_layertype_layers_max(type);
last_active = src_layer.active;
last_render = src_layer.active_rnd;
last_clone = src_layer.active_clone;
last_mask = src_layer.active_mask;
last_type = type;
}
else {
number++;
current_type_layer_count++;
}
if (flag & CD_FLAG_NOCOPY) {
if (src_layer_flag & CD_FLAG_NOCOPY) {
/* Don't merge this layer because it's not supposed to leave the source data. */
continue;
}
if (!(mask & CD_TYPE_AS_MASK(type))) {
/* Don't merge this layer because it does not match the type mask. */
continue;
}
if ((maxnumber != -1) && (number >= maxnumber)) {
if ((max_current_type_layer_count != -1) &&
(current_type_layer_count >= max_current_type_layer_count)) {
/* Don't merge this layer because the maximum amount of layers of this type is reached. */
continue;
}
if (CustomData_get_named_layer_index(dest, type, layer->name) != -1) {
if (CustomData_get_named_layer_index(dest, type, src_layer.name) != -1) {
/* Don't merge this layer because it exists in the destination already. */
continue;
}
void *data;
switch (alloctype) {
case CD_ASSIGN:
case CD_REFERENCE:
case CD_DUPLICATE:
data = layer->data;
break;
default:
data = nullptr;
break;
}
if ((alloctype == CD_ASSIGN) && (flag & CD_FLAG_NOFREE)) {
newlayer = customData_add_layer__internal(
dest, type, CD_REFERENCE, data, totelem, layer->name);
}
else {
newlayer = customData_add_layer__internal(dest, type, alloctype, data, totelem, layer->name);
}
if (newlayer) {
newlayer->uid = layer->uid;
newlayer->active = lastactive;
newlayer->active_rnd = lastrender;
newlayer->active_clone = lastclone;
newlayer->active_mask = lastmask;
newlayer->flag |= flag & (CD_FLAG_EXTERNAL | CD_FLAG_IN_MEMORY);
changed = true;
if (layer->anonymous_id != nullptr) {
newlayer->anonymous_id = layer->anonymous_id;
if (alloctype == CD_ASSIGN) {
layer->anonymous_id = nullptr;
void *layer_data_to_assign = nullptr;
const ImplicitSharingInfo *sharing_info_to_assign = nullptr;
if (!alloctype.has_value()) {
if (src_layer.data != nullptr) {
if (src_layer.sharing_info == nullptr) {
/* Can't share the layer, duplicate it instead. */
layer_data_to_assign = copy_layer_data(type, src_layer.data, totelem);
}
else {
layer->anonymous_id->add_user();
/* Share the layer. */
layer_data_to_assign = src_layer.data;
sharing_info_to_assign = src_layer.sharing_info;
}
}
if (alloctype == CD_ASSIGN) {
layer->data = nullptr;
}
}
CustomDataLayer *new_layer = customData_add_layer__internal(dest,
type,
alloctype,
layer_data_to_assign,
sharing_info_to_assign,
totelem,
src_layer.name);
new_layer->uid = src_layer.uid;
new_layer->flag |= src_layer_flag & (CD_FLAG_EXTERNAL | CD_FLAG_IN_MEMORY);
new_layer->active = last_active;
new_layer->active_rnd = last_render;
new_layer->active_clone = last_clone;
new_layer->active_mask = last_mask;
changed = true;
if (src_layer.anonymous_id != nullptr) {
new_layer->anonymous_id = src_layer.anonymous_id;
new_layer->anonymous_id->add_user();
}
}
@ -2286,6 +2309,23 @@ bool CustomData_merge(const CustomData *source,
return changed;
}
bool CustomData_merge(const CustomData *source,
CustomData *dest,
eCustomDataMask mask,
int totelem)
{
return customdata_merge_internal(source, dest, mask, std::nullopt, totelem);
}
bool CustomData_merge_layout(const CustomData *source,
CustomData *dest,
const eCustomDataMask mask,
const eCDAllocType alloctype,
const int totelem)
{
return customdata_merge_internal(source, dest, mask, alloctype, totelem);
}
CustomData CustomData_shallow_copy_remove_non_bmesh_attributes(const CustomData *src,
const eCustomDataMask mask)
{
@ -2311,28 +2351,91 @@ CustomData CustomData_shallow_copy_remove_non_bmesh_attributes(const CustomData
return dst;
}
/**
* An #ImplicitSharingInfo that knows how to free the entire referenced custom data layer
* (including potentially separately allocated chunks like for vertex groups).
*/
class CustomDataLayerImplicitSharing : public ImplicitSharingInfo {
private:
const void *data_;
const int totelem_;
const eCustomDataType type_;
public:
CustomDataLayerImplicitSharing(const void *data, const int totelem, const eCustomDataType type)
: ImplicitSharingInfo(1), data_(data), totelem_(totelem), type_(type)
{
}
private:
void delete_self_with_data() override
{
free_layer_data(type_, data_, totelem_);
MEM_delete(this);
}
};
/** Create a #ImplicitSharingInfo that takes ownership of the data. */
static ImplicitSharingInfo *make_implicit_sharing_info_for_layer(const eCustomDataType type,
const void *data,
const int totelem)
{
return MEM_new<CustomDataLayerImplicitSharing>(__func__, data, totelem, type);
}
/**
* If the layer data is currently shared (hence it is immutable), create a copy that can be edited.
*/
static void ensure_layer_data_is_mutable(CustomDataLayer &layer, const int totelem)
{
if (layer.data == nullptr) {
return;
}
if (layer.sharing_info == nullptr) {
/* Can not be shared without implicit-sharing data. */
return;
}
if (layer.sharing_info->is_shared()) {
const eCustomDataType type = eCustomDataType(layer.type);
const void *old_data = layer.data;
/* Copy the layer before removing the user because otherwise the data might be freed while
* we're still copying from it here. */
layer.data = copy_layer_data(type, old_data, totelem);
layer.sharing_info->remove_user_and_delete_if_last();
layer.sharing_info = make_implicit_sharing_info_for_layer(type, layer.data, totelem);
}
}
void CustomData_realloc(CustomData *data, const int old_size, const int new_size)
{
BLI_assert(new_size >= 0);
for (int i = 0; i < data->totlayer; i++) {
CustomDataLayer *layer = &data->layers[i];
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(layer->type));
const int64_t old_size_in_bytes = int64_t(old_size) * typeInfo->size;
const int64_t new_size_in_bytes = int64_t(new_size) * typeInfo->size;
if (layer->flag & CD_FLAG_NOFREE) {
const void *old_data = layer->data;
layer->data = MEM_malloc_arrayN(new_size, typeInfo->size, __func__);
void *new_layer_data = MEM_mallocN(new_size_in_bytes, __func__);
/* Copy data to new array. */
if (old_size_in_bytes) {
if (typeInfo->copy) {
typeInfo->copy(old_data, layer->data, std::min(old_size, new_size));
typeInfo->copy(layer->data, new_layer_data, std::min(old_size, new_size));
}
else {
std::memcpy(layer->data, old_data, std::min(old_size_in_bytes, new_size_in_bytes));
BLI_assert(layer->data != nullptr);
memcpy(new_layer_data, layer->data, std::min(old_size_in_bytes, new_size_in_bytes));
}
layer->flag &= ~CD_FLAG_NOFREE;
}
else {
layer->data = MEM_reallocN(layer->data, new_size_in_bytes);
/* Remove ownership of old array */
if (layer->sharing_info) {
layer->sharing_info->remove_user_and_delete_if_last();
layer->sharing_info = nullptr;
}
/* Take ownership of new array. */
layer->data = new_layer_data;
if (layer->data) {
layer->sharing_info = make_implicit_sharing_info_for_layer(
eCustomDataType(layer->type), layer->data, new_size);
}
if (new_size > old_size) {
@ -2345,11 +2448,7 @@ void CustomData_realloc(CustomData *data, const int old_size, const int new_size
}
}
void CustomData_copy(const CustomData *source,
CustomData *dest,
eCustomDataMask mask,
eCDAllocType alloctype,
int totelem)
void CustomData_copy(const CustomData *source, CustomData *dest, eCustomDataMask mask, int totelem)
{
CustomData_reset(dest);
@ -2357,28 +2456,40 @@ void CustomData_copy(const CustomData *source,
dest->external = static_cast<CustomDataExternal *>(MEM_dupallocN(source->external));
}
CustomData_merge(source, dest, mask, alloctype, totelem);
CustomData_merge(source, dest, mask, totelem);
}
void CustomData_copy_layout(const struct CustomData *source,
struct CustomData *dest,
eCustomDataMask mask,
eCDAllocType alloctype,
int totelem)
{
CustomData_reset(dest);
if (source->external) {
dest->external = static_cast<CustomDataExternal *>(MEM_dupallocN(source->external));
}
CustomData_merge_layout(source, dest, mask, alloctype, totelem);
}
static void customData_free_layer__internal(CustomDataLayer *layer, const int totelem)
{
const LayerTypeInfo *typeInfo;
if (layer->anonymous_id != nullptr) {
layer->anonymous_id->remove_user_and_delete_if_last();
layer->anonymous_id = nullptr;
}
if (!(layer->flag & CD_FLAG_NOFREE) && layer->data) {
typeInfo = layerType_getInfo(eCustomDataType(layer->type));
if (typeInfo->free) {
typeInfo->free(layer->data, totelem, typeInfo->size);
}
const eCustomDataType type = eCustomDataType(layer->type);
if (layer->sharing_info == nullptr) {
if (layer->data) {
MEM_freeN(layer->data);
free_layer_data(type, layer->data, totelem);
}
}
else {
layer->sharing_info->remove_user_and_delete_if_last();
layer->sharing_info = nullptr;
}
}
static void CustomData_external_free(CustomData *data)
@ -2738,76 +2849,26 @@ static void customData_resize(CustomData *data, const int grow_amount)
data->maxlayer += grow_amount;
}
static CustomDataLayer *customData_add_layer__internal(CustomData *data,
const eCustomDataType type,
const eCDAllocType alloctype,
void *layerdata,
const int totelem,
const char *name)
static CustomDataLayer *customData_add_layer__internal(
CustomData *data,
const eCustomDataType type,
const std::optional<eCDAllocType> alloctype,
void *layer_data_to_assign,
const ImplicitSharingInfo *sharing_info_to_assign,
const int totelem,
const char *name)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
const LayerTypeInfo &type_info = *layerType_getInfo(type);
int flag = 0;
/* Some layer types only support a single layer. */
if (!typeInfo->defaultname && CustomData_has_layer(data, type)) {
if (!type_info.defaultname && CustomData_has_layer(data, type)) {
/* This function doesn't support dealing with existing layer data for these layer types when
* the layer already exists. */
BLI_assert(layerdata == nullptr);
BLI_assert(layer_data_to_assign == nullptr);
return &data->layers[CustomData_get_layer_index(data, type)];
}
void *newlayerdata = nullptr;
switch (alloctype) {
case CD_SET_DEFAULT:
if (totelem > 0) {
if (typeInfo->set_default_value) {
newlayerdata = MEM_malloc_arrayN(totelem, typeInfo->size, layerType_getName(type));
typeInfo->set_default_value(newlayerdata, totelem);
}
else {
newlayerdata = MEM_calloc_arrayN(totelem, typeInfo->size, layerType_getName(type));
}
}
break;
case CD_CONSTRUCT:
if (totelem > 0) {
newlayerdata = MEM_malloc_arrayN(totelem, typeInfo->size, layerType_getName(type));
if (typeInfo->construct) {
typeInfo->construct(newlayerdata, totelem);
}
}
break;
case CD_ASSIGN:
if (totelem > 0) {
BLI_assert(layerdata != nullptr);
newlayerdata = layerdata;
}
else {
MEM_SAFE_FREE(layerdata);
}
break;
case CD_REFERENCE:
if (totelem > 0) {
BLI_assert(layerdata != nullptr);
newlayerdata = layerdata;
flag |= CD_FLAG_NOFREE;
}
break;
case CD_DUPLICATE:
if (totelem > 0) {
newlayerdata = MEM_malloc_arrayN(totelem, typeInfo->size, layerType_getName(type));
if (typeInfo->copy) {
typeInfo->copy(layerdata, newlayerdata, totelem);
}
else {
BLI_assert(layerdata != nullptr);
BLI_assert(newlayerdata != nullptr);
memcpy(newlayerdata, layerdata, totelem * typeInfo->size);
}
}
break;
}
int index = data->totlayer;
if (index >= data->maxlayer) {
customData_resize(data, CUSTOMDATA_GROW);
@ -2815,7 +2876,7 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
data->totlayer++;
/* keep layers ordered by type */
/* Keep layers ordered by type. */
for (; index > 0 && data->layers[index - 1].type > type; index--) {
data->layers[index] = data->layers[index - 1];
}
@ -2827,15 +2888,57 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
* leaks into the new layer. */
memset(&new_layer, 0, sizeof(CustomDataLayer));
if (alloctype.has_value()) {
switch (*alloctype) {
case CD_SET_DEFAULT: {
if (totelem > 0) {
if (type_info.set_default_value) {
new_layer.data = MEM_malloc_arrayN(totelem, type_info.size, layerType_getName(type));
type_info.set_default_value(new_layer.data, totelem);
}
else {
new_layer.data = MEM_calloc_arrayN(totelem, type_info.size, layerType_getName(type));
}
}
break;
}
case CD_CONSTRUCT: {
if (totelem > 0) {
new_layer.data = MEM_malloc_arrayN(totelem, type_info.size, layerType_getName(type));
if (type_info.construct) {
type_info.construct(new_layer.data, totelem);
}
}
break;
}
}
}
else {
if (totelem == 0 && sharing_info_to_assign == nullptr) {
MEM_SAFE_FREE(layer_data_to_assign);
}
else {
new_layer.data = layer_data_to_assign;
new_layer.sharing_info = sharing_info_to_assign;
if (new_layer.sharing_info) {
new_layer.sharing_info->add_user();
}
}
}
if (new_layer.data != nullptr && new_layer.sharing_info == nullptr) {
/* Make layer data shareable. */
new_layer.sharing_info = make_implicit_sharing_info_for_layer(type, new_layer.data, totelem);
}
new_layer.type = type;
new_layer.flag = flag;
new_layer.data = newlayerdata;
/* Set default name if none exists. Note we only call DATA_() once
* we know there is a default name, to avoid overhead of locale lookups
* in the depsgraph. */
if (!name && typeInfo->defaultname) {
name = DATA_(typeInfo->defaultname);
if (!name && type_info.defaultname) {
name = DATA_(type_info.defaultname);
}
if (name) {
@ -2864,16 +2967,15 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
return &data->layers[index];
}
static void *customdata_add_layer(CustomData *data,
const eCustomDataType type,
eCDAllocType alloctype,
void *layerdata,
const int totelem)
void *CustomData_add_layer(CustomData *data,
const eCustomDataType type,
eCDAllocType alloctype,
const int totelem)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
CustomDataLayer *layer = customData_add_layer__internal(
data, type, alloctype, layerdata, totelem, typeInfo->defaultname);
data, type, alloctype, nullptr, nullptr, totelem, typeInfo->defaultname);
CustomData_update_typemap(data);
if (layer) {
@ -2883,31 +2985,16 @@ static void *customdata_add_layer(CustomData *data,
return nullptr;
}
void *CustomData_add_layer(CustomData *data,
const eCustomDataType type,
const eCDAllocType alloctype,
const int totelem)
{
return customdata_add_layer(data, type, alloctype, nullptr, totelem);
}
const void *CustomData_add_layer_with_data(CustomData *data,
const eCustomDataType type,
void *layer_data,
const int totelem)
const int totelem,
const ImplicitSharingInfo *sharing_info)
{
return customdata_add_layer(data, type, CD_ASSIGN, layer_data, totelem);
}
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
static void *customdata_add_layer_named(CustomData *data,
const eCustomDataType type,
const eCDAllocType alloctype,
void *layerdata,
const int totelem,
const char *name)
{
CustomDataLayer *layer = customData_add_layer__internal(
data, type, alloctype, layerdata, totelem, name);
data, type, std::nullopt, layer_data, sharing_info, totelem, typeInfo->defaultname);
CustomData_update_typemap(data);
if (layer) {
@ -2923,25 +3010,42 @@ void *CustomData_add_layer_named(CustomData *data,
const int totelem,
const char *name)
{
return customdata_add_layer_named(data, type, alloctype, nullptr, totelem, name);
CustomDataLayer *layer = customData_add_layer__internal(
data, type, alloctype, nullptr, nullptr, totelem, name);
CustomData_update_typemap(data);
if (layer) {
return layer->data;
}
return nullptr;
}
const void *CustomData_add_layer_named_with_data(
CustomData *data, const eCustomDataType type, void *layer_data, int totelem, const char *name)
const void *CustomData_add_layer_named_with_data(CustomData *data,
eCustomDataType type,
void *layer_data,
int totelem,
const char *name,
const ImplicitSharingInfo *sharing_info)
{
return customdata_add_layer_named(data, type, CD_ASSIGN, layer_data, totelem, name);
CustomDataLayer *layer = customData_add_layer__internal(
data, type, std::nullopt, layer_data, sharing_info, totelem, name);
CustomData_update_typemap(data);
if (layer) {
return layer->data;
}
return nullptr;
}
void *CustomData_add_layer_anonymous(CustomData *data,
const eCustomDataType type,
const eCDAllocType alloctype,
void *layerdata,
const int totelem,
const AnonymousAttributeIDHandle *anonymous_id)
{
const char *name = anonymous_id->name().c_str();
CustomDataLayer *layer = customData_add_layer__internal(
data, type, alloctype, layerdata, totelem, name);
data, type, alloctype, nullptr, nullptr, totelem, name);
CustomData_update_typemap(data);
if (layer == nullptr) {
@ -2953,6 +3057,27 @@ void *CustomData_add_layer_anonymous(CustomData *data,
return layer->data;
}
const void *CustomData_add_layer_anonymous_with_data(
CustomData *data,
const eCustomDataType type,
const AnonymousAttributeIDHandle *anonymous_id,
const int totelem,
void *layer_data,
const ImplicitSharingInfo *sharing_info)
{
const char *name = anonymous_id->name().c_str();
CustomDataLayer *layer = customData_add_layer__internal(
data, type, std::nullopt, layer_data, sharing_info, totelem, name);
CustomData_update_typemap(data);
if (layer == nullptr) {
return nullptr;
}
anonymous_id->add_user();
layer->anonymous_id = anonymous_id;
return layer->data;
}
bool CustomData_free_layer(CustomData *data,
const eCustomDataType type,
const int totelem,
@ -3081,47 +3206,6 @@ int CustomData_number_of_layers_typemask(const CustomData *data, const eCustomDa
return number;
}
static void *customData_duplicate_referenced_layer_index(CustomData *data,
const int layer_index,
const int totelem)
{
if (layer_index == -1) {
return nullptr;
}
CustomDataLayer *layer = &data->layers[layer_index];
if (layer->flag & CD_FLAG_NOFREE) {
/* MEM_dupallocN won't work in case of complex layers, like e.g.
* CD_MDEFORMVERT, which has pointers to allocated data...
* So in case a custom copy function is defined, use it!
*/
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(layer->type));
if (typeInfo->copy) {
void *dst_data = MEM_malloc_arrayN(
size_t(totelem), typeInfo->size, "CD duplicate ref layer");
typeInfo->copy(layer->data, dst_data, totelem);
layer->data = dst_data;
}
else {
layer->data = MEM_dupallocN(layer->data);
}
layer->flag &= ~CD_FLAG_NOFREE;
}
return layer->data;
}
void CustomData_duplicate_referenced_layers(CustomData *data, const int totelem)
{
for (int i = 0; i < data->totlayer; i++) {
CustomDataLayer *layer = &data->layers[i];
layer->data = customData_duplicate_referenced_layer_index(data, i, totelem);
}
}
void CustomData_free_temporary(CustomData *data, const int totelem)
{
int i, j;
@ -3299,14 +3383,12 @@ void CustomData_copy_layer_type_data(const CustomData *source,
void CustomData_free_elem(CustomData *data, const int index, const int count)
{
for (int i = 0; i < data->totlayer; i++) {
if (!(data->layers[i].flag & CD_FLAG_NOFREE)) {
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
if (typeInfo->free) {
size_t offset = size_t(index) * typeInfo->size;
if (typeInfo->free) {
size_t offset = size_t(index) * typeInfo->size;
typeInfo->free(POINTER_OFFSET(data->layers[i].data, offset), count, typeInfo->size);
}
typeInfo->free(POINTER_OFFSET(data->layers[i].data, offset), count, typeInfo->size);
}
}
}
@ -3476,7 +3558,12 @@ void *CustomData_get_layer_for_write(CustomData *data,
const int totelem)
{
const int layer_index = CustomData_get_active_layer_index(data, type);
return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
if (layer_index == -1) {
return nullptr;
}
CustomDataLayer &layer = data->layers[layer_index];
ensure_layer_data_is_mutable(layer, totelem);
return layer.data;
}
const void *CustomData_get_layer_n(const CustomData *data, const eCustomDataType type, const int n)
@ -3485,7 +3572,6 @@ const void *CustomData_get_layer_n(const CustomData *data, const eCustomDataType
if (layer_index == -1) {
return nullptr;
}
return data->layers[layer_index].data;
}
@ -3495,7 +3581,12 @@ void *CustomData_get_layer_n_for_write(CustomData *data,
const int totelem)
{
const int layer_index = CustomData_get_layer_index_n(data, type, n);
return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
if (layer_index == -1) {
return nullptr;
}
CustomDataLayer &layer = data->layers[layer_index];
ensure_layer_data_is_mutable(layer, totelem);
return layer.data;
}
const void *CustomData_get_layer_named(const CustomData *data,
@ -3506,7 +3597,6 @@ const void *CustomData_get_layer_named(const CustomData *data,
if (layer_index == -1) {
return nullptr;
}
return data->layers[layer_index].data;
}
@ -3516,7 +3606,12 @@ void *CustomData_get_layer_named_for_write(CustomData *data,
const int totelem)
{
const int layer_index = CustomData_get_named_layer_index(data, type, name);
return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
if (layer_index == -1) {
return nullptr;
}
CustomDataLayer &layer = data->layers[layer_index];
ensure_layer_data_is_mutable(layer, totelem);
return layer.data;
}
int CustomData_get_offset(const CustomData *data, const eCustomDataType type)
@ -3525,7 +3620,6 @@ int CustomData_get_offset(const CustomData *data, const eCustomDataType type)
if (layer_index == -1) {
return -1;
}
return data->layers[layer_index].offset;
}
@ -3610,12 +3704,12 @@ void CustomData_bmesh_init_pool(CustomData *data, const int totelem, const char
}
}
bool CustomData_bmesh_merge(const CustomData *source,
CustomData *dest,
eCustomDataMask mask,
eCDAllocType alloctype,
BMesh *bm,
const char htype)
bool CustomData_bmesh_merge_layout(const CustomData *source,
CustomData *dest,
eCustomDataMask mask,
eCDAllocType alloctype,
BMesh *bm,
const char htype)
{
if (CustomData_number_of_layers_typemask(source, mask) == 0) {
@ -3629,7 +3723,7 @@ bool CustomData_bmesh_merge(const CustomData *source,
destold.layers = static_cast<CustomDataLayer *>(MEM_dupallocN(destold.layers));
}
if (CustomData_merge(source, dest, mask, alloctype, 0) == false) {
if (CustomData_merge_layout(source, dest, mask, alloctype, 0) == false) {
if (destold.layers) {
MEM_freeN(destold.layers);
}
@ -3709,13 +3803,11 @@ void CustomData_bmesh_free_block(CustomData *data, void **block)
}
for (int i = 0; i < data->totlayer; i++) {
if (!(data->layers[i].flag & CD_FLAG_NOFREE)) {
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
if (typeInfo->free) {
int offset = data->layers[i].offset;
typeInfo->free(POINTER_OFFSET(*block, offset), 1, typeInfo->size);
}
if (typeInfo->free) {
int offset = data->layers[i].offset;
typeInfo->free(POINTER_OFFSET(*block, offset), 1, typeInfo->size);
}
}
@ -3732,12 +3824,10 @@ void CustomData_bmesh_free_block_data(CustomData *data, void *block)
return;
}
for (int i = 0; i < data->totlayer; i++) {
if (!(data->layers[i].flag & CD_FLAG_NOFREE)) {
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
if (typeInfo->free) {
const size_t offset = data->layers[i].offset;
typeInfo->free(POINTER_OFFSET(block, offset), 1, typeInfo->size);
}
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
if (typeInfo->free) {
const size_t offset = data->layers[i].offset;
typeInfo->free(POINTER_OFFSET(block, offset), 1, typeInfo->size);
}
}
if (data->totsize) {
@ -3770,10 +3860,8 @@ void CustomData_bmesh_free_block_data_exclude_by_type(CustomData *data,
if ((CD_TYPE_AS_MASK(data->layers[i].type) & mask_exclude) == 0) {
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
const size_t offset = data->layers[i].offset;
if (!(data->layers[i].flag & CD_FLAG_NOFREE)) {
if (typeInfo->free) {
typeInfo->free(POINTER_OFFSET(block, offset), 1, typeInfo->size);
}
if (typeInfo->free) {
typeInfo->free(POINTER_OFFSET(block, offset), 1, typeInfo->size);
}
memset(POINTER_OFFSET(block, offset), 0, typeInfo->size);
}
@ -3951,11 +4039,9 @@ bool CustomData_has_math(const CustomData *data)
bool CustomData_bmesh_has_free(const CustomData *data)
{
for (int i = 0; i < data->totlayer; i++) {
if (!(data->layers[i].flag & CD_FLAG_NOFREE)) {
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
if (typeInfo->free) {
return true;
}
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
if (typeInfo->free) {
return true;
}
}
return false;
@ -3973,16 +4059,6 @@ bool CustomData_has_interp(const CustomData *data)
return false;
}
bool CustomData_has_referenced(const CustomData *data)
{
for (int i = 0; i < data->totlayer; i++) {
if (data->layers[i].flag & CD_FLAG_NOFREE) {
return true;
}
}
return false;
}
void CustomData_data_copy_value(const eCustomDataType type, const void *source, void *dest)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
@ -5188,11 +5264,15 @@ void CustomData_blend_read(BlendDataReader *reader, CustomData *data, const int
if (layer->flag & CD_FLAG_EXTERNAL) {
layer->flag &= ~CD_FLAG_IN_MEMORY;
}
layer->flag &= ~CD_FLAG_NOFREE;
layer->sharing_info = nullptr;
if (CustomData_verify_versions(data, i)) {
BLO_read_data_address(reader, &layer->data);
if (layer->data != nullptr) {
/* Make layer data shareable. */
layer->sharing_info = make_implicit_sharing_info_for_layer(
eCustomDataType(layer->type), layer->data, count);
}
if (CustomData_layer_ensure_data_exists(layer, count)) {
/* Under normal operations, this shouldn't happen, but...
* For a CD_PROP_BOOL example, see #84935.
@ -5280,6 +5360,8 @@ const blender::CPPType *custom_data_type_to_cpp_type(const eCustomDataType type)
return &CPPType::get<float3>();
case CD_PROP_INT32:
return &CPPType::get<int>();
case CD_PROP_INT32_2D:
return &CPPType::get<int2>();
case CD_PROP_COLOR:
return &CPPType::get<ColorGeometry4f>();
case CD_PROP_BOOL:
@ -5309,6 +5391,9 @@ eCustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type)
if (type.is<int>()) {
return CD_PROP_INT32;
}
if (type.is<int2>()) {
return CD_PROP_INT32_2D;
}
if (type.is<ColorGeometry4f>()) {
return CD_PROP_COLOR;
}

View File

@ -649,7 +649,7 @@ bool BKE_gpencil_stroke_stretch(bGPDstroke *gps,
if (!isfinite(used_percent_length)) {
/* #used_percent_length must always be finite, otherwise a segfault occurs.
* Since this function should never segfault, set #used_percent_length to a safe fallback. */
/* NOTE: This fallback is used if gps->totpoints == 2, see MOD_gpencillength.c */
/* NOTE: This fallback is used if gps->totpoints == 2, see MOD_gpencil_legacy_length.c */
used_percent_length = 0.1f;
}

View File

@ -43,8 +43,8 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
#include "MOD_gpencil_lineart.h"
#include "MOD_gpencil_modifiertypes.h"
#include "MOD_gpencil_legacy_lineart.h"
#include "MOD_gpencil_legacy_modifiertypes.h"
#include "BLO_read_write.h"
@ -329,7 +329,7 @@ void BKE_gpencil_frame_active_set(Depsgraph *depsgraph, bGPdata *gpd)
void BKE_gpencil_modifier_init(void)
{
/* Initialize modifier types */
gpencil_modifier_type_init(modifier_gpencil_types); /* MOD_gpencil_util.c */
gpencil_modifier_type_init(modifier_gpencil_types); /* MOD_gpencil_legacy_util.c */
#if 0
/* Note that GPencil actually does not support these at the moment,

View File

@ -404,7 +404,7 @@ static int lib_id_expand_local_cb(LibraryIDLinkCallbackData *cb_data)
return IDWALK_RET_NOP;
}
if (cb_flag & IDWALK_CB_EMBEDDED) {
if (cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_EMBEDDED_NOT_OWNING)) {
/* Embedded data-blocks need to be made fully local as well.
* Note however that in some cases (when owner ID had to be duplicated instead of being made
* local directly), its embedded IDs should also have already been duplicated, and hence be
@ -1494,12 +1494,11 @@ bool BKE_id_new_name_validate(
return result;
}
/* if no name given, use name of current ID
* else make a copy (tname args can be const) */
/* If no name given, use name of current ID. */
if (tname == NULL) {
tname = id->name + 2;
}
/* Make a copy of given name (tname args can be const). */
BLI_strncpy(name, tname, sizeof(name));
if (name[0] == '\0') {

View File

@ -696,7 +696,8 @@ static void lib_query_unused_ids_tag_recurse(Main *bmain,
/* An ID user is 'valid' (i.e. may affect the 'used'/'not used' status of the ID it uses) if it
* does not match `ignored_usages`, and does match `required_usages`. */
const int ignored_usages = (IDWALK_CB_LOOPBACK | IDWALK_CB_EMBEDDED);
const int ignored_usages = (IDWALK_CB_LOOPBACK | IDWALK_CB_EMBEDDED |
IDWALK_CB_EMBEDDED_NOT_OWNING);
const int required_usages = (IDWALK_CB_USER | IDWALK_CB_USER_ONE);
/* This ID may be tagged as unused if none of its users are 'valid', as defined above.

View File

@ -157,7 +157,7 @@ static int foreach_libblock_remap_callback(LibraryIDLinkCallbackData *cb_data)
{
const int cb_flag = cb_data->cb_flag;
if (cb_flag & IDWALK_CB_EMBEDDED) {
if (cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_EMBEDDED_NOT_OWNING)) {
return IDWALK_RET_NOP;
}
@ -857,7 +857,8 @@ static void libblock_relink_to_newid_prepare_data(Main *bmain,
static int id_relink_to_newid_looper(LibraryIDLinkCallbackData *cb_data)
{
const int cb_flag = cb_data->cb_flag;
if (cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE)) {
if (cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_EMBEDDED_NOT_OWNING |
IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE)) {
return IDWALK_RET_NOP;
}

View File

@ -150,14 +150,13 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
mesh_dst->default_color_attribute = static_cast<char *>(
MEM_dupallocN(mesh_src->default_color_attribute));
const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
CustomData_copy(&mesh_src->vdata, &mesh_dst->vdata, mask.vmask, alloc_type, mesh_dst->totvert);
CustomData_copy(&mesh_src->edata, &mesh_dst->edata, mask.emask, alloc_type, mesh_dst->totedge);
CustomData_copy(&mesh_src->ldata, &mesh_dst->ldata, mask.lmask, alloc_type, mesh_dst->totloop);
CustomData_copy(&mesh_src->pdata, &mesh_dst->pdata, mask.pmask, alloc_type, mesh_dst->totpoly);
CustomData_copy(&mesh_src->vdata, &mesh_dst->vdata, mask.vmask, mesh_dst->totvert);
CustomData_copy(&mesh_src->edata, &mesh_dst->edata, mask.emask, mesh_dst->totedge);
CustomData_copy(&mesh_src->ldata, &mesh_dst->ldata, mask.lmask, mesh_dst->totloop);
CustomData_copy(&mesh_src->pdata, &mesh_dst->pdata, mask.pmask, mesh_dst->totpoly);
mesh_dst->poly_offset_indices = static_cast<int *>(MEM_dupallocN(mesh_src->poly_offset_indices));
if (do_tessface) {
CustomData_copy(&mesh_src->fdata, &mesh_dst->fdata, mask.fmask, alloc_type, mesh_dst->totface);
CustomData_copy(&mesh_src->fdata, &mesh_dst->fdata, mask.fmask, mesh_dst->totface);
}
else {
mesh_tessface_clear_intern(mesh_dst, false);
@ -617,6 +616,16 @@ static int customdata_compare(
BLI_edgehash_free(eh, nullptr);
break;
}
case CD_PROP_INT32_2D: {
const blender::int2 *l1_data = static_cast<const blender::int2 *>(l1->data);
const blender::int2 *l2_data = static_cast<const blender::int2 *>(l2->data);
for (int i = 0; i < total_length; i++) {
if (l1_data[i] != l2_data[i]) {
return MESHCMP_ATTRIBUTE_VALUE_MISMATCH;
}
}
break;
}
case CD_PROP_BYTE_COLOR: {
MLoopCol *lp1 = (MLoopCol *)l1->data;
MLoopCol *lp2 = (MLoopCol *)l2->data;
@ -1102,12 +1111,13 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
BKE_mesh_copy_parameters_for_eval(me_dst, me_src);
CustomData_copy(&me_src->vdata, &me_dst->vdata, mask.vmask, CD_SET_DEFAULT, verts_len);
CustomData_copy(&me_src->edata, &me_dst->edata, mask.emask, CD_SET_DEFAULT, edges_len);
CustomData_copy(&me_src->ldata, &me_dst->ldata, mask.lmask, CD_SET_DEFAULT, loops_len);
CustomData_copy(&me_src->pdata, &me_dst->pdata, mask.pmask, CD_SET_DEFAULT, polys_len);
CustomData_copy_layout(&me_src->vdata, &me_dst->vdata, mask.vmask, CD_SET_DEFAULT, verts_len);
CustomData_copy_layout(&me_src->edata, &me_dst->edata, mask.emask, CD_SET_DEFAULT, edges_len);
CustomData_copy_layout(&me_src->ldata, &me_dst->ldata, mask.lmask, CD_SET_DEFAULT, loops_len);
CustomData_copy_layout(&me_src->pdata, &me_dst->pdata, mask.pmask, CD_SET_DEFAULT, polys_len);
if (do_tessface) {
CustomData_copy(&me_src->fdata, &me_dst->fdata, mask.fmask, CD_SET_DEFAULT, tessface_len);
CustomData_copy_layout(
&me_src->fdata, &me_dst->fdata, mask.fmask, CD_SET_DEFAULT, tessface_len);
}
else {
mesh_tessface_clear_intern(me_dst, false);
@ -1384,7 +1394,7 @@ void BKE_mesh_orco_ensure(Object *ob, Mesh *mesh)
/* Orcos are stored in normalized 0..1 range by convention. */
float(*orcodata)[3] = BKE_mesh_orco_verts_get(ob);
BKE_mesh_orco_verts_transform(mesh, orcodata, mesh->totvert, false);
CustomData_add_layer_with_data(&mesh->vdata, CD_ORCO, orcodata, mesh->totvert);
CustomData_add_layer_with_data(&mesh->vdata, CD_ORCO, orcodata, mesh->totvert, nullptr);
}
Mesh *BKE_mesh_from_object(Object *ob)

View File

@ -656,15 +656,15 @@ static void merge_vertex_loop_poly_customdata_layers(Mesh *target, MeshesToIMesh
for (int mesh_index = 1; mesh_index < mim.meshes.size(); ++mesh_index) {
const Mesh *me = mim.meshes[mesh_index];
if (me->totvert) {
CustomData_merge(
CustomData_merge_layout(
&me->vdata, &target->vdata, CD_MASK_MESH.vmask, CD_SET_DEFAULT, target->totvert);
}
if (me->totloop) {
CustomData_merge(
CustomData_merge_layout(
&me->ldata, &target->ldata, CD_MASK_MESH.lmask, CD_SET_DEFAULT, target->totloop);
}
if (me->totpoly) {
CustomData_merge(
CustomData_merge_layout(
&me->pdata, &target->pdata, CD_MASK_MESH.pmask, CD_SET_DEFAULT, target->totpoly);
}
}
@ -675,7 +675,7 @@ static void merge_edge_customdata_layers(Mesh *target, MeshesToIMeshInfo &mim)
for (int mesh_index = 0; mesh_index < mim.meshes.size(); ++mesh_index) {
const Mesh *me = mim.meshes[mesh_index];
if (me->totedge) {
CustomData_merge(
CustomData_merge_layout(
&me->edata, &target->edata, CD_MASK_MESH.emask, CD_SET_DEFAULT, target->totedge);
}
}

View File

@ -244,7 +244,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select
/* Free old CustomData and assign new one. */
CustomData_free(&mesh->edata, mesh->totedge);
CustomData_reset(&mesh->edata);
CustomData_add_layer_with_data(&mesh->edata, CD_MEDGE, new_edges.data(), new_totedge);
CustomData_add_layer_with_data(&mesh->edata, CD_MEDGE, new_edges.data(), new_totedge, nullptr);
mesh->totedge = new_totedge;
if (select_new_edges) {

View File

@ -625,7 +625,7 @@ void BKE_pointcloud_from_mesh(const Mesh *me, PointCloud *pointcloud)
{
CustomData_free(&pointcloud->pdata, pointcloud->totpoint);
pointcloud->totpoint = me->totvert;
CustomData_merge(&me->vdata, &pointcloud->pdata, CD_MASK_PROP_ALL, CD_DUPLICATE, me->totvert);
CustomData_merge(&me->vdata, &pointcloud->pdata, CD_MASK_PROP_ALL, me->totvert);
}
void BKE_mesh_to_pointcloud(Main *bmain, Depsgraph *depsgraph, Scene * /*scene*/, Object *ob)
@ -652,8 +652,7 @@ void BKE_mesh_to_pointcloud(Main *bmain, Depsgraph *depsgraph, Scene * /*scene*/
void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me)
{
me->totvert = pointcloud->totpoint;
CustomData_merge(
&pointcloud->pdata, &me->vdata, CD_MASK_PROP_ALL, CD_DUPLICATE, pointcloud->totpoint);
CustomData_merge(&pointcloud->pdata, &me->vdata, CD_MASK_PROP_ALL, pointcloud->totpoint);
}
void BKE_pointcloud_to_mesh(Main *bmain, Depsgraph *depsgraph, Scene * /*scene*/, Object *ob)
@ -1116,13 +1115,6 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
BKE_mesh_clear_geometry_and_metadata(mesh_dst);
/* Make sure referenced layers have a single user so assigning them to the mesh in main doesn't
* share them. "Referenced" layers are not expected to be shared between original meshes. */
CustomData_duplicate_referenced_layers(&mesh_src->vdata, mesh_src->totvert);
CustomData_duplicate_referenced_layers(&mesh_src->edata, mesh_src->totedge);
CustomData_duplicate_referenced_layers(&mesh_src->pdata, mesh_src->totpoly);
CustomData_duplicate_referenced_layers(&mesh_src->ldata, mesh_src->totloop);
const bool verts_num_changed = mesh_dst->totvert != mesh_src->totvert;
mesh_dst->totvert = mesh_src->totvert;
mesh_dst->totedge = mesh_src->totedge;
@ -1131,10 +1123,10 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
/* Using #CD_MASK_MESH ensures that only data that should exist in Main meshes is moved. */
const CustomData_MeshMasks mask = CD_MASK_MESH;
CustomData_copy(&mesh_src->vdata, &mesh_dst->vdata, mask.vmask, CD_ASSIGN, mesh_src->totvert);
CustomData_copy(&mesh_src->edata, &mesh_dst->edata, mask.emask, CD_ASSIGN, mesh_src->totedge);
CustomData_copy(&mesh_src->pdata, &mesh_dst->pdata, mask.pmask, CD_ASSIGN, mesh_src->totpoly);
CustomData_copy(&mesh_src->ldata, &mesh_dst->ldata, mask.lmask, CD_ASSIGN, mesh_src->totloop);
CustomData_copy(&mesh_src->vdata, &mesh_dst->vdata, mask.vmask, mesh_src->totvert);
CustomData_copy(&mesh_src->edata, &mesh_dst->edata, mask.emask, mesh_src->totedge);
CustomData_copy(&mesh_src->pdata, &mesh_dst->pdata, mask.pmask, mesh_src->totpoly);
CustomData_copy(&mesh_src->ldata, &mesh_dst->ldata, mask.lmask, mesh_src->totloop);
std::swap(mesh_dst->poly_offset_indices, mesh_src->poly_offset_indices);
/* Make sure attribute names are moved. */

View File

@ -227,7 +227,7 @@ void BKE_mesh_calc_edges_legacy(Mesh *me)
return;
}
edges = (MEdge *)CustomData_add_layer_with_data(&me->edata, CD_MEDGE, edges, totedge);
edges = (MEdge *)CustomData_add_layer_with_data(&me->edata, CD_MEDGE, edges, totedge, nullptr);
me->totedge = totedge;
BKE_mesh_tag_topology_changed(me);
@ -1149,11 +1149,11 @@ static int mesh_tessface_calc(Mesh &mesh,
sizeof(*mface_to_poly_map) * size_t(totface));
}
CustomData_add_layer_with_data(fdata, CD_MFACE, mface, totface);
CustomData_add_layer_with_data(fdata, CD_MFACE, mface, totface, nullptr);
/* #CD_ORIGINDEX will contain an array of indices from tessellation-faces to the polygons
* they are directly tessellated from. */
CustomData_add_layer_with_data(fdata, CD_ORIGINDEX, mface_to_poly_map, totface);
CustomData_add_layer_with_data(fdata, CD_ORIGINDEX, mface_to_poly_map, totface, nullptr);
add_mface_layers(mesh, fdata, ldata, totface);
/* NOTE: quad detection issue - fourth vertex-index vs fourth loop-index:
@ -1297,17 +1297,28 @@ void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh)
return;
}
void *faceset_data = nullptr;
const ImplicitSharingInfo *faceset_sharing_info = nullptr;
for (const int i : IndexRange(mesh->pdata.totlayer)) {
if (mesh->pdata.layers[i].type == CD_SCULPT_FACE_SETS) {
faceset_data = mesh->pdata.layers[i].data;
mesh->pdata.layers[i].data = nullptr;
CustomDataLayer &layer = mesh->pdata.layers[i];
if (layer.type == CD_SCULPT_FACE_SETS) {
faceset_data = layer.data;
faceset_sharing_info = layer.sharing_info;
layer.data = nullptr;
layer.sharing_info = nullptr;
CustomData_free_layer(&mesh->pdata, CD_SCULPT_FACE_SETS, mesh->totpoly, i);
break;
}
}
if (faceset_data != nullptr) {
CustomData_add_layer_named_with_data(
&mesh->pdata, CD_PROP_INT32, faceset_data, mesh->totpoly, ".sculpt_face_set");
CustomData_add_layer_named_with_data(&mesh->pdata,
CD_PROP_INT32,
faceset_data,
mesh->totpoly,
".sculpt_face_set",
faceset_sharing_info);
}
if (faceset_sharing_info != nullptr) {
faceset_sharing_info->remove_user_and_delete_if_last();
}
}
@ -1815,28 +1826,31 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh)
uv_names[i] = new_name;
CustomData_add_layer_named_with_data(
&mesh->ldata, CD_PROP_FLOAT2, coords, mesh->totloop, new_name);
&mesh->ldata, CD_PROP_FLOAT2, coords, mesh->totloop, new_name, nullptr);
char buffer[MAX_CUSTOMDATA_LAYER_NAME];
if (vert_selection) {
CustomData_add_layer_named_with_data(&mesh->ldata,
CD_PROP_BOOL,
vert_selection,
mesh->totloop,
BKE_uv_map_vert_select_name_get(new_name, buffer));
BKE_uv_map_vert_select_name_get(new_name, buffer),
nullptr);
}
if (edge_selection) {
CustomData_add_layer_named_with_data(&mesh->ldata,
CD_PROP_BOOL,
edge_selection,
mesh->totloop,
BKE_uv_map_edge_select_name_get(new_name, buffer));
BKE_uv_map_edge_select_name_get(new_name, buffer),
nullptr);
}
if (pin) {
CustomData_add_layer_named_with_data(&mesh->ldata,
CD_PROP_BOOL,
pin,
mesh->totloop,
BKE_uv_map_pin_name_get(new_name, buffer));
BKE_uv_map_pin_name_get(new_name, buffer),
nullptr);
}
}
@ -2272,7 +2286,8 @@ void BKE_mesh_legacy_convert_polys_to_offsets(Mesh *mesh)
});
CustomData old_poly_data = mesh->pdata;
CustomData_reset(&mesh->pdata);
CustomData_copy(&old_poly_data, &mesh->pdata, CD_MASK_MESH.pmask, CD_CONSTRUCT, mesh->totpoly);
CustomData_copy_layout(
&old_poly_data, &mesh->pdata, CD_MASK_MESH.pmask, CD_CONSTRUCT, mesh->totpoly);
int offset = 0;
for (const int i : orig_indices.index_range()) {

View File

@ -224,6 +224,7 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink();
if (mesh->runtime->shrinkwrap_data) {
BKE_shrinkwrap_boundary_data_free(mesh->runtime->shrinkwrap_data);
mesh->runtime->shrinkwrap_data = nullptr;
}
}
@ -240,6 +241,7 @@ void BKE_mesh_tag_edges_split(struct Mesh *mesh)
mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink();
if (mesh->runtime->shrinkwrap_data) {
BKE_shrinkwrap_boundary_data_free(mesh->runtime->shrinkwrap_data);
mesh->runtime->shrinkwrap_data = nullptr;
}
}

View File

@ -1952,9 +1952,11 @@ static void BKE_nlastrip_validate_autoblends(NlaTrack *nlt, NlaStrip *nls)
}
}
/* Ensure every transition's start/end properly set.
/**
* Ensure every transition's start/end properly set.
* Strip will be removed / freed if it doesn't fit (invalid).
* Return value indicates if passed strip is valid/fixed or invalid/removed. */
* Return value indicates if passed strip is valid/fixed or invalid/removed.
*/
static bool nlastrip_validate_transition_start_end(NlaStrip *strip)
{

View File

@ -132,7 +132,8 @@ struct DupliContext {
};
struct DupliGenerator {
short type; /* Dupli Type, see members of #OB_DUPLI. */
/** Duplicator Type, see members of #OB_DUPLI. */
short type;
void (*make_duplis)(const DupliContext *ctx);
};
@ -1325,8 +1326,10 @@ static void make_duplis_faces(const DupliContext *ctx)
}
}
static const DupliGenerator gen_dupli_faces = {/*type*/ OB_DUPLIFACES,
/*make_duplis*/ make_duplis_faces};
static const DupliGenerator gen_dupli_faces = {
/*type*/ OB_DUPLIFACES,
/*make_duplis*/ make_duplis_faces,
};
/** \} */
@ -1673,8 +1676,10 @@ static void make_duplis_particles(const DupliContext *ctx)
}
}
static const DupliGenerator gen_dupli_particles = {/*type*/ OB_DUPLIPARTS,
/*make_duplis*/ make_duplis_particles};
static const DupliGenerator gen_dupli_particles = {
/*type*/ OB_DUPLIPARTS,
/*make_duplis*/ make_duplis_particles,
};
/** \} */

View File

@ -2171,11 +2171,10 @@ static PBVH *build_pbvh_for_dynamic_topology(Object *ob)
return pbvh;
}
static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool respect_hide)
static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform)
{
Mesh *me = BKE_object_get_original_mesh(ob);
PBVH *pbvh = BKE_pbvh_new(PBVH_FACES);
BKE_pbvh_respect_hide_set(pbvh, respect_hide);
BKE_pbvh_build_mesh(pbvh, me);
@ -2188,12 +2187,11 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
return pbvh;
}
static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect_hide)
static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg)
{
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
PBVH *pbvh = BKE_pbvh_new(PBVH_GRIDS);
BKE_pbvh_respect_hide_set(pbvh, respect_hide);
Mesh *base_mesh = BKE_mesh_from_object(ob);
BKE_sculpt_sync_face_visibility_to_grids(base_mesh, subdiv_ccg);
@ -2216,8 +2214,6 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
return nullptr;
}
const bool respect_hide = true;
PBVH *pbvh = ob->sculpt->pbvh;
if (pbvh != nullptr) {
/* NOTE: It is possible that pointers to grids or other geometry data changed. Need to update
@ -2258,11 +2254,11 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
Mesh *mesh_eval = static_cast<Mesh *>(object_eval->data);
if (mesh_eval->runtime->subdiv_ccg != nullptr) {
pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime->subdiv_ccg, respect_hide);
pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime->subdiv_ccg);
}
else if (ob->type == OB_MESH) {
Mesh *me_eval_deform = object_eval->runtime.mesh_deform_eval;
pbvh = build_pbvh_from_regular_mesh(ob, me_eval_deform, respect_hide);
pbvh = build_pbvh_from_regular_mesh(ob, me_eval_deform);
}
}

View File

@ -335,10 +335,6 @@ static void build_mesh_leaf_node(PBVH *pbvh, PBVHNode *node)
node->face_vert_indices = (const int(*)[3])face_vert_indices;
if (pbvh->respect_hide == false) {
has_visible = true;
}
for (int i = 0; i < totface; i++) {
const MLoopTri *lt = &pbvh->looptri[node->prim_indices[i]];
for (int j = 0; j < 3; j++) {
@ -1042,7 +1038,6 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
PBVH *BKE_pbvh_new(PBVHType type)
{
PBVH *pbvh = MEM_new<PBVH>(__func__);
pbvh->respect_hide = true;
pbvh->draw_cache_invalid = true;
pbvh->header.type = type;
@ -2600,7 +2595,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh,
const MLoopTri *lt = &pbvh->looptri[faces[i]];
const int *face_verts = node->face_vert_indices[i];
if (pbvh->respect_hide && paint_is_face_hidden(lt, pbvh->hide_poly)) {
if (paint_is_face_hidden(lt, pbvh->hide_poly)) {
continue;
}
@ -2909,7 +2904,7 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh,
const MLoopTri *lt = &pbvh->looptri[faces[i]];
const int *face_verts = node->face_vert_indices[i];
if (pbvh->respect_hide && paint_is_face_hidden(lt, pbvh->hide_poly)) {
if (paint_is_face_hidden(lt, pbvh->hide_poly)) {
continue;
}
@ -3425,12 +3420,6 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
vi->vert_positions = nullptr;
vi->vertex.i = 0LL;
vi->respect_hide = pbvh->respect_hide;
if (pbvh->respect_hide == false) {
/* The same value for all vertices. */
vi->visible = true;
}
BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, nullptr, &gridsize, &grids);
BKE_pbvh_node_num_verts(pbvh, node, &uniq_verts, &totvert);
const int *vert_indices = BKE_pbvh_node_get_vert_indices(node);
@ -3586,11 +3575,6 @@ void BKE_pbvh_update_hide_attributes_from_mesh(PBVH *pbvh)
}
}
void BKE_pbvh_respect_hide_set(PBVH *pbvh, bool respect_hide)
{
pbvh->respect_hide = respect_hide;
}
bool BKE_pbvh_is_drawing(const PBVH *pbvh)
{
return pbvh->is_drawing;

View File

@ -187,7 +187,6 @@ struct PBVH {
/* flag are verts/faces deformed */
bool deformed;
bool respect_hide;
/* Dynamic topology */
float bm_max_edge_len;

View File

@ -64,25 +64,24 @@ static void pointcloud_init_data(ID *id)
CustomData_reset(&pointcloud->pdata);
CustomData_add_layer_named(&pointcloud->pdata,
CD_PROP_FLOAT3,
CD_SET_DEFAULT,
CD_CONSTRUCT,
pointcloud->totpoint,
POINTCLOUD_ATTR_POSITION);
pointcloud->runtime = new blender::bke::PointCloudRuntime();
}
static void pointcloud_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int flag)
static void pointcloud_copy_data(Main * /*bmain*/,
ID *id_dst,
const ID *id_src,
const int /*flag*/)
{
PointCloud *pointcloud_dst = (PointCloud *)id_dst;
const PointCloud *pointcloud_src = (const PointCloud *)id_src;
pointcloud_dst->mat = static_cast<Material **>(MEM_dupallocN(pointcloud_src->mat));
const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
CustomData_copy(&pointcloud_src->pdata,
&pointcloud_dst->pdata,
CD_MASK_ALL,
alloc_type,
pointcloud_dst->totpoint);
CustomData_copy(
&pointcloud_src->pdata, &pointcloud_dst->pdata, CD_MASK_ALL, pointcloud_dst->totpoint);
pointcloud_dst->runtime = new blender::bke::PointCloudRuntime();
pointcloud_dst->runtime->bounds_cache = pointcloud_src->runtime->bounds_cache;
@ -203,21 +202,18 @@ static void pointcloud_random(PointCloud *pointcloud)
RNG *rng = BLI_rng_new(0);
blender::bke::MutableAttributeAccessor attributes = pointcloud->attributes_for_write();
blender::bke::SpanAttributeWriter positions =
attributes.lookup_or_add_for_write_only_span<float3>(POINTCLOUD_ATTR_POSITION,
ATTR_DOMAIN_POINT);
blender::MutableSpan<float3> positions = pointcloud->positions_for_write();
blender::bke::SpanAttributeWriter<float> radii =
attributes.lookup_or_add_for_write_only_span<float>(POINTCLOUD_ATTR_RADIUS,
ATTR_DOMAIN_POINT);
for (const int i : positions.span.index_range()) {
positions.span[i] =
float3(BLI_rng_get_float(rng), BLI_rng_get_float(rng), BLI_rng_get_float(rng)) * 2.0f -
1.0f;
for (const int i : positions.index_range()) {
positions[i] = float3(BLI_rng_get_float(rng), BLI_rng_get_float(rng), BLI_rng_get_float(rng)) *
2.0f -
1.0f;
radii.span[i] = 0.05f * BLI_rng_get_float(rng);
}
positions.finish();
radii.finish();
BLI_rng_free(rng);
@ -259,27 +255,12 @@ void BKE_pointcloud_nomain_to_pointcloud(PointCloud *pointcloud_src,
{
BLI_assert(pointcloud_src->id.tag & LIB_TAG_NO_MAIN);
eCDAllocType alloctype = CD_DUPLICATE;
if (take_ownership) {
bool has_any_referenced_layers = CustomData_has_referenced(&pointcloud_src->pdata);
if (!has_any_referenced_layers) {
alloctype = CD_ASSIGN;
}
}
CustomData_free(&pointcloud_dst->pdata, pointcloud_dst->totpoint);
const int totpoint = pointcloud_dst->totpoint = pointcloud_src->totpoint;
CustomData_copy(
&pointcloud_src->pdata, &pointcloud_dst->pdata, CD_MASK_ALL, alloctype, totpoint);
CustomData_copy(&pointcloud_src->pdata, &pointcloud_dst->pdata, CD_MASK_ALL, totpoint);
if (take_ownership) {
if (alloctype == CD_ASSIGN) {
/* Free the CustomData but keep the layers. */
CustomData_free_typemask(&pointcloud_src->pdata, pointcloud_src->totpoint, 0);
}
BKE_id_free(nullptr, pointcloud_src);
}
}

View File

@ -763,7 +763,7 @@ static void scene_foreach_layer_collection(LibraryForeachIDData *data, ListBase
* anyway... */
const int cb_flag = (lc->collection != nullptr &&
(lc->collection->id.flag & LIB_EMBEDDED_DATA) != 0) ?
IDWALK_CB_EMBEDDED :
IDWALK_CB_EMBEDDED_NOT_OWNING :
IDWALK_CB_NOP;
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, lc->collection, cb_flag | IDWALK_CB_DIRECT_WEAK_LINK);
scene_foreach_layer_collection(data, &lc->layer_collections);

View File

@ -168,15 +168,17 @@ void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area
BKE_LIB_FOREACHID_PROCESS_ID(data, snode->id, IDWALK_CB_NOP);
BKE_LIB_FOREACHID_PROCESS_ID(data, snode->from, IDWALK_CB_NOP);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(
data, snode->nodetree, is_private_nodetree ? IDWALK_CB_EMBEDDED : IDWALK_CB_USER_ONE);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data,
snode->nodetree,
is_private_nodetree ? IDWALK_CB_EMBEDDED_NOT_OWNING :
IDWALK_CB_USER_ONE);
LISTBASE_FOREACH (bNodeTreePath *, path, &snode->treepath) {
if (path == snode->treepath.first) {
/* first nodetree in path is same as snode->nodetree */
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data,
path->nodetree,
is_private_nodetree ? IDWALK_CB_EMBEDDED :
is_private_nodetree ? IDWALK_CB_EMBEDDED_NOT_OWNING :
IDWALK_CB_USER_ONE);
}
else {

View File

@ -221,11 +221,11 @@ static void vertex_interpolation_init(const SubdivMeshContext *ctx,
else {
vertex_interpolation->vertex_data = &vertex_interpolation->vertex_data_storage;
/* Allocate storage for loops corresponding to ptex corners. */
CustomData_copy(&ctx->coarse_mesh->vdata,
&vertex_interpolation->vertex_data_storage,
CD_MASK_EVERYTHING.vmask,
CD_SET_DEFAULT,
4);
CustomData_copy_layout(&ctx->coarse_mesh->vdata,
&vertex_interpolation->vertex_data_storage,
CD_MASK_EVERYTHING.vmask,
CD_SET_DEFAULT,
4);
/* Initialize indices. */
vertex_interpolation->vertex_indices[0] = 0;
vertex_interpolation->vertex_indices[1] = 1;
@ -351,11 +351,11 @@ static void loop_interpolation_init(const SubdivMeshContext *ctx,
else {
loop_interpolation->loop_data = &loop_interpolation->loop_data_storage;
/* Allocate storage for loops corresponding to ptex corners. */
CustomData_copy(&ctx->coarse_mesh->ldata,
&loop_interpolation->loop_data_storage,
CD_MASK_EVERYTHING.lmask,
CD_SET_DEFAULT,
4);
CustomData_copy_layout(&ctx->coarse_mesh->ldata,
&loop_interpolation->loop_data_storage,
CD_MASK_EVERYTHING.lmask,
CD_SET_DEFAULT,
4);
/* Initialize indices. */
loop_interpolation->loop_indices[0] = 0;
loop_interpolation->loop_indices[1] = 1;

View File

@ -51,6 +51,10 @@ static int32_t float_to_int(const float &a)
{
return int32_t(a);
}
static int2 float_to_int2(const float &a)
{
return int2(a);
}
static bool float_to_bool(const float &a)
{
return a > 0.0f;
@ -81,6 +85,10 @@ static int float2_to_int(const float2 &a)
{
return int32_t((a.x + a.y) / 2.0f);
}
static int2 float2_to_int2(const float2 &a)
{
return int2(a.x, a.y);
}
static bool float2_to_bool(const float2 &a)
{
return !math::is_zero(a);
@ -114,6 +122,10 @@ static int float3_to_int(const float3 &a)
{
return int((a.x + a.y + a.z) / 3.0f);
}
static int2 float3_to_int2(const float3 &a)
{
return int2(a.x, a.y);
}
static float2 float3_to_float2(const float3 &a)
{
return float2(a);
@ -136,6 +148,10 @@ static int8_t int_to_int8(const int32_t &a)
return std::clamp(
a, int(std::numeric_limits<int8_t>::min()), int(std::numeric_limits<int8_t>::max()));
}
static int2 int_to_int2(const int32_t &a)
{
return int2(a);
}
static float int_to_float(const int32_t &a)
{
return float(a);
@ -157,6 +173,39 @@ static ColorGeometry4b int_to_byte_color(const int32_t &a)
return int_to_color(a).encode();
}
static bool int2_to_bool(const int2 &a)
{
return !math::is_zero(a);
}
static float2 int2_to_float2(const int2 &a)
{
return float2(a);
}
static int int2_to_int(const int2 &a)
{
return math::midpoint(a.x, a.y);
}
static int8_t int2_to_int8(const int2 &a)
{
return int_to_int8(int2_to_int(a));
}
static float int2_to_float(const int2 &a)
{
return float2_to_float(float2(a));
}
static float3 int2_to_float3(const int2 &a)
{
return float3(float(a.x), float(a.y), 0.0f);
}
static ColorGeometry4f int2_to_color(const int2 &a)
{
return ColorGeometry4f(float(a.x), float(a.y), 0.0f, 1.0f);
}
static ColorGeometry4b int2_to_byte_color(const int2 &a)
{
return int2_to_color(a).encode();
}
static bool int8_to_bool(const int8_t &a)
{
return a > 0;
@ -165,6 +214,10 @@ static int int8_to_int(const int8_t &a)
{
return int(a);
}
static int2 int8_to_int2(const int8_t &a)
{
return int2(a);
}
static float int8_to_float(const int8_t &a)
{
return float(a);
@ -198,6 +251,10 @@ static int32_t bool_to_int(const bool &a)
{
return int32_t(a);
}
static int2 bool_to_int2(const bool &a)
{
return int2(a);
}
static float2 bool_to_float2(const bool &a)
{
return (a) ? float2(1.0f) : float2(0.0f);
@ -227,6 +284,10 @@ static int32_t color_to_int(const ColorGeometry4f &a)
{
return int(rgb_to_grayscale(a));
}
static int2 color_to_int2(const ColorGeometry4f &a)
{
return int2(a.r, a.g);
}
static int8_t color_to_int8(const ColorGeometry4f &a)
{
return int_to_int8(color_to_int(a));
@ -256,6 +317,10 @@ static int32_t byte_color_to_int(const ColorGeometry4b &a)
{
return color_to_int(a.decode());
}
static int2 byte_color_to_int2(const ColorGeometry4b &a)
{
return int2(a.r, a.g);
}
static int8_t byte_color_to_int8(const ColorGeometry4b &a)
{
return color_to_int8(a.decode());
@ -280,6 +345,7 @@ static DataTypeConversions create_implicit_conversions()
add_implicit_conversion<float, float2, float_to_float2>(conversions);
add_implicit_conversion<float, float3, float_to_float3>(conversions);
add_implicit_conversion<float, int32_t, float_to_int>(conversions);
add_implicit_conversion<float, int2, float_to_int2>(conversions);
add_implicit_conversion<float, bool, float_to_bool>(conversions);
add_implicit_conversion<float, int8_t, float_to_int8>(conversions);
add_implicit_conversion<float, ColorGeometry4f, float_to_color>(conversions);
@ -288,6 +354,7 @@ static DataTypeConversions create_implicit_conversions()
add_implicit_conversion<float2, float3, float2_to_float3>(conversions);
add_implicit_conversion<float2, float, float2_to_float>(conversions);
add_implicit_conversion<float2, int32_t, float2_to_int>(conversions);
add_implicit_conversion<float2, int2, float2_to_int2>(conversions);
add_implicit_conversion<float2, bool, float2_to_bool>(conversions);
add_implicit_conversion<float2, int8_t, float2_to_int8>(conversions);
add_implicit_conversion<float2, ColorGeometry4f, float2_to_color>(conversions);
@ -297,20 +364,32 @@ static DataTypeConversions create_implicit_conversions()
add_implicit_conversion<float3, int8_t, float3_to_int8>(conversions);
add_implicit_conversion<float3, float, float3_to_float>(conversions);
add_implicit_conversion<float3, int32_t, float3_to_int>(conversions);
add_implicit_conversion<float3, int2, float3_to_int2>(conversions);
add_implicit_conversion<float3, float2, float3_to_float2>(conversions);
add_implicit_conversion<float3, ColorGeometry4f, float3_to_color>(conversions);
add_implicit_conversion<float3, ColorGeometry4b, float3_to_byte_color>(conversions);
add_implicit_conversion<int32_t, bool, int_to_bool>(conversions);
add_implicit_conversion<int32_t, int8_t, int_to_int8>(conversions);
add_implicit_conversion<int32_t, int2, int_to_int2>(conversions);
add_implicit_conversion<int32_t, float, int_to_float>(conversions);
add_implicit_conversion<int32_t, float2, int_to_float2>(conversions);
add_implicit_conversion<int32_t, float3, int_to_float3>(conversions);
add_implicit_conversion<int32_t, ColorGeometry4f, int_to_color>(conversions);
add_implicit_conversion<int32_t, ColorGeometry4b, int_to_byte_color>(conversions);
add_implicit_conversion<int2, bool, int2_to_bool>(conversions);
add_implicit_conversion<int2, int8_t, int2_to_int8>(conversions);
add_implicit_conversion<int2, int, int2_to_int>(conversions);
add_implicit_conversion<int2, float, int2_to_float>(conversions);
add_implicit_conversion<int2, float2, int2_to_float2>(conversions);
add_implicit_conversion<int2, float3, int2_to_float3>(conversions);
add_implicit_conversion<int2, ColorGeometry4f, int2_to_color>(conversions);
add_implicit_conversion<int2, ColorGeometry4b, int2_to_byte_color>(conversions);
add_implicit_conversion<int8_t, bool, int8_to_bool>(conversions);
add_implicit_conversion<int8_t, int32_t, int8_to_int>(conversions);
add_implicit_conversion<int8_t, int2, int8_to_int2>(conversions);
add_implicit_conversion<int8_t, float, int8_to_float>(conversions);
add_implicit_conversion<int8_t, float2, int8_to_float2>(conversions);
add_implicit_conversion<int8_t, float3, int8_to_float3>(conversions);
@ -320,6 +399,7 @@ static DataTypeConversions create_implicit_conversions()
add_implicit_conversion<bool, float, bool_to_float>(conversions);
add_implicit_conversion<bool, int8_t, bool_to_int8>(conversions);
add_implicit_conversion<bool, int32_t, bool_to_int>(conversions);
add_implicit_conversion<bool, int2, bool_to_int2>(conversions);
add_implicit_conversion<bool, float2, bool_to_float2>(conversions);
add_implicit_conversion<bool, float3, bool_to_float3>(conversions);
add_implicit_conversion<bool, ColorGeometry4f, bool_to_color>(conversions);
@ -329,6 +409,7 @@ static DataTypeConversions create_implicit_conversions()
add_implicit_conversion<ColorGeometry4f, int8_t, color_to_int8>(conversions);
add_implicit_conversion<ColorGeometry4f, float, color_to_float>(conversions);
add_implicit_conversion<ColorGeometry4f, int32_t, color_to_int>(conversions);
add_implicit_conversion<ColorGeometry4f, int2, color_to_int2>(conversions);
add_implicit_conversion<ColorGeometry4f, float2, color_to_float2>(conversions);
add_implicit_conversion<ColorGeometry4f, float3, color_to_float3>(conversions);
add_implicit_conversion<ColorGeometry4f, ColorGeometry4b, color_to_byte_color>(conversions);
@ -337,6 +418,7 @@ static DataTypeConversions create_implicit_conversions()
add_implicit_conversion<ColorGeometry4b, int8_t, byte_color_to_int8>(conversions);
add_implicit_conversion<ColorGeometry4b, float, byte_color_to_float>(conversions);
add_implicit_conversion<ColorGeometry4b, int32_t, byte_color_to_int>(conversions);
add_implicit_conversion<ColorGeometry4b, int2, byte_color_to_int2>(conversions);
add_implicit_conversion<ColorGeometry4b, float2, byte_color_to_float2>(conversions);
add_implicit_conversion<ColorGeometry4b, float3, byte_color_to_float3>(conversions);
add_implicit_conversion<ColorGeometry4b, ColorGeometry4f, byte_color_to_color>(conversions);

View File

@ -73,7 +73,7 @@ inline void gather(const VArray<T> &src,
{
BLI_assert(indices.size() == dst.size());
threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) {
src.materialize_compressed_to_uninitialized(indices.slice(range), dst.slice(range).data());
src.materialize_compressed_to_uninitialized(indices.slice(range), dst.slice(range));
});
}

View File

@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup bli
*
* This file only exists to forward declare `blender::ImplicitSharingInfo` in C code.
*/
#ifdef __cplusplus
namespace blender {
class ImplicitSharingInfo;
}
using ImplicitSharingInfoHandle = blender::ImplicitSharingInfo;
#else
typedef struct ImplicitSharingInfoHandle ImplicitSharingInfoHandle;
#endif

View File

@ -194,11 +194,22 @@ inline T interpolate(const T &a, const T &b, const FactorT &t)
template<typename T> inline T midpoint(const T &a, const T &b)
{
auto result = (a + b) * T(0.5);
if constexpr (std::is_integral_v<T>) {
result = std::round(result);
/** See std::midpoint from C++20. */
using Unsigned = std::make_unsigned_t<T>;
int sign = 1;
Unsigned smaller = a;
Unsigned larger = b;
if (a > b) {
sign = -1;
smaller = b;
larger = a;
}
return a + sign * T(Unsigned(larger - smaller) / 2);
}
else {
return (a + b) * T(0.5);
}
return result;
}
} // namespace blender::math

View File

@ -243,6 +243,7 @@ set(SRC
BLI_hash_tables.hh
BLI_heap.h
BLI_heap_simple.h
BLI_implicit_sharing.h
BLI_implicit_sharing.hh
BLI_implicit_sharing_ptr.hh
BLI_index_mask.hh

View File

@ -104,6 +104,8 @@
} \
(void)0
#define TIMEIT_BLOCK_VALUE(id) (float)(_timeit_var_##id)
#define TIMEIT_BLOCK_STATS(id) \
{ \
printf("%s time (in seconds): %f\n", #id, _timeit_var_##id); \

View File

@ -52,6 +52,7 @@ BLI_CPP_TYPE_MAKE(blender::float4x4, CPPTypeFlags::BasicType)
BLI_CPP_TYPE_MAKE(int8_t, CPPTypeFlags::BasicType)
BLI_CPP_TYPE_MAKE(int16_t, CPPTypeFlags::BasicType)
BLI_CPP_TYPE_MAKE(int32_t, CPPTypeFlags::BasicType)
BLI_CPP_TYPE_MAKE(blender::int2, CPPTypeFlags::BasicType)
BLI_CPP_TYPE_MAKE(int64_t, CPPTypeFlags::BasicType)
BLI_CPP_TYPE_MAKE(uint8_t, CPPTypeFlags::BasicType)
@ -80,6 +81,7 @@ void register_cpp_types()
BLI_CPP_TYPE_REGISTER(int8_t);
BLI_CPP_TYPE_REGISTER(int16_t);
BLI_CPP_TYPE_REGISTER(int32_t);
BLI_CPP_TYPE_REGISTER(blender::int2);
BLI_CPP_TYPE_REGISTER(int64_t);
BLI_CPP_TYPE_REGISTER(uint8_t);

View File

@ -2241,7 +2241,7 @@ static int lib_link_main_data_restore_cb(LibraryIDLinkCallbackData *cb_data)
{
const int cb_flag = cb_data->cb_flag;
ID **id_pointer = cb_data->id_pointer;
if (cb_flag & IDWALK_CB_EMBEDDED || *id_pointer == nullptr) {
if (cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_EMBEDDED_NOT_OWNING) || *id_pointer == nullptr) {
return IDWALK_RET_NOP;
}

View File

@ -273,19 +273,19 @@ static void customdata_version_242(Mesh *me)
int a, mtfacen, mcoln;
if (!me->vdata.totlayer) {
CustomData_add_layer_with_data(&me->vdata, CD_MVERT, me->mvert, me->totvert);
CustomData_add_layer_with_data(&me->vdata, CD_MVERT, me->mvert, me->totvert, NULL);
if (me->dvert) {
CustomData_add_layer_with_data(&me->vdata, CD_MDEFORMVERT, me->dvert, me->totvert);
CustomData_add_layer_with_data(&me->vdata, CD_MDEFORMVERT, me->dvert, me->totvert, NULL);
}
}
if (!me->edata.totlayer) {
CustomData_add_layer_with_data(&me->edata, CD_MEDGE, me->medge, me->totedge);
CustomData_add_layer_with_data(&me->edata, CD_MEDGE, me->medge, me->totedge, NULL);
}
if (!me->fdata.totlayer) {
CustomData_add_layer_with_data(&me->fdata, CD_MFACE, me->mface, me->totface);
CustomData_add_layer_with_data(&me->fdata, CD_MFACE, me->mface, me->totface, NULL);
if (me->tface) {
if (me->mcol) {
@ -308,7 +308,7 @@ static void customdata_version_242(Mesh *me)
me->tface = NULL;
}
else if (me->mcol) {
CustomData_add_layer_with_data(&me->fdata, CD_MCOL, me->mcol, me->totface);
CustomData_add_layer_with_data(&me->fdata, CD_MCOL, me->mcol, me->totface, NULL);
}
}

View File

@ -517,16 +517,16 @@ void BM_mesh_copy_init_customdata_from_mesh_array(BMesh *bm_dst,
&me_src->ldata, CD_MASK_BMESH.pmask);
if (i == 0) {
CustomData_copy(&mesh_vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0);
CustomData_copy(&mesh_edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0);
CustomData_copy(&mesh_pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0);
CustomData_copy(&mesh_ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0);
CustomData_copy_layout(&mesh_vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0);
CustomData_copy_layout(&mesh_edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0);
CustomData_copy_layout(&mesh_pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0);
CustomData_copy_layout(&mesh_ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0);
}
else {
CustomData_merge(&mesh_vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0);
CustomData_merge(&mesh_edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0);
CustomData_merge(&mesh_pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0);
CustomData_merge(&mesh_ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0);
CustomData_merge_layout(&mesh_vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0);
CustomData_merge_layout(&mesh_edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0);
CustomData_merge_layout(&mesh_pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0);
CustomData_merge_layout(&mesh_ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0);
}
MEM_SAFE_FREE(mesh_vdata.layers);
@ -554,10 +554,10 @@ void BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const BMAllocTem
allocsize = &bm_mesh_allocsize_default;
}
CustomData_copy(&bm_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0);
CustomData_copy(&bm_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0);
CustomData_copy(&bm_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0);
CustomData_copy(&bm_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0);
CustomData_copy_layout(&bm_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_SET_DEFAULT, 0);
CustomData_copy_layout(&bm_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_SET_DEFAULT, 0);
CustomData_copy_layout(&bm_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_SET_DEFAULT, 0);
CustomData_copy_layout(&bm_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_SET_DEFAULT, 0);
CustomData_bmesh_init_pool(&bm_dst->vdata, allocsize->totvert, BM_VERT);
CustomData_bmesh_init_pool(&bm_dst->edata, allocsize->totedge, BM_EDGE);

View File

@ -268,10 +268,10 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
if (me->totvert == 0) {
if (is_new) {
/* No verts? still copy custom-data layout. */
CustomData_copy(&mesh_vdata, &bm->vdata, mask.vmask, CD_CONSTRUCT, 0);
CustomData_copy(&mesh_edata, &bm->edata, mask.emask, CD_CONSTRUCT, 0);
CustomData_copy(&mesh_pdata, &bm->pdata, mask.pmask, CD_CONSTRUCT, 0);
CustomData_copy(&mesh_ldata, &bm->ldata, mask.lmask, CD_CONSTRUCT, 0);
CustomData_copy_layout(&mesh_vdata, &bm->vdata, mask.vmask, CD_CONSTRUCT, 0);
CustomData_copy_layout(&mesh_edata, &bm->edata, mask.emask, CD_CONSTRUCT, 0);
CustomData_copy_layout(&mesh_pdata, &bm->pdata, mask.pmask, CD_CONSTRUCT, 0);
CustomData_copy_layout(&mesh_ldata, &bm->ldata, mask.lmask, CD_CONSTRUCT, 0);
CustomData_bmesh_init_pool(&bm->vdata, me->totvert, BM_VERT);
CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE);
@ -287,16 +287,20 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
}
if (is_new) {
CustomData_copy(&mesh_vdata, &bm->vdata, mask.vmask, CD_SET_DEFAULT, 0);
CustomData_copy(&mesh_edata, &bm->edata, mask.emask, CD_SET_DEFAULT, 0);
CustomData_copy(&mesh_pdata, &bm->pdata, mask.pmask, CD_SET_DEFAULT, 0);
CustomData_copy(&mesh_ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, 0);
CustomData_copy_layout(&mesh_vdata, &bm->vdata, mask.vmask, CD_SET_DEFAULT, 0);
CustomData_copy_layout(&mesh_edata, &bm->edata, mask.emask, CD_SET_DEFAULT, 0);
CustomData_copy_layout(&mesh_pdata, &bm->pdata, mask.pmask, CD_SET_DEFAULT, 0);
CustomData_copy_layout(&mesh_ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, 0);
}
else {
CustomData_bmesh_merge(&mesh_vdata, &bm->vdata, mask.vmask, CD_SET_DEFAULT, bm, BM_VERT);
CustomData_bmesh_merge(&mesh_edata, &bm->edata, mask.emask, CD_SET_DEFAULT, bm, BM_EDGE);
CustomData_bmesh_merge(&mesh_pdata, &bm->pdata, mask.pmask, CD_SET_DEFAULT, bm, BM_FACE);
CustomData_bmesh_merge(&mesh_ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, bm, BM_LOOP);
CustomData_bmesh_merge_layout(
&mesh_vdata, &bm->vdata, mask.vmask, CD_SET_DEFAULT, bm, BM_VERT);
CustomData_bmesh_merge_layout(
&mesh_edata, &bm->edata, mask.emask, CD_SET_DEFAULT, bm, BM_EDGE);
CustomData_bmesh_merge_layout(
&mesh_pdata, &bm->pdata, mask.pmask, CD_SET_DEFAULT, bm, BM_FACE);
CustomData_bmesh_merge_layout(
&mesh_ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, bm, BM_LOOP);
}
/* -------------------------------------------------------------------- */
@ -1394,10 +1398,10 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
{
CustomData_MeshMasks mask = CD_MASK_MESH;
CustomData_MeshMasks_update(&mask, &params->cd_mask_extra);
CustomData_copy(&bm->vdata, &me->vdata, mask.vmask, CD_SET_DEFAULT, me->totvert);
CustomData_copy(&bm->edata, &me->edata, mask.emask, CD_SET_DEFAULT, me->totedge);
CustomData_copy(&bm->ldata, &me->ldata, mask.lmask, CD_SET_DEFAULT, me->totloop);
CustomData_copy(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly);
CustomData_copy_layout(&bm->vdata, &me->vdata, mask.vmask, CD_SET_DEFAULT, me->totvert);
CustomData_copy_layout(&bm->edata, &me->edata, mask.emask, CD_SET_DEFAULT, me->totedge);
CustomData_copy_layout(&bm->ldata, &me->ldata, mask.lmask, CD_SET_DEFAULT, me->totloop);
CustomData_copy_layout(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly);
}
bool need_select_vert = false;
@ -1609,10 +1613,10 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
CustomData_MeshMasks_update(&mask, cd_mask_extra);
}
mask.vmask &= ~CD_MASK_SHAPEKEY;
CustomData_merge(&bm->vdata, &me->vdata, mask.vmask, CD_CONSTRUCT, me->totvert);
CustomData_merge(&bm->edata, &me->edata, mask.emask, CD_CONSTRUCT, me->totedge);
CustomData_merge(&bm->ldata, &me->ldata, mask.lmask, CD_CONSTRUCT, me->totloop);
CustomData_merge(&bm->pdata, &me->pdata, mask.pmask, CD_CONSTRUCT, me->totpoly);
CustomData_merge_layout(&bm->vdata, &me->vdata, mask.vmask, CD_CONSTRUCT, me->totvert);
CustomData_merge_layout(&bm->edata, &me->edata, mask.emask, CD_CONSTRUCT, me->totedge);
CustomData_merge_layout(&bm->ldata, &me->ldata, mask.lmask, CD_CONSTRUCT, me->totloop);
CustomData_merge_layout(&bm->pdata, &me->pdata, mask.pmask, CD_CONSTRUCT, me->totpoly);
me->runtime->deformed_only = true;

View File

@ -20,7 +20,7 @@
#include "bmesh.h"
#include "intern/bmesh_private.h"
BMUVOffsets BM_uv_map_get_offsets_n(const BMesh *bm, const int layer)
BMUVOffsets BM_uv_map_get_offsets_from_layer(const BMesh *bm, const int layer)
{
using namespace blender;
using namespace blender::bke;
@ -46,7 +46,8 @@ BMUVOffsets BM_uv_map_get_offsets_n(const BMesh *bm, const int layer)
BMUVOffsets BM_uv_map_get_offsets(const BMesh *bm)
{
return BM_uv_map_get_offsets_n(bm, CustomData_get_active_layer(&bm->ldata, CD_PROP_FLOAT2));
const int layer = CustomData_get_active_layer(&bm->ldata, CD_PROP_FLOAT2);
return BM_uv_map_get_offsets_from_layer(bm, layer);
}
static void uv_aspect(const BMLoop *l,

View File

@ -11,11 +11,17 @@ extern "C" {
#endif
/**
* Retrieve the custom data offsets for layers used for user interaction with a UV map, returns the
* active uv map if layer is -1.
* Retrieve the custom data offsets for the UV map.
* \param layer: The layer index (where 0 is the first UV map).
* \return The layer offsets or -1 when not found.
*/
BMUVOffsets BM_uv_map_get_offsets_from_layer(const BMesh *bm, int layer);
/**
* Retrieve the custom data offsets for layers used for user interaction with the active UV map.
* \return The layer offsets or -1 when not found.
*/
BMUVOffsets BM_uv_map_get_offsets(const BMesh *bm);
BMUVOffsets BM_uv_map_get_offsets_n(const BMesh *bm, int layer);
float BM_loop_uv_calc_edge_length_squared(const BMLoop *l,
int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT

View File

@ -8,7 +8,7 @@
#include "DRW_engine.h"
#include "DRW_render.h"
#include "ED_gpencil.h"
#include "ED_gpencil_legacy.h"
#include "ED_view3d.h"
#include "DNA_gpencil_legacy_types.h"

View File

@ -77,8 +77,8 @@ GPU_SHADER_CREATE_INFO(workbench_next_resolve_curvature)
GPU_SHADER_CREATE_INFO(workbench_next_resolve_cavity)
.define("WORKBENCH_CAVITY")
/* TODO(@pragma37): GPU_SAMPLER_EXTEND_MODE_REPEAT is set in CavityEffect, it doesn't work
here? */
/* TODO(@pragma37): GPU_SAMPLER_EXTEND_MODE_REPEAT is set in CavityEffect,
* it doesn't work here? */
.sampler(8, ImageType::FLOAT_2D, "jitter_tx")
.uniform_buf(5, "vec4", "cavity_samples[512]");

View File

@ -766,12 +766,17 @@ class Texture : NonCopyable {
return GPU_texture_height(tx_);
}
int depth() const
{
return GPU_texture_depth(tx_);
}
int pixel_count() const
{
return GPU_texture_width(tx_) * GPU_texture_height(tx_);
}
bool depth() const
bool is_depth() const
{
return GPU_texture_has_depth_format(tx_);
}

View File

@ -80,9 +80,10 @@ bool drw_custom_data_match_attribute(const CustomData *custom_data,
int *r_layer_index,
eCustomDataType *r_type)
{
const eCustomDataType possible_attribute_types[8] = {
const eCustomDataType possible_attribute_types[9] = {
CD_PROP_BOOL,
CD_PROP_INT8,
CD_PROP_INT32_2D,
CD_PROP_INT32,
CD_PROP_FLOAT,
CD_PROP_FLOAT2,

View File

@ -17,7 +17,7 @@
#include "DRW_engine.h"
#include "DRW_render.h"
#include "ED_gpencil.h"
#include "ED_gpencil_legacy.h"
#include "GPU_batch.h"
#include "DEG_depsgraph_query.h"

View File

@ -395,6 +395,7 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object,
case CD_PROP_BOOL:
case CD_PROP_INT8:
case CD_PROP_INT32:
case CD_PROP_INT32_2D:
case CD_PROP_FLOAT:
case CD_PROP_FLOAT2: {
if (layer != -1 && domain.has_value()) {

View File

@ -250,7 +250,7 @@ static void pointcloud_extract_position_and_radius(const PointCloud &pointcloud,
using namespace blender;
const bke::AttributeAccessor attributes = pointcloud.attributes();
const VArraySpan<float3> positions = attributes.lookup<float3>("position", ATTR_DOMAIN_POINT);
const Span<float3> positions = pointcloud.positions();
const VArray<float> radii = attributes.lookup<float>("radius", ATTR_DOMAIN_POINT);
static GPUVertFormat format = {0};
if (format.attr_len == 0) {

View File

@ -48,7 +48,7 @@
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
#include "ED_gpencil.h"
#include "ED_gpencil_legacy.h"
#include "ED_screen.h"
#include "ED_space_api.h"
#include "ED_view3d.h"

View File

@ -100,6 +100,7 @@ static uint gpu_component_size_for_attribute_type(eCustomDataType type)
* comment #extract_attr_init. */
return 3;
case CD_PROP_FLOAT2:
case CD_PROP_INT32_2D:
return 2;
case CD_PROP_FLOAT3:
return 3;
@ -116,6 +117,7 @@ static GPUVertFetchMode get_fetch_mode_for_type(eCustomDataType type)
switch (type) {
case CD_PROP_INT8:
case CD_PROP_INT32:
case CD_PROP_INT32_2D:
return GPU_FETCH_INT_TO_FLOAT;
case CD_PROP_BYTE_COLOR:
return GPU_FETCH_INT_TO_FLOAT_UNIT;
@ -128,6 +130,7 @@ static GPUVertCompType get_comp_type_for_type(eCustomDataType type)
{
switch (type) {
case CD_PROP_INT8:
case CD_PROP_INT32_2D:
case CD_PROP_INT32:
return GPU_COMP_I32;
case CD_PROP_BYTE_COLOR:
@ -299,6 +302,9 @@ static void extract_attr(const MeshRenderData *mr,
case CD_PROP_INT32:
extract_attr_generic<int32_t, int3>(mr, vbo, request);
break;
case CD_PROP_INT32_2D:
extract_attr_generic<int2>(mr, vbo, request);
break;
case CD_PROP_FLOAT:
extract_attr_generic<float, float3>(mr, vbo, request);
break;

View File

@ -12,7 +12,7 @@ if(WITH_BLENDER)
add_subdirectory(curves)
add_subdirectory(geometry)
add_subdirectory(gizmo_library)
add_subdirectory(gpencil)
add_subdirectory(gpencil_legacy)
add_subdirectory(interface)
add_subdirectory(io)
add_subdirectory(lattice)

View File

@ -746,7 +746,11 @@ void ANIM_frame_channel_y_extents(bContext *C, bAnimContext *ac)
rctf bounds = {.xmin = FLT_MAX, .xmax = -FLT_MAX, .ymin = FLT_MAX, .ymax = -FLT_MAX};
const bool include_handles = false;
const float frame_range[2] = {window_region->v2d.cur.xmin, window_region->v2d.cur.xmax};
float frame_range[2] = {window_region->v2d.cur.xmin, window_region->v2d.cur.xmax};
if (ac->scene->r.flag & SCER_PRV_RANGE) {
frame_range[0] = ac->scene->r.psfra;
frame_range[1] = ac->scene->r.pefra;
}
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
rctf channel_bounds;

View File

@ -741,7 +741,7 @@ bool ANIM_driver_vars_paste(ReportList *reports, FCurve *fcu, bool replace)
/* sanity checks */
if (BLI_listbase_is_empty(&driver_vars_copybuf)) {
BKE_report(reports, RPT_ERROR, "No driver variables in clipboard to paste");
BKE_report(reports, RPT_ERROR, "No driver variables in the internal clipboard to paste");
return false;
}
@ -1257,7 +1257,7 @@ void ANIM_OT_paste_driver_button(wmOperatorType *ot)
/* identifiers */
ot->name = "Paste Driver";
ot->idname = "ANIM_OT_paste_driver_button";
ot->description = "Paste the driver in the clipboard to the highlighted button";
ot->description = "Paste the driver in the internal clipboard to the highlighted button";
/* callbacks */
ot->exec = paste_driver_button_exec;

View File

@ -123,7 +123,7 @@ static void poselib_keytag_pose(bContext *C, Scene *scene, PoseBlendData *pbd)
}
bPose *pose = pbd->ob->pose;
bAction *act = pbd->act;
bAction *act = poselib_action_to_blend(pbd);
KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID);
ListBase dsources = {NULL, NULL};

View File

@ -798,7 +798,7 @@ static int pose_copy_exec(bContext *C, wmOperator *op)
BLI_listbase_clear(&temp_bmain->armatures);
BKE_main_free(temp_bmain);
/* We are all done! */
BKE_report(op->reports, RPT_INFO, "Copied pose to buffer");
BKE_report(op->reports, RPT_INFO, "Copied pose to internal clipboard");
return OPERATOR_FINISHED;
}
@ -807,7 +807,7 @@ void POSE_OT_copy(wmOperatorType *ot)
/* identifiers */
ot->name = "Copy Pose";
ot->idname = "POSE_OT_copy";
ot->description = "Copies the current pose of the selected bones to copy/paste buffer";
ot->description = "Copy the current pose of the selected bones to the internal clipboard";
/* api callbacks */
ot->exec = pose_copy_exec;
@ -846,13 +846,13 @@ static int pose_paste_exec(bContext *C, wmOperator *op)
BLI_path_join(str, sizeof(str), BKE_tempdir_base(), "copybuffer_pose.blend");
if (!BKE_copybuffer_read(tmp_bmain, str, op->reports, FILTER_ID_OB)) {
BKE_report(op->reports, RPT_ERROR, "Copy buffer is empty");
BKE_report(op->reports, RPT_ERROR, "Internal clipboard is empty");
BKE_main_free(tmp_bmain);
return OPERATOR_CANCELLED;
}
/* Make sure data from this file is usable for pose paste. */
if (BLI_listbase_count_at_most(&tmp_bmain->objects, 2) != 1) {
BKE_report(op->reports, RPT_ERROR, "Copy buffer is not from pose mode");
BKE_report(op->reports, RPT_ERROR, "Internal clipboard is not from pose mode");
BKE_main_free(tmp_bmain);
return OPERATOR_CANCELLED;
}
@ -860,7 +860,7 @@ static int pose_paste_exec(bContext *C, wmOperator *op)
Object *object_from = tmp_bmain->objects.first;
bPose *pose_from = object_from->pose;
if (pose_from == NULL) {
BKE_report(op->reports, RPT_ERROR, "Copy buffer has no pose");
BKE_report(op->reports, RPT_ERROR, "Internal clipboard has no pose");
BKE_main_free(tmp_bmain);
return OPERATOR_CANCELLED;
}

View File

@ -7,6 +7,8 @@
#pragma once
#define DIAL_RESOLUTION 48
/**
* Data for common interactions. Used in gizmo_library_utils.c functions.
*/
@ -73,6 +75,13 @@ bool gizmo_window_project_2d(bContext *C,
bool gizmo_window_project_3d(
bContext *C, const struct wmGizmo *gz, const float mval[2], bool use_offset, float r_co[3]);
/* -------------------------------------------------------------------- */
/* Gizmo RNA Utils. */
struct wmGizmo *gizmo_find_from_properties(const struct IDProperty *properties,
const int spacetype,
const int regionid);
/* -------------------------------------------------------------------- */
/* Gizmo drawing */

View File

@ -15,12 +15,15 @@
#include "DNA_view3d_types.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "RNA_access.h"
#include "WM_api.h"
#include "WM_types.h"
#include "ED_screen.h"
#include "ED_view3d.h"
#include "CLG_log.h"
@ -245,3 +248,38 @@ bool gizmo_window_project_3d(
copy_v2_v2(r_co, co);
return true;
}
/* -------------------------------------------------------------------- */
/** \name RNA Utils
* \{ */
/* Based on 'rna_GizmoProperties_find_operator'. */
wmGizmo *gizmo_find_from_properties(const struct IDProperty *properties,
const int spacetype,
const int regionid)
{
for (bScreen *screen = G_MAIN->screens.first; screen; screen = screen->id.next) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (!ELEM(spacetype, SPACE_TYPE_ANY, area->spacetype)) {
continue;
}
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->gizmo_map == NULL) {
continue;
}
if (!ELEM(regionid, RGN_TYPE_ANY, region->regiontype)) {
continue;
}
LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, WM_gizmomap_group_list(region->gizmo_map)) {
LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
if (gz->properties == properties) {
return gz;
}
}
}
}
}
}
return NULL;
}

View File

@ -48,7 +48,7 @@
#include "../gizmo_library_intern.h"
/* to use custom arrows exported to geom_arrow_gizmo.c */
//#define USE_GIZMO_CUSTOM_ARROWS
// #define USE_GIZMO_CUSTOM_ARROWS
/* Margin to add when selecting the arrow. */
#define ARROW_SELECT_THRESHOLD_PX (5)
@ -115,6 +115,29 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow,
immUniform1f("lineWidth", arrow->gizmo.line_width * U.pixelsize);
wm_gizmo_vec_draw(color, vec, ARRAY_SIZE(vec), pos, GPU_PRIM_LINE_LOOP);
}
else if (draw_style == ED_GIZMO_ARROW_STYLE_PLANE) {
const float scale = 0.1f;
const float verts[4][3] = {
{0, 0, 0},
{scale, 0, scale},
{0, 0, 2 * scale},
{-scale, 0, scale},
};
const float color_inner[4] = {UNPACK3(color), color[3] * 0.5f};
/* Translate to line end. */
GPU_matrix_push();
GPU_matrix_translate_3f(0.0f, 0.0f, arrow_length);
immUniform1f("lineWidth", arrow->gizmo.line_width * U.pixelsize);
wm_gizmo_vec_draw(color, verts, ARRAY_SIZE(verts), pos, GPU_PRIM_LINE_LOOP);
immUnbindProgram();
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
wm_gizmo_vec_draw(color_inner, verts, ARRAY_SIZE(verts), pos, GPU_PRIM_TRI_FAN);
GPU_matrix_pop();
}
else {
#ifdef USE_GIZMO_CUSTOM_ARROWS
wm_gizmo_geometryinfo_draw(&wm_gizmo_geom_data_arrow, select, color);
@ -177,6 +200,19 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow,
if (unbind_shader) {
immUnbindProgram();
}
if (draw_options & ED_GIZMO_ARROW_DRAW_FLAG_ORIGIN) {
const float point_size = 10 * U.pixelsize;
GPU_program_point_size(true);
immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
immUniform1f("size", point_size);
immUniformColor4fv(color);
immBegin(GPU_PRIM_POINTS, 1);
immVertex3f(pos, 0.0f, 0.0f, 0.0f);
immEnd();
immUnbindProgram();
GPU_program_point_size(false);
}
}
static void arrow_draw_intern(ArrowGizmo3D *arrow, const bool select, const bool highlight)
@ -504,10 +540,12 @@ static void GIZMO_GT_arrow_3d(wmGizmoType *gzt)
{ED_GIZMO_ARROW_STYLE_CROSS, "CROSS", 0, "Cross", ""},
{ED_GIZMO_ARROW_STYLE_BOX, "BOX", 0, "Box", ""},
{ED_GIZMO_ARROW_STYLE_CONE, "CONE", 0, "Cone", ""},
{ED_GIZMO_ARROW_STYLE_PLANE, "PLANE", 0, "Plane", ""},
{0, NULL, 0, NULL, NULL},
};
static EnumPropertyItem rna_enum_draw_options_items[] = {
{ED_GIZMO_ARROW_DRAW_FLAG_STEM, "STEM", 0, "Stem", ""},
{ED_GIZMO_ARROW_DRAW_FLAG_ORIGIN, "ORIGIN", 0, "Origin", ""},
{0, NULL, 0, NULL, NULL},
};
static EnumPropertyItem rna_enum_transform_items[] = {

View File

@ -71,7 +71,6 @@ typedef struct DialInteraction {
} DialInteraction;
#define DIAL_WIDTH 1.0f
#define DIAL_RESOLUTION 48
/* Could make option, negative to clip more (don't show when view aligned). */
#define DIAL_CLIP_BIAS 0.02

View File

@ -42,6 +42,7 @@
#include "../gizmo_library_intern.h"
#define MVAL_MAX_PX_DIST 12.0f
#define RING_2D_RESOLUTION 32
typedef struct MoveGizmo3D {
wmGizmo gizmo;
@ -78,8 +79,6 @@ typedef struct MoveInteraction {
} MoveInteraction;
#define DIAL_RESOLUTION 32
/* -------------------------------------------------------------------- */
static void move_geom_draw(const wmGizmo *gz,
@ -116,10 +115,10 @@ static void move_geom_draw(const wmGizmo *gz,
if (draw_style == ED_GIZMO_MOVE_STYLE_RING_2D) {
if (filled) {
imm_draw_circle_fill_3d(pos, 0.0f, 0.0f, radius, DIAL_RESOLUTION);
imm_draw_circle_fill_3d(pos, 0.0f, 0.0f, radius, RING_2D_RESOLUTION);
}
else {
imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, radius, DIAL_RESOLUTION);
imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, radius, RING_2D_RESOLUTION);
}
}
else if (draw_style == ED_GIZMO_MOVE_STYLE_CROSS_2D) {

View File

@ -15,6 +15,8 @@
#include "BLI_math.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
#include "BKE_context.h"
@ -42,36 +44,135 @@ static float verts_plane[4][3] = {
{-1, 1, 0},
};
typedef struct PrimitiveGizmo3D {
wmGizmo gizmo;
int draw_style;
float arc_inner_factor;
bool draw_inner;
} PrimitiveGizmo3D;
/* -------------------------------------------------------------------- */
/** \name RNA callbacks */
static void gizmo_primitive_draw_geom(const float col_inner[4],
const float col_outer[4],
const int draw_style)
static PrimitiveGizmo3D *gizmo_primitive_rna_find_operator(PointerRNA *ptr)
{
float(*verts)[3];
uint vert_count = 0;
if (draw_style == ED_GIZMO_PRIMITIVE_STYLE_PLANE) {
verts = verts_plane;
vert_count = ARRAY_SIZE(verts_plane);
}
if (vert_count > 0) {
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
wm_gizmo_vec_draw(col_inner, verts, vert_count, pos, GPU_PRIM_TRI_FAN);
wm_gizmo_vec_draw(col_outer, verts, vert_count, pos, GPU_PRIM_LINE_LOOP);
immUnbindProgram();
}
return (PrimitiveGizmo3D *)gizmo_find_from_properties(ptr->data, SPACE_TYPE_ANY, RGN_TYPE_ANY);
}
static void gizmo_primitive_draw_intern(wmGizmo *gz,
const bool UNUSED(select),
const bool highlight)
static int gizmo_primitive_rna__draw_style_get_fn(struct PointerRNA *ptr,
struct PropertyRNA *UNUSED(prop))
{
PrimitiveGizmo3D *gz_prim = gizmo_primitive_rna_find_operator(ptr);
return gz_prim->draw_style;
}
static void gizmo_primitive_rna__draw_style_set_fn(struct PointerRNA *ptr,
struct PropertyRNA *UNUSED(prop),
int value)
{
PrimitiveGizmo3D *gz_prim = gizmo_primitive_rna_find_operator(ptr);
gz_prim->draw_style = value;
}
static float gizmo_primitive_rna__arc_inner_factor_get_fn(struct PointerRNA *ptr,
struct PropertyRNA *UNUSED(prop))
{
PrimitiveGizmo3D *gz_prim = gizmo_primitive_rna_find_operator(ptr);
return gz_prim->arc_inner_factor;
}
static void gizmo_primitive_rna__arc_inner_factor_set_fn(struct PointerRNA *ptr,
struct PropertyRNA *UNUSED(prop),
float value)
{
PrimitiveGizmo3D *gz_prim = gizmo_primitive_rna_find_operator(ptr);
gz_prim->arc_inner_factor = value;
}
static bool gizmo_primitive_rna__draw_inner_get_fn(struct PointerRNA *ptr,
struct PropertyRNA *UNUSED(prop))
{
PrimitiveGizmo3D *gz_prim = gizmo_primitive_rna_find_operator(ptr);
return gz_prim->draw_inner;
}
static void gizmo_primitive_rna__draw_inner_set_fn(struct PointerRNA *ptr,
struct PropertyRNA *UNUSED(prop),
bool value)
{
PrimitiveGizmo3D *gz_prim = gizmo_primitive_rna_find_operator(ptr);
gz_prim->draw_inner = value;
}
/* -------------------------------------------------------------------- */
static void gizmo_primitive_draw_geom(PrimitiveGizmo3D *gz_prim,
const float col_inner[4],
const float col_outer[4],
const int nsegments,
const bool draw_inner)
{
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
const bool use_polyline_shader = gz_prim->gizmo.line_width > 1.0f;
if (draw_inner || !use_polyline_shader) {
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
}
if (draw_inner) {
if (gz_prim->draw_style == ED_GIZMO_PRIMITIVE_STYLE_PLANE) {
wm_gizmo_vec_draw(col_inner, verts_plane, ARRAY_SIZE(verts_plane), pos, GPU_PRIM_TRI_FAN);
}
else {
immUniformColor4fv(col_inner);
if (gz_prim->draw_style == ED_GIZMO_PRIMITIVE_STYLE_CIRCLE) {
imm_draw_circle_fill_3d(pos, 0.0f, 0.0f, 1.0f, nsegments);
}
else {
BLI_assert(gz_prim->draw_style == ED_GIZMO_PRIMITIVE_STYLE_ANNULUS);
imm_draw_disk_partial_fill_3d(
pos, 0.0f, 0.0f, 0.0f, gz_prim->arc_inner_factor, 1.0f, nsegments, 0.0f, 360.0f);
}
}
}
/* Draw outline. */
if (use_polyline_shader) {
if (draw_inner) {
immUnbindProgram();
}
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
float viewport[4];
GPU_viewport_size_get_f(viewport);
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", gz_prim->gizmo.line_width * U.pixelsize);
}
if (gz_prim->draw_style == ED_GIZMO_PRIMITIVE_STYLE_PLANE) {
wm_gizmo_vec_draw(col_outer, verts_plane, ARRAY_SIZE(verts_plane), pos, GPU_PRIM_LINE_LOOP);
}
else {
immUniformColor4fv(col_outer);
if (gz_prim->draw_style == ED_GIZMO_PRIMITIVE_STYLE_CIRCLE) {
imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, 1.0f, nsegments);
}
else {
imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, gz_prim->arc_inner_factor, nsegments);
imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, 1.0f, nsegments);
}
}
immUnbindProgram();
}
static void gizmo_primitive_draw_intern(wmGizmo *gz, const bool select, const bool highlight)
{
PrimitiveGizmo3D *gz_prim = (PrimitiveGizmo3D *)gz;
float color_inner[4], color_outer[4];
float matrix_final[4][4];
const int draw_style = RNA_enum_get(gz->ptr, "draw_style");
gizmo_color_get(gz, highlight, color_outer);
copy_v4_v4(color_inner, color_outer);
@ -79,12 +180,15 @@ static void gizmo_primitive_draw_intern(wmGizmo *gz,
WM_gizmo_calc_matrix_final(gz, matrix_final);
GPU_blend(GPU_BLEND_ALPHA);
GPU_matrix_push();
GPU_matrix_mul(matrix_final);
GPU_blend(GPU_BLEND_ALPHA);
gizmo_primitive_draw_geom(color_inner, color_outer, draw_style);
GPU_blend(GPU_BLEND_NONE);
gizmo_primitive_draw_geom(gz_prim,
color_inner,
color_outer,
select ? 24 : DIAL_RESOLUTION,
gz_prim->draw_inner || select);
GPU_matrix_pop();
@ -98,12 +202,12 @@ static void gizmo_primitive_draw_intern(wmGizmo *gz,
GPU_matrix_push();
GPU_matrix_mul(inter->init_matrix_final);
GPU_blend(GPU_BLEND_ALPHA);
gizmo_primitive_draw_geom(color_inner, color_outer, draw_style);
GPU_blend(GPU_BLEND_NONE);
gizmo_primitive_draw_geom(
gz_prim, color_inner, color_outer, DIAL_RESOLUTION, gz_prim->draw_inner);
GPU_matrix_pop();
}
GPU_blend(GPU_BLEND_NONE);
}
static void gizmo_primitive_draw_select(const bContext *UNUSED(C), wmGizmo *gz, int select_id)
@ -120,6 +224,12 @@ static void gizmo_primitive_draw(const bContext *UNUSED(C), wmGizmo *gz)
static void gizmo_primitive_setup(wmGizmo *gz)
{
gz->flag |= WM_GIZMO_DRAW_MODAL;
/* Default Values. */
PrimitiveGizmo3D *gz_prim = (PrimitiveGizmo3D *)gz;
gz_prim->draw_style = ED_GIZMO_PRIMITIVE_STYLE_PLANE;
gz_prim->arc_inner_factor = true;
gz_prim->draw_inner = true;
}
static int gizmo_primitive_invoke(bContext *UNUSED(C), wmGizmo *gz, const wmEvent *UNUSED(event))
@ -148,18 +258,35 @@ static void GIZMO_GT_primitive_3d(wmGizmoType *gzt)
gzt->setup = gizmo_primitive_setup;
gzt->invoke = gizmo_primitive_invoke;
gzt->struct_size = sizeof(wmGizmo);
gzt->struct_size = sizeof(PrimitiveGizmo3D);
static EnumPropertyItem rna_enum_draw_style[] = {
{ED_GIZMO_PRIMITIVE_STYLE_PLANE, "PLANE", 0, "Plane", ""},
{ED_GIZMO_PRIMITIVE_STYLE_CIRCLE, "CIRCLE", 0, "Circle", ""},
{ED_GIZMO_PRIMITIVE_STYLE_ANNULUS, "ANNULUS", 0, "Annulus", ""},
{0, NULL, 0, NULL, NULL},
};
RNA_def_enum(gzt->srna,
"draw_style",
rna_enum_draw_style,
ED_GIZMO_PRIMITIVE_STYLE_PLANE,
"Draw Style",
"");
PropertyRNA *prop;
prop = RNA_def_enum(gzt->srna,
"draw_style",
rna_enum_draw_style,
ED_GIZMO_PRIMITIVE_STYLE_PLANE,
"Draw Style",
"");
RNA_def_property_enum_funcs_runtime(
prop, gizmo_primitive_rna__draw_style_get_fn, gizmo_primitive_rna__draw_style_set_fn, NULL);
prop = RNA_def_float_factor(
gzt->srna, "arc_inner_factor", 0.0f, 0.0f, FLT_MAX, "Arc Inner Factor", "", 0.0f, 1.0f);
RNA_def_property_float_funcs_runtime(prop,
gizmo_primitive_rna__arc_inner_factor_get_fn,
gizmo_primitive_rna__arc_inner_factor_set_fn,
NULL);
prop = RNA_def_boolean(gzt->srna, "draw_inner", true, "Draw Inner", "");
RNA_def_property_boolean_funcs_runtime(
prop, gizmo_primitive_rna__draw_inner_get_fn, gizmo_primitive_rna__draw_inner_set_fn);
}
void ED_gizmotypes_primitive_3d(void)

View File

@ -123,30 +123,9 @@ void ED_gizmotypes_snap_3d_data_get(const struct bContext *C,
/** \name RNA callbacks
* \{ */
/* Based on 'rna_GizmoProperties_find_operator'. */
static SnapGizmo3D *gizmo_snap_rna_find_operator(PointerRNA *ptr)
{
IDProperty *properties = ptr->data;
for (bScreen *screen = G_MAIN->screens.first; screen; screen = screen->id.next) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (area->spacetype != SPACE_VIEW3D) {
continue;
}
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->regiontype == RGN_TYPE_WINDOW && region->gizmo_map) {
wmGizmoMap *gzmap = region->gizmo_map;
LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, WM_gizmomap_group_list(gzmap)) {
LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
if (gz->properties == properties) {
return (SnapGizmo3D *)gz;
}
}
}
}
}
}
}
return NULL;
return (SnapGizmo3D *)gizmo_find_from_properties(ptr->data, SPACE_VIEW3D, RGN_TYPE_WINDOW);
}
static V3DSnapCursorState *gizmo_snap_state_from_rna_get(struct PointerRNA *ptr)

View File

@ -77,7 +77,7 @@ if(WITH_POTRACE)
endif()
blender_add_lib(bf_editor_gpencil "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
blender_add_lib(bf_editor_gpencil_legacy "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
# RNA_prototypes.h
add_dependencies(bf_editor_gpencil bf_rna)
add_dependencies(bf_editor_gpencil_legacy bf_rna)

View File

@ -41,7 +41,7 @@
#include "GPU_matrix.h"
#include "GPU_state.h"
#include "ED_gpencil.h"
#include "ED_gpencil_legacy.h"
#include "ED_screen.h"
#include "ED_space_api.h"
#include "ED_view3d.h"

View File

@ -39,7 +39,7 @@
#include "UI_view2d.h"
#include "ED_clip.h"
#include "ED_gpencil.h"
#include "ED_gpencil_legacy.h"
#include "ED_screen.h"
#include "ED_view3d.h"

View File

@ -52,7 +52,7 @@
#include "GPU_state.h"
#include "GPU_uniform_buffer.h"
#include "ED_gpencil.h"
#include "ED_gpencil_legacy.h"
#include "ED_screen.h"
#include "ED_space_api.h"
#include "ED_view3d.h"

View File

@ -24,7 +24,7 @@
#include "BKE_report.h"
#include "ED_anim_api.h"
#include "ED_gpencil.h"
#include "ED_gpencil_legacy.h"
#include "ED_keyframes_edit.h"
#include "ED_markers.h"

View File

@ -23,7 +23,7 @@
#include "DEG_depsgraph.h"
#include "ED_gpencil.h"
#include "ED_gpencil_legacy.h"
/* Definition of the most important info from a color */
typedef struct ColorTemplate {

View File

@ -26,7 +26,7 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
#include "ED_gpencil.h"
#include "ED_gpencil_legacy.h"
/* Definition of the most important info from a color */
typedef struct ColorTemplate {

View File

@ -23,7 +23,7 @@
#include "DEG_depsgraph.h"
#include "ED_gpencil.h"
#include "ED_gpencil_legacy.h"
void ED_gpencil_stroke_init_data(bGPDstroke *gps,
const float *array,

View File

@ -23,7 +23,7 @@
#include "DEG_depsgraph.h"
#include "ED_gpencil.h"
#include "ED_gpencil_legacy.h"
/* Definition of the most important info from a color */
typedef struct ColorTemplate {

Some files were not shown because too many files have changed in this diff Show More